OSDN Git Service

PR c++/27819
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Jun 2006 02:46:38 +0000 (02:46 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Jun 2006 02:46:38 +0000 (02:46 +0000)
* decl.c (cp_finish_decl): Process initializers for static data
members with non-dependent initializers, even in templates.
PR c++/27722
* decl.c (maybe_deduce_size_from_array_init): If the declaration
is erroneous, give it an erroneous type.
(layout_var_decl): If the type is erroneous, give up.
(check_initializer): Likewise.
PR c++/27807
* cp-tree.h (TYPE_OBJ_P): New macro.
(TYPE_PTROB_P): Use it.
(TYPE_REF_OBJ_P): Likewise.
* semantics.c (finish_compound_literal): Do not permit compound
literals of non-object types.
PR c++/27806
* typeck.c (original_type): Robustify.
PR c++/27819
* g++.dg/template/static25.C: New test.
PR c++/27722
* g++.dg/init/array21.C: New test.
PR c++/27807
* g++.dg/ext/complit7.C: New test.

PR c++/27806
* g++.dg/parse/ptrmem5.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114382 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/complit7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/init/array21.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/ptrmem5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/static25.C [new file with mode: 0644]

index 7f118ab..3d0fe7f 100644 (file)
@@ -1,3 +1,25 @@
+2006-06-04  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/27819
+       * decl.c (cp_finish_decl): Process initializers for static data
+       members with non-dependent initializers, even in templates.
+
+       PR c++/27722
+       * decl.c (maybe_deduce_size_from_array_init): If the declaration
+       is erroneous, give it an erroneous type.
+       (layout_var_decl): If the type is erroneous, give up.
+       (check_initializer): Likewise.
+
+       PR c++/27807
+       * cp-tree.h (TYPE_OBJ_P): New macro.
+       (TYPE_PTROB_P): Use it.
+       (TYPE_REF_OBJ_P): Likewise.
+       * semantics.c (finish_compound_literal): Do not permit compound
+       literals of non-object types.
+
+       PR c++/27806
+       * typeck.c (original_type): Robustify.
+
 2006-06-05  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        PR c++/27804
index 486a90d..9253764 100644 (file)
@@ -2515,30 +2515,43 @@ extern void decl_shadowed_for_var_insert (tree, tree);
 /* Returns true if NODE is a pointer.  */
 #define TYPE_PTR_P(NODE)                       \
   (TREE_CODE (NODE) == POINTER_TYPE)
+
+/* Returns true if NODE is an object type:
+
+     [basic.types]
+
+     An object type is a (possibly cv-qualified) type that is not a
+     function type, not a reference type, and not a void type.  
+
+   Keep these checks in ascending order, for speed.  */
+#define TYPE_OBJ_P(NODE)                       \
+  (TREE_CODE (NODE) != REFERENCE_TYPE          \
+   && TREE_CODE (NODE) != VOID_TYPE            \
+   && TREE_CODE (NODE) != FUNCTION_TYPE                \
+   && TREE_CODE (NODE) != METHOD_TYPE)
+
 /* Returns true if NODE is a pointer to an object.  Keep these checks
    in ascending tree code order.  */
 #define TYPE_PTROB_P(NODE)                                     \
-  (TYPE_PTR_P (NODE)                                           \
-   && !(TREE_CODE (TREE_TYPE (NODE)) == VOID_TYPE              \
-       || TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE        \
-       || TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
+  (TYPE_PTR_P (NODE) && TYPE_OBJ_P (TREE_TYPE (NODE)))
+
 /* Returns true if NODE is a reference to an object.  Keep these checks
    in ascending tree code order.  */
 #define TYPE_REF_OBJ_P(NODE)                                   \
-  (TREE_CODE (NODE) == REFERENCE_TYPE                          \
-   && !(TREE_CODE (TREE_TYPE (NODE)) == VOID_TYPE              \
-       || TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE        \
-       || TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
+  (TREE_CODE (NODE) == REFERENCE_TYPE && TYPE_OBJ_P (TREE_TYPE (NODE)))
+
 /* Returns true if NODE is a pointer to an object, or a pointer to
    void.  Keep these checks in ascending tree code order.  */
 #define TYPE_PTROBV_P(NODE)                                    \
   (TYPE_PTR_P (NODE)                                           \
    && !(TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE          \
        || TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
+
 /* Returns true if NODE is a pointer to function.  */
 #define TYPE_PTRFN_P(NODE)                             \
   (TREE_CODE (NODE) == POINTER_TYPE                    \
    && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
+
 /* Returns true if NODE is a reference to function.  */
 #define TYPE_REFFN_P(NODE)                             \
   (TREE_CODE (NODE) == REFERENCE_TYPE                  \
index bccb438..e005d63 100644 (file)
@@ -4111,12 +4111,17 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
                                            do_default);
 
       if (failure == 1)
-       error ("initializer fails to determine size of %qD", decl);
-
-      if (failure == 2)
+       {
+         error ("initializer fails to determine size of %qD", decl);
+         TREE_TYPE (decl) = error_mark_node;
+       }
+      else if (failure == 2)
        {
          if (do_default)
-           error ("array size missing in %qD", decl);
+           {
+             error ("array size missing in %qD", decl);
+             TREE_TYPE (decl) = error_mark_node;
+           }
          /* If a `static' var's size isn't known, make it extern as
             well as static, so it does not get allocated.  If it's not
             `static', then don't mark it extern; finish_incomplete_decl
@@ -4124,9 +4129,11 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
          else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
            DECL_EXTERNAL (decl) = 1;
        }
-
-      if (failure == 3)
-       error ("zero-size array %qD", decl);
+      else if (failure == 3)
+       {
+         error ("zero-size array %qD", decl);
+         TREE_TYPE (decl) = error_mark_node;
+       }
 
       cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);
 
@@ -4140,7 +4147,17 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
 static void
 layout_var_decl (tree decl)
 {
-  tree type = TREE_TYPE (decl);
+  tree type;
+
+  if (TREE_STATIC (decl)
+      && !DECL_ARTIFICIAL (decl)
+      && current_function_decl
+      && DECL_CONTEXT (decl) == current_function_decl)
+    push_local_name (decl);
+
+  type = TREE_TYPE (decl);
+  if (type == error_mark_node)
+    return;
 
   /* If we haven't already layed out this declaration, do so now.
      Note that we must not call complete type for an external object
@@ -4186,12 +4203,6 @@ layout_var_decl (tree decl)
       else
        error ("storage size of %qD isn't constant", decl);
     }
-
-  if (TREE_STATIC (decl)
-      && !DECL_ARTIFICIAL (decl)
-      && current_function_decl
-      && DECL_CONTEXT (decl) == current_function_decl)
-    push_local_name (decl);
 }
 
 /* If a local static variable is declared in an inline function, or if
@@ -4714,6 +4725,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
         array size from the initializer.  */
       maybe_deduce_size_from_array_init (decl, init);
       type = TREE_TYPE (decl);
+      if (type == error_mark_node)
+       return NULL_TREE;
 
       if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
        {
@@ -4977,6 +4990,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   const char *asmspec = NULL;
   int was_readonly = 0;
   bool var_definition_p = false;
+  int saved_processing_template_decl;
 
   if (decl == error_mark_node)
     return;
@@ -4988,9 +5002,16 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
     }
 
   gcc_assert (TREE_CODE (decl) != RESULT_DECL);
+  /* Parameters are handled by store_parm_decls, not cp_finish_decl.  */
+  gcc_assert (TREE_CODE (decl) != PARM_DECL);
+
+  type = TREE_TYPE (decl);
+  if (type == error_mark_node)
+    return;
 
   /* Assume no cleanup is required.  */
   cleanup = NULL_TREE;
+  saved_processing_template_decl = processing_template_decl;
 
   /* If a name was specified, get the string.  */
   if (global_scope_p (current_binding_level))
@@ -4998,51 +5019,48 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   if (asmspec_tree)
     asmspec = TREE_STRING_POINTER (asmspec_tree);
 
-  if (init && TREE_CODE (init) == NAMESPACE_DECL)
-    {
-      error ("cannot initialize %qD to namespace %qD", decl, init);
-      init = NULL_TREE;
-    }
-
   if (current_class_type
       && CP_DECL_CONTEXT (decl) == current_class_type
       && TYPE_BEING_DEFINED (current_class_type)
       && (DECL_INITIAL (decl) || init))
     DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
 
-  type = TREE_TYPE (decl);
-
-  if (type == error_mark_node)
-    goto finish_end;
-
   if (processing_template_decl)
     {
+      bool type_dependent_p;
+
       /* Add this declaration to the statement-tree.  */
       if (at_function_scope_p ())
        add_decl_expr (decl);
 
-      if (init)
+      type_dependent_p = dependent_type_p (type);
+
+      if (init && init_const_expr_p)
        {
-         DECL_INITIAL (decl) = init;
-         if (init_const_expr_p)
-           {
-             DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
-             if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
-               TREE_CONSTANT (decl) = 1;
-           }
+         DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
+         if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
+           TREE_CONSTANT (decl) = 1;
        }
 
-      if (TREE_CODE (decl) == VAR_DECL
-         && !DECL_PRETTY_FUNCTION_P (decl)
-         && !dependent_type_p (TREE_TYPE (decl)))
-       maybe_deduce_size_from_array_init (decl, init);
+      if (!init
+         || !DECL_CLASS_SCOPE_P (decl)
+         || !DECL_INTEGRAL_CONSTANT_VAR_P (decl)
+         || type_dependent_p
+         || value_dependent_expression_p (init))
+       {
+         if (init)
+           DECL_INITIAL (decl) = init;
+         if (TREE_CODE (decl) == VAR_DECL
+             && !DECL_PRETTY_FUNCTION_P (decl)
+             && !type_dependent_p)
+           maybe_deduce_size_from_array_init (decl, init);
+         goto finish_end;
+       }
 
-      goto finish_end;
+      init = fold_non_dependent_expr (init);
+      processing_template_decl = 0;
     }
 
-  /* Parameters are handled by store_parm_decls, not cp_finish_decl.  */
-  gcc_assert (TREE_CODE (decl) != PARM_DECL);
-
   /* Take care of TYPE_DECLs up front.  */
   if (TREE_CODE (decl) == TYPE_DECL)
     {
@@ -5236,6 +5254,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
     push_cleanup (decl, cleanup, false);
 
  finish_end:
+  processing_template_decl = saved_processing_template_decl;
 
   if (was_readonly)
     TREE_READONLY (decl) = 1;
index 976005c..06ed52d 100644 (file)
@@ -2021,6 +2021,12 @@ finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list)
   tree var;
   tree compound_literal;
 
+  if (!TYPE_OBJ_P (type))
+    {
+      error ("compound literal of non-object type %qT", type);
+      return error_mark_node;
+    }
+
   /* Build a CONSTRUCTOR for the INITIALIZER_LIST.  */
   compound_literal = build_constructor (NULL_TREE, initializer_list);
   if (processing_template_decl)
index 5861f23..7ddbf23 100644 (file)
@@ -228,7 +228,8 @@ commonparms (tree p1, tree p2)
 static tree
 original_type (tree t)
 {
-  while (TYPE_NAME (t) != NULL_TREE)
+  while (t != error_mark_node
+        && TYPE_NAME (t) != NULL_TREE)
     {
       tree x = TYPE_NAME (t);
       if (TREE_CODE (x) != TYPE_DECL)
index b325d67..1396e30 100644 (file)
@@ -1,3 +1,17 @@
+2006-06-04  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/27819
+       * g++.dg/template/static25.C: New test.
+
+       PR c++/27722
+       * g++.dg/init/array21.C: New test.
+
+       PR c++/27807
+       * g++.dg/ext/complit7.C: New test.
+       
+       PR c++/27806
+       * g++.dg/parse/ptrmem5.C: New test.
+
 2006-06-04  Roger Sayle  <roger@eyesopen.com>
            Andrew Pinski  <pinskia@physics.uc.edu>
 
diff --git a/gcc/testsuite/g++.dg/ext/complit7.C b/gcc/testsuite/g++.dg/ext/complit7.C
new file mode 100644 (file)
index 0000000..bceb6d1
--- /dev/null
@@ -0,0 +1,4 @@
+// PR c++/27807
+// { dg-options "" }
+
+int i = (int()){0}; // { dg-error "type" }
diff --git a/gcc/testsuite/g++.dg/init/array21.C b/gcc/testsuite/g++.dg/init/array21.C
new file mode 100644 (file)
index 0000000..f41ce86
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/27722
+
+void foo()
+{
+  const int x[] = 0; // { dg-error "size" }
+  ++x;
+}
diff --git a/gcc/testsuite/g++.dg/parse/ptrmem5.C b/gcc/testsuite/g++.dg/parse/ptrmem5.C
new file mode 100644 (file)
index 0000000..1101ad9
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/27806
+
+struct A {};
+
+void foo()
+{
+  p;  // { dg-error "p" }
+  extern int A::* p;
+}
diff --git a/gcc/testsuite/g++.dg/template/static25.C b/gcc/testsuite/g++.dg/template/static25.C
new file mode 100644 (file)
index 0000000..20c0c84
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/27819
+struct A
+{
+  static const char i = 1;
+};
+
+template<int> struct B
+{
+  static const int j = A::i;
+  int x[int(j)];
+};
+
+B<0> b;