OSDN Git Service

PR c++/29175
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 542fcbe..e95870d 100644 (file)
@@ -3745,7 +3745,8 @@ shadow_tag (cp_decl_specifier_seq *declspecs)
 
     }
 
-  maybe_process_partial_specialization (t);
+  if (maybe_process_partial_specialization (t) == error_mark_node)
+    return NULL_TREE;
 
   /* This is where the variables in an anonymous union are
      declared.  An anonymous union declaration looks like:
@@ -4702,32 +4703,46 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
 
   if (type == error_mark_node)
     /* We will have already complained.  */
-    init = NULL_TREE;
-  else if (init && COMPLETE_TYPE_P (type)
-          && !TREE_CONSTANT (TYPE_SIZE (type)))
-    {
-      error ("variable-sized object %qD may not be initialized", decl);
-      init = NULL_TREE;
-    }
-  else if (TREE_CODE (type) == ARRAY_TYPE
-          && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
+    return NULL_TREE;
+
+  if (TREE_CODE (type) == ARRAY_TYPE)
     {
-      error ("elements of array %q#D have incomplete type", decl);
-      init = NULL_TREE;
+      tree element_type = TREE_TYPE (type);
+
+      /* The array type itself need not be complete, because the
+        initializer may tell us how many elements are in the array.
+        But, the elements of the array must be complete.  */
+      if (!COMPLETE_TYPE_P (complete_type (element_type)))
+       {
+         error ("elements of array %q#D have incomplete type", decl);
+         return NULL_TREE;
+       }
+      /* It is not valid to initialize an a VLA.  */
+      if (init
+         && ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type)))
+             || !TREE_CONSTANT (TYPE_SIZE (element_type))))
+       {
+         error ("variable-sized object %qD may not be initialized", decl);
+         return NULL_TREE;
+       }
     }
-  else if (TREE_CODE (type) != ARRAY_TYPE && !COMPLETE_TYPE_P (type))
+  else if (!COMPLETE_TYPE_P (type))
     {
       error ("%qD has incomplete type", decl);
       TREE_TYPE (decl) = error_mark_node;
-      init = NULL_TREE;
+      return NULL_TREE;
     }
-  else if (!CP_AGGREGATE_TYPE_P (type)
-          && init && BRACE_ENCLOSED_INITIALIZER_P (init)
-          && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)) != 1)
+  else
+    /* There is no way to make a variable-sized class type in GNU C++.  */
+    gcc_assert (TREE_CONSTANT (TYPE_SIZE (type)));
+  
+  if (!CP_AGGREGATE_TYPE_P (type)
+      && init && BRACE_ENCLOSED_INITIALIZER_P (init)
+      && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)) != 1)
     {
       error ("scalar object %qD requires one element in initializer", decl);
       TREE_TYPE (decl) = error_mark_node;
-      init = NULL_TREE;
+      return NULL_TREE;
     }
 
   if (TREE_CODE (decl) == CONST_DECL)
@@ -4908,7 +4923,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
     {
       /* Fool with the linkage of static consts according to #pragma
         interface.  */
-      struct c_fileinfo *finfo = get_fileinfo (lbasename (filename));
+      struct c_fileinfo *finfo = get_fileinfo (filename);
       if (!finfo->interface_unknown && !TREE_PUBLIC (decl))
        {
          TREE_PUBLIC (decl) = 1;
@@ -7014,8 +7029,6 @@ grokdeclarator (const cp_declarator *declarator,
                  tree fns = TREE_OPERAND (decl, 0);
 
                  dname = fns;
-                 if (TREE_CODE (dname) == COMPONENT_REF)
-                   dname = TREE_OPERAND (dname, 1);
                  if (TREE_CODE (dname) != IDENTIFIER_NODE)
                    {
                      gcc_assert (is_overloaded_fn (dname));
@@ -7118,7 +7131,11 @@ grokdeclarator (const cp_declarator *declarator,
   /* If there were multiple types specified in the decl-specifier-seq,
      issue an error message.  */
   if (declspecs->multiple_types_p)
-    error ("two or more data types in declaration of %qs", name);
+    {
+      error ("two or more data types in declaration of %qs", name);
+      return error_mark_node;
+    }
+
   /* Extract the basic type from the decl-specifier-seq.  */
   type = declspecs->type;
   if (type == error_mark_node)
@@ -7399,9 +7416,9 @@ grokdeclarator (const cp_declarator *declarator,
 
   /* Warn about storage classes that are invalid for certain
      kinds of declarations (parameters, typenames, etc.).  */
-  if (declspecs->multiple_storage_classes_p)
+  if (declspecs->conflicting_specifiers_p)
     {
-      error ("multiple storage classes in declaration of %qs", name);
+      error ("conflicting specifiers in declaration of %qs", name);
       storage_class = sc_none;
     }
   else if (thread_p
@@ -9709,7 +9726,10 @@ xref_tag (enum tag_types tag_code, tree name,
   else
     {
       if (template_header_p && IS_AGGR_TYPE (t))
-       redeclare_class_template (t, current_template_parms);
+        {
+         if (!redeclare_class_template (t, current_template_parms))
+            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+        }
       else if (!processing_template_decl
               && CLASS_TYPE_P (t)
               && CLASSTYPE_IS_TEMPLATE (t))
@@ -10359,7 +10379,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   struct cp_binding_level *bl;
   tree current_function_parms;
   struct c_fileinfo *finfo
-    = get_fileinfo (lbasename (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1))));
+    = get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)));
   bool honor_interface;
 
   /* Sanity check.  */
@@ -11090,7 +11110,8 @@ finish_function (int flags)
   /* If this function can't throw any exceptions, remember that.  */
   if (!processing_template_decl
       && !cp_function_chain->can_throw
-      && !flag_non_call_exceptions)
+      && !flag_non_call_exceptions
+      && targetm.binds_local_p (fndecl))
     TREE_NOTHROW (fndecl) = 1;
 
   /* This must come after expand_function_end because cleanups might