OSDN Git Service

PR c++/54652
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 2379489..955fd0f 100644 (file)
@@ -917,7 +917,7 @@ push_local_name (tree decl)
          if (!DECL_LANG_SPECIFIC (decl))
            retrofit_lang_decl (decl);
          DECL_LANG_SPECIFIC (decl)->u.base.u2sel = 1;
-         if (DECL_LANG_SPECIFIC (t))
+         if (DECL_DISCRIMINATOR_SET_P (t))
            DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1;
          else
            DECL_DISCRIMINATOR (decl) = 1;
@@ -1815,9 +1815,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       /* Merge the data types specified in the two decls.  */
       newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
 
-      /* If merge_types produces a non-typedef type, just use the old type.  */
-      if (TREE_CODE (newdecl) == TYPE_DECL
-         && newtype == DECL_ORIGINAL_TYPE (newdecl))
+      /* For typedefs use the old type, as the new type's DECL_NAME points
+        at newdecl, which will be ggc_freed.  */
+      if (TREE_CODE (newdecl) == TYPE_DECL)
        newtype = oldtype;
 
       if (TREE_CODE (newdecl) == VAR_DECL)
@@ -5556,7 +5556,9 @@ check_initializer (tree decl, tree init, int flags, VEC(tree,gc) **cleanups)
       if ((type_build_ctor_call (type) || CLASS_TYPE_P (type))
          && !(flags & LOOKUP_ALREADY_DIGESTED)
          && !(init && BRACE_ENCLOSED_INITIALIZER_P (init)
-              && CP_AGGREGATE_TYPE_P (type)))
+              && CP_AGGREGATE_TYPE_P (type)
+              && (CLASS_TYPE_P (type)
+                  || type_has_extended_temps (type))))
        {
          init_code = build_aggr_init_full_exprs (decl, init, flags);
 
@@ -6318,6 +6320,10 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
            }
          else if (was_readonly)
            TREE_READONLY (decl) = 1;
+
+         /* Likewise if it needs destruction.  */
+         if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+           TREE_READONLY (decl) = 0;
        }
 
       make_rtl_for_nonlocal_decl (decl, init, asmspec);
@@ -8300,6 +8306,23 @@ check_var_type (tree identifier, tree type)
   return type;
 }
 
+/* Functions for adjusting the visibility of a tagged type and its nested
+   types when it gets a name for linkage purposes from a typedef.  */
+
+static void bt_reset_linkage (binding_entry, void *);
+static void
+reset_type_linkage (tree type)
+{
+  set_linkage_according_to_type (type, TYPE_MAIN_DECL (type));
+  if (CLASS_TYPE_P (type))
+    binding_table_foreach (CLASSTYPE_NESTED_UTDS (type), bt_reset_linkage, NULL);
+}
+static void
+bt_reset_linkage (binding_entry b, void *data ATTRIBUTE_UNUSED)
+{
+  reset_type_linkage (b->type);
+}
+
 /* Given declspecs and a declarator (abstract or otherwise), determine
    the name and type of the object declared and construct a DECL node
    for it.
@@ -9798,8 +9821,7 @@ grokdeclarator (const cp_declarator *declarator,
              = TYPE_IDENTIFIER (type);
 
          /* Adjust linkage now that we aren't anonymous anymore.  */
-         set_linkage_according_to_type (type, TYPE_MAIN_DECL (type));
-         determine_visibility (TYPE_MAIN_DECL (type));
+         reset_type_linkage (type);
 
          /* FIXME remangle member functions; member functions of a
             type with external linkage have external linkage.  */
@@ -10514,9 +10536,8 @@ static tree
 local_variable_p_walkfn (tree *tp, int *walk_subtrees,
                         void *data ATTRIBUTE_UNUSED)
 {
-  /* Check DECL_NAME to avoid including temporaries.  We don't check
-     DECL_ARTIFICIAL because we do want to complain about 'this'.  */
-  if (local_variable_p (*tp) && DECL_NAME (*tp))
+  if (local_variable_p (*tp)
+      && (!DECL_ARTIFICIAL (*tp) || DECL_NAME (*tp) == this_identifier))
     return *tp;
   else if (TYPE_P (*tp))
     *walk_subtrees = 0;
@@ -11439,9 +11460,6 @@ check_elaborated_type_specifier (enum tag_types tag_code,
 {
   tree type;
 
-  if (decl == error_mark_node)
-    return error_mark_node;
-
   /* In the case of:
 
        struct S { struct S *p; };
@@ -12928,10 +12946,9 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       if (DECL_NOT_REALLY_EXTERN (decl1))
        DECL_EXTERNAL (decl1) = 0;
 
-      if (ctx != NULL_TREE && DECL_DECLARED_INLINE_P (ctx)
-         && TREE_PUBLIC (ctx))
+      if (ctx != NULL_TREE && vague_linkage_p (ctx))
        /* This is a function in a local class in an extern inline
-          function.  */
+          or template function.  */
        comdat_linkage (decl1);
     }
   /* If this function belongs to an interface, it is public.