X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fdecl2.c;h=a0ae6e4f7be2d4c91d441b5b5db447c4dde51095;hb=cb5526cd76771c78bf232a61fcf3472e0faaf5fc;hp=a156e32dcdb9227dfbb991677f1f14a08034bbde;hpb=3b116dc2623db18f724f1c62f3d610c6613a2a3c;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a156e32dcdb..a0ae6e4f7be 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see #include "c-pragma.h" #include "tree-dump.h" #include "intl.h" +#include "gimple.h" extern cpp_reader *parse_in; @@ -353,7 +354,7 @@ grok_array_decl (tree array_expr, tree index_exp) if (array_expr == error_mark_node || index_exp == error_mark_node) error ("ambiguous conversion for array subscript"); - expr = build_array_ref (array_expr, index_exp); + expr = build_array_ref (array_expr, index_exp, input_location); } if (processing_template_decl && expr != error_mark_node) return build_min_non_dep (ARRAY_REF, expr, orig_array_expr, orig_index_exp, @@ -637,8 +638,9 @@ check_classfn (tree ctype, tree function, tree template_parms) return OVL_CURRENT (fndecls); } - error ("prototype for %q#D does not match any in class %qT", - function, ctype); + error_at (DECL_SOURCE_LOCATION (function), + "prototype for %q#D does not match any in class %qT", + function, ctype); is_conv_op = DECL_CONV_FN_P (fndecl); if (is_conv_op) @@ -717,7 +719,7 @@ finish_static_data_member_decl (tree decl, VEC_safe_push (tree, gc, pending_statics, decl); if (LOCAL_CLASS_P (current_class_type)) - permerror ("local class %q#T shall not have static data member %q#D", + permerror (input_location, "local class %q#T shall not have static data member %q#D", current_class_type, decl); /* Static consts need not be initialized in the class definition. */ @@ -801,7 +803,17 @@ grokfield (const cp_declarator *declarator, value = push_template_decl (value); if (attrlist) - cplus_decl_attributes (&value, attrlist, 0); + { + int attrflags = 0; + + /* If this is a typedef that names the class for linkage purposes + (7.1.3p8), apply any attributes directly to the type. */ + if (TAGGED_TYPE_P (TREE_TYPE (value)) + && value == TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (value)))) + attrflags = ATTR_FLAG_TYPE_IN_PLACE; + + cplus_decl_attributes (&value, attrlist, attrflags); + } return value; } @@ -836,7 +848,6 @@ grokfield (const cp_declarator *declarator, DECL_DEFAULTED_FN (value) = 1; DECL_INITIALIZED_IN_CLASS_P (value) = 1; DECL_DECLARED_INLINE_P (value) = 1; - DECL_INLINE (value) = 1; } } else if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE) @@ -1260,15 +1271,15 @@ build_anon_union_vars (tree type, tree object) continue; if (TREE_CODE (field) != FIELD_DECL) { - permerror ("%q+#D invalid; an anonymous union can only " + permerror (input_location, "%q+#D invalid; an anonymous union can only " "have non-static data members", field); continue; } if (TREE_PRIVATE (field)) - permerror ("private member %q+#D in anonymous union", field); + permerror (input_location, "private member %q+#D in anonymous union", field); else if (TREE_PROTECTED (field)) - permerror ("protected member %q+#D in anonymous union", field); + permerror (input_location, "protected member %q+#D in anonymous union", field); if (processing_template_decl) ref = build_min_nt (COMPONENT_REF, object, @@ -1403,7 +1414,7 @@ coerce_new_type (tree type) e = 2; if (e == 2) - permerror ("% takes type % (%qT) " + permerror (input_location, "% takes type % (%qT) " "as first parameter", size_type_node); switch (e) @@ -2529,14 +2540,16 @@ get_guard_cond (tree guard) guard_value = integer_one_node; if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard))) guard_value = convert (TREE_TYPE (guard), guard_value); - guard = cp_build_binary_op (BIT_AND_EXPR, guard, guard_value, + guard = cp_build_binary_op (input_location, + BIT_AND_EXPR, guard, guard_value, tf_warning_or_error); } guard_value = integer_zero_node; if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard))) guard_value = convert (TREE_TYPE (guard), guard_value); - return cp_build_binary_op (EQ_EXPR, guard, guard_value, + return cp_build_binary_op (input_location, + EQ_EXPR, guard, guard_value, tf_warning_or_error); } @@ -2701,7 +2714,6 @@ start_static_storage_duration_function (unsigned count) type); TREE_PUBLIC (ssdf_decl) = 0; DECL_ARTIFICIAL (ssdf_decl) = 1; - DECL_INLINE (ssdf_decl) = 1; /* Put this function in the list of functions to be called from the static constructors and destructors. */ @@ -2812,6 +2824,38 @@ get_priority_info (int priority) || DECL_ONE_ONLY (decl) \ || DECL_WEAK (decl))) +/* Called from one_static_initialization_or_destruction(), + via walk_tree. + Walks the initializer list of a global variable and looks for + temporary variables (DECL_NAME() == NULL and DECL_ARTIFICIAL != 0) + and that have their DECL_CONTEXT() == NULL. + For each such temporary variable, set their DECL_CONTEXT() to + the current function. This is necessary because otherwise + some optimizers (enabled by -O2 -fprofile-arcs) might crash + when trying to refer to a temporary variable that does not have + it's DECL_CONTECT() properly set. */ +static tree +fix_temporary_vars_context_r (tree *node, + int *unused ATTRIBUTE_UNUSED, + void *unused1 ATTRIBUTE_UNUSED) +{ + gcc_assert (current_function_decl); + + if (TREE_CODE (*node) == BIND_EXPR) + { + tree var; + + for (var = BIND_EXPR_VARS (*node); var; var = TREE_CHAIN (var)) + if (TREE_CODE (var) == VAR_DECL + && !DECL_NAME (var) + && DECL_ARTIFICIAL (var) + && !DECL_CONTEXT (var)) + DECL_CONTEXT (var) = current_function_decl; + } + + return NULL_TREE; +} + /* Set up to handle the initialization or destruction of DECL. If INITP is nonzero, we are initializing the variable. Otherwise, we are destroying it. */ @@ -2834,6 +2878,19 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp) information. */ input_location = DECL_SOURCE_LOCATION (decl); + /* Make sure temporary variables in the initialiser all have + their DECL_CONTEXT() set to a value different from NULL_TREE. + This can happen when global variables initialisers are built. + In that case, the DECL_CONTEXT() of the global variables _AND_ of all + the temporary variables that might have been generated in the + accompagning initialisers is NULL_TREE, meaning the variables have been + declared in the global namespace. + What we want to do here is to fix that and make sure the DECL_CONTEXT() + of the temporaries are set to the current function decl. */ + cp_walk_tree_without_duplicates (&init, + fix_temporary_vars_context_r, + NULL); + /* Because of: [class.access.spec] @@ -2882,20 +2939,22 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp) last to destroy the variable. */ else if (initp) guard_cond - = cp_build_binary_op (EQ_EXPR, + = cp_build_binary_op (input_location, + EQ_EXPR, cp_build_unary_op (PREINCREMENT_EXPR, - guard, - /*noconvert=*/1, - tf_warning_or_error), + guard, + /*noconvert=*/1, + tf_warning_or_error), integer_one_node, tf_warning_or_error); else guard_cond - = cp_build_binary_op (EQ_EXPR, + = cp_build_binary_op (input_location, + EQ_EXPR, cp_build_unary_op (PREDECREMENT_EXPR, - guard, - /*noconvert=*/1, - tf_warning_or_error), + guard, + /*noconvert=*/1, + tf_warning_or_error), integer_zero_node, tf_warning_or_error); @@ -2948,7 +3007,8 @@ do_static_initialization_or_destruction (tree vars, bool initp) /* Build the outer if-stmt to check for initialization or destruction. */ init_if_stmt = begin_if_stmt (); cond = initp ? integer_one_node : integer_zero_node; - cond = cp_build_binary_op (EQ_EXPR, + cond = cp_build_binary_op (input_location, + EQ_EXPR, initialize_p_decl, cond, tf_warning_or_error); @@ -2981,7 +3041,8 @@ do_static_initialization_or_destruction (tree vars, bool initp) /* Conditionalize this initialization on being in the right priority and being initializing/finalizing appropriately. */ priority_if_stmt = begin_if_stmt (); - cond = cp_build_binary_op (EQ_EXPR, + cond = cp_build_binary_op (input_location, + EQ_EXPR, priority_decl, build_int_cst (NULL_TREE, priority), tf_warning_or_error); @@ -3439,7 +3500,7 @@ cp_write_global_declarations (void) reconsider = true; } - if (!DECL_SAVED_TREE (decl)) + if (!gimple_body (decl)) continue; /* We lie to the back end, pretending that some functions @@ -3723,9 +3784,24 @@ mark_used (tree decl) TREE_USED (decl) = 1; if (DECL_CLONED_FUNCTION_P (decl)) TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1; + if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_DELETED_FN (decl)) + { + error ("deleted function %q+D", decl); + error ("used here"); + } /* If we don't need a value, then we don't need to synthesize DECL. */ if (skip_evaluation) return; + + /* If within finish_function, defer the rest until that function + finishes, otherwise it might recurse. */ + if (defer_mark_used_calls) + { + VEC_safe_push (tree, gc, deferred_mark_used_calls, decl); + return; + } + /* Normally, we can wait until instantiation-time to synthesize DECL. However, if DECL is a static data member initialized with a constant, we need the value right now because a reference to @@ -3786,12 +3862,6 @@ mark_used (tree decl) /* If we've already synthesized the method we don't need to do the instantiation test below. */ } - else if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_DELETED_FN (decl)) - { - error ("deleted function %q+D", decl); - error ("used here"); - } else if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL) && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) && (!DECL_EXPLICIT_INSTANTIATION (decl)