OSDN Git Service

PR c++/54652
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 2fc794b..955fd0f 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C++ compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -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;
@@ -952,6 +952,8 @@ decls_match (tree newdecl, tree olddecl)
        interested in their types.  */
     return 0;
 
+  gcc_assert (DECL_P (newdecl));
+
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
       tree f1 = TREE_TYPE (newdecl);
@@ -1698,7 +1700,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          /* Don't warn about extern decl followed by definition.  */
          && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl))
          /* Don't warn about friends, let add_friend take care of it.  */
-         && ! (newdecl_is_friend || DECL_FRIEND_P (olddecl)))
+         && ! (newdecl_is_friend || DECL_FRIEND_P (olddecl))
+         /* Don't warn about declaration followed by specialization.  */
+         && (! DECL_TEMPLATE_SPECIALIZATION (newdecl)
+             || DECL_TEMPLATE_SPECIALIZATION (olddecl)))
        {
          warning (OPT_Wredundant_decls, "redundant redeclaration of %qD in same scope", newdecl);
          warning (OPT_Wredundant_decls, "previous declaration of %q+D", olddecl);
@@ -1810,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)
@@ -2209,7 +2214,12 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       SET_DECL_INIT_PRIORITY (olddecl, DECL_INIT_PRIORITY (newdecl));
       DECL_HAS_INIT_PRIORITY_P (olddecl) = 1;
     }
-  /* Likewise for DECL_USER_ALIGN and DECL_PACKED.  */
+  /* Likewise for DECL_ALIGN, DECL_USER_ALIGN and DECL_PACKED.  */
+  if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
+    {
+      DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
+      DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
+    }
   DECL_USER_ALIGN (olddecl) = DECL_USER_ALIGN (newdecl);
   if (TREE_CODE (newdecl) == FIELD_DECL)
     DECL_PACKED (olddecl) = DECL_PACKED (newdecl);
@@ -2937,9 +2947,9 @@ tree
 define_label (location_t location, tree name)
 {
   tree ret;
-  timevar_start (TV_NAME_LOOKUP);
+  bool running = timevar_cond_start (TV_NAME_LOOKUP);
   ret = define_label_1 (location, name);
-  timevar_stop (TV_NAME_LOOKUP);
+  timevar_cond_stop (TV_NAME_LOOKUP, running);
   return ret;
 }
 
@@ -4206,6 +4216,20 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
         error ("%<constexpr%> cannot be used for type declarations");
     }
 
+  if (declspecs->attributes && declared_type)
+    {
+      location_t loc = input_location;
+      if (!CLASS_TYPE_P (declared_type)
+         || !CLASSTYPE_TEMPLATE_INSTANTIATION (declared_type))
+       /* For a non-template class, use the name location; for a template
+          class (an explicit instantiation), use the current location.  */
+       input_location = location_of (declared_type);
+      warning (0, "attribute ignored in declaration of %q#T", declared_type);
+      warning (0, "attribute for %q#T must follow the %qs keyword",
+              declared_type, class_key_or_enum_as_string (declared_type));
+      input_location = loc;
+    }
+
   return declared_type;
 }
 
@@ -4230,14 +4254,6 @@ shadow_tag (cp_decl_specifier_seq *declspecs)
   if (!t)
     return NULL_TREE;
 
-  if (declspecs->attributes)
-    {
-      warning (0, "attribute ignored in declaration of %q+#T", t);
-      warning (0, "attribute for %q+#T must follow the %qs keyword",
-              t, class_key_or_enum_as_string (t));
-
-    }
-
   if (maybe_process_partial_specialization (t) == error_mark_node)
     return NULL_TREE;
 
@@ -4404,7 +4420,8 @@ start_decl (const cp_declarator *declarator,
     }
 
   /* If #pragma weak was used, mark the decl weak now.  */
-  maybe_apply_pragma_weak (decl);
+  if (!processing_template_decl)
+    maybe_apply_pragma_weak (decl);
 
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DECLARED_INLINE_P (decl)
@@ -5539,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);
 
@@ -6301,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);
@@ -8283,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.
@@ -9476,8 +9516,6 @@ grokdeclarator (const cp_declarator *declarator,
      the object as `const'.  */
   if (constexpr_p && innermost_code != cdk_function)
     {
-      if (type_quals & TYPE_QUAL_CONST)
-        error ("both %<const%> and %<constexpr%> cannot be used here");
       if (type_quals & TYPE_QUAL_VOLATILE)
         error ("both %<volatile%> and %<constexpr%> cannot be used here");
       if (TREE_CODE (type) != REFERENCE_TYPE)
@@ -9783,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.  */
@@ -10499,7 +10536,8 @@ static tree
 local_variable_p_walkfn (tree *tp, int *walk_subtrees,
                         void *data ATTRIBUTE_UNUSED)
 {
-  if (local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
+  if (local_variable_p (*tp)
+      && (!DECL_ARTIFICIAL (*tp) || DECL_NAME (*tp) == this_identifier))
     return *tp;
   else if (TYPE_P (*tp))
     *walk_subtrees = 0;
@@ -10507,7 +10545,6 @@ local_variable_p_walkfn (tree *tp, int *walk_subtrees,
   return NULL_TREE;
 }
 
-
 /* Check that ARG, which is a default-argument expression for a
    parameter DECL, is valid.  Returns ARG, or ERROR_MARK_NODE, if
    something goes wrong.  DECL may also be a _TYPE node, rather than a
@@ -10558,6 +10595,17 @@ check_default_argument (tree decl, tree arg)
       return error_mark_node;
     }
 
+  if (warn_zero_as_null_pointer_constant
+      && c_inhibit_evaluation_warnings == 0
+      && (TYPE_PTR_P (decl_type) || TYPE_PTR_TO_MEMBER_P (decl_type))
+      && null_ptr_cst_p (arg)
+      && !NULLPTR_TYPE_P (TREE_TYPE (arg)))
+    {
+      warning (OPT_Wzero_as_null_pointer_constant,
+              "zero as null pointer constant");
+      return nullptr_node;
+    }
+
   /* [dcl.fct.default]
 
      Local variables shall not be used in default argument
@@ -10568,7 +10616,10 @@ check_default_argument (tree decl, tree arg)
   var = cp_walk_tree_without_duplicates (&arg, local_variable_p_walkfn, NULL);
   if (var)
     {
-      error ("default argument %qE uses local variable %qD", arg, var);
+      if (DECL_NAME (var) == this_identifier)
+       permerror (input_location, "default argument %qE uses %qD", arg, var);
+      else
+       error ("default argument %qE uses local variable %qD", arg, var);
       return error_mark_node;
     }
 
@@ -10813,10 +10864,6 @@ copy_fn_p (const_tree d)
 bool
 move_fn_p (const_tree d)
 {
-  tree args;
-  tree arg_type;
-  bool result = false;
-
   gcc_assert (DECL_FUNCTION_MEMBER_P (d));
 
   if (cxx_dialect == cxx98)
@@ -10826,12 +10873,29 @@ move_fn_p (const_tree d)
   if (TREE_CODE (d) == TEMPLATE_DECL
       || (DECL_TEMPLATE_INFO (d)
          && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))))
-    /* Instantiations of template member functions are never copy
+    /* Instantiations of template member functions are never move
        functions.  Note that member functions of templated classes are
        represented as template functions internally, and we must
-       accept those as copy functions.  */
+       accept those as move functions.  */
     return 0;
 
+  return move_signature_fn_p (d);
+}
+
+/* D is a constructor or overloaded `operator='.
+
+   Then, this function returns true when D has the same signature as a move
+   constructor or move assignment operator (because either it is such a
+   ctor/op= or it is a template specialization with the same signature),
+   false otherwise.  */
+
+bool
+move_signature_fn_p (const_tree d)
+{
+  tree args;
+  tree arg_type;
+  bool result = false;
+
   args = FUNCTION_FIRST_USER_PARMTYPE (d);
   if (!args)
     return 0;
@@ -11396,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; };
@@ -11866,7 +11927,7 @@ xref_basetypes (tree ref, tree base_list)
        TYPE_FOR_JAVA (ref) = 1;
 
       base_binfo = NULL_TREE;
-      if (CLASS_TYPE_P (basetype) && !dependent_type_p (basetype))
+      if (CLASS_TYPE_P (basetype) && !dependent_scope_p (basetype))
        {
          base_binfo = TYPE_BINFO (basetype);
          /* The original basetype could have been a typedef'd type.  */
@@ -11911,8 +11972,8 @@ xref_basetypes (tree ref, tree base_list)
       BINFO_BASE_ACCESS_APPEND (binfo, access);
     }
 
-  if (VEC_space (tree, CLASSTYPE_VBASECLASSES (ref), 1))
-    /* If we have space in the vbase vector, we must have shared at
+  if (VEC_length (tree, CLASSTYPE_VBASECLASSES (ref)) < max_vbases)
+    /* If we didn't get max_vbases vbases, we must have shared at
        least one of them, and are therefore diamond shaped.  */
     CLASSTYPE_DIAMOND_SHAPED_P (ref) = 1;
 
@@ -12315,6 +12376,12 @@ finish_enum_value_list (tree enumtype)
   for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t))
     TYPE_VALUES (t) = TYPE_VALUES (enumtype);
 
+  if (at_class_scope_p ()
+      && COMPLETE_TYPE_P (current_class_type)
+      && UNSCOPED_ENUM_P (enumtype))
+    insert_late_enum_def_into_classtype_sorted_fields (enumtype,
+                                                      current_class_type);
+
   /* Finish debugging output for this type.  */
   rest_of_type_compilation (enumtype, namespace_bindings_p ());
 }
@@ -12369,14 +12436,11 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
        {
          value = cxx_constant_value (value);
 
-         if (TREE_CODE (value) == INTEGER_CST
-             && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (value)))
-           {
-             value = perform_integral_promotions (value);
-           }
-         else
+         if (TREE_CODE (value) != INTEGER_CST
+             || ! INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (value)))
            {
-             error ("enumerator value for %qD is not an integer constant", name);
+             error ("enumerator value for %qD is not an integer constant",
+                    name);
              value = NULL_TREE;
            }
        }
@@ -12882,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.