diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 134 |
1 files changed, 61 insertions, 73 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 980a38a..fb6c776 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -67,7 +67,6 @@ static int ambi_op_p PARAMS ((enum tree_code)); static int unary_op_p PARAMS ((enum tree_code)); static tree store_bindings PARAMS ((tree, tree)); static tree lookup_tag_reverse PARAMS ((tree, tree)); -static tree obscure_complex_init PARAMS ((tree, tree)); static tree lookup_name_real PARAMS ((tree, int, int, int)); static void push_local_name PARAMS ((tree)); static void warn_extern_redeclared_static PARAMS ((tree, tree)); @@ -3460,7 +3459,11 @@ duplicate_decls (newdecl, olddecl) newtype = oldtype; if (TREE_CODE (newdecl) == VAR_DECL) - DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); + { + DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); + DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl); + } + /* Do this after calling `merge_types' so that default parameters don't confuse us. */ else if (TREE_CODE (newdecl) == FUNCTION_DECL @@ -7548,45 +7551,6 @@ grok_reference_init (decl, type, init) return NULL_TREE; } -/* Fill in DECL_INITIAL with some magical value to prevent expand_decl from - mucking with forces it does not comprehend (i.e. initialization with a - constructor). If we are at global scope and won't go into COMMON, fill - it in with a dummy CONSTRUCTOR to force the variable into .data; - otherwise we can use error_mark_node. */ - -static tree -obscure_complex_init (decl, init) - tree decl, init; -{ - if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) - { - error ("run-time initialization of thread-local storage"); - return NULL_TREE; - } - - if (! flag_no_inline && TREE_STATIC (decl)) - { - if (extract_init (decl, init)) - return NULL_TREE; - } - -#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS) - if (toplevel_bindings_p () && ! DECL_COMMON (decl)) - DECL_INITIAL (decl) = build (CONSTRUCTOR, TREE_TYPE (decl), NULL_TREE, - NULL_TREE); - else -#endif - { - if (zero_init_p (TREE_TYPE (decl))) - DECL_INITIAL (decl) = error_mark_node; - /* Otherwise, force_store_init_value will have already stored a - zero-init initializer in DECL_INITIAL, that should be - retained. */ - } - - return init; -} - /* When parsing `int a[] = {1, 2};' we don't know the size of the array until we finish parsing the initializer. If that's the situation we're in, update DECL accordingly. */ @@ -7773,17 +7737,18 @@ check_initializer (decl, init) tree decl; tree init; { - tree type; - - if (TREE_CODE (decl) == FIELD_DECL) - return init; - - type = TREE_TYPE (decl); + tree type = TREE_TYPE (decl); /* If `start_decl' didn't like having an initialization, ignore it now. */ if (init != NULL_TREE && DECL_INITIAL (decl) == NULL_TREE) init = NULL_TREE; + /* If an initializer is present, DECL_INITIAL has been + error_mark_node, to indicate that an as-of-yet unevaluated + initialization will occur. From now on, DECL_INITIAL reflects + the static initialization -- if any -- of DECL. */ + DECL_INITIAL (decl) = NULL_TREE; + /* Check the initializer. */ if (init) { @@ -7823,21 +7788,9 @@ check_initializer (decl, init) init = NULL_TREE; } else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE) - { - init = grok_reference_init (decl, type, init); - if (init) - init = obscure_complex_init (decl, init); - } - else if (!DECL_EXTERNAL (decl) && !zero_init_p (type)) - { - force_store_init_value (decl, build_forced_zero_init (type)); - - if (init) - goto process_init; - } + init = grok_reference_init (decl, type, init); else if (init) { - process_init: if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type)) { if (TREE_CODE (type) == ARRAY_TYPE) @@ -7861,11 +7814,6 @@ check_initializer (decl, init) if (TREE_CODE (init) != TREE_VEC) init = store_init_value (decl, init); } - - if (init) - /* We must hide the initializer so that expand_decl - won't try to do something it does not understand. */ - init = obscure_complex_init (decl, init); } else if (DECL_EXTERNAL (decl)) ; @@ -7884,10 +7832,6 @@ check_initializer (decl, init) } check_for_uninitialized_const_var (decl); - - if (COMPLETE_TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type)) - init = obscure_complex_init (decl, NULL_TREE); - } else check_for_uninitialized_const_var (decl); @@ -8255,10 +8199,54 @@ cp_finish_decl (decl, init, asmspec_tree, flags) SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec)); make_decl_rtl (decl, asmspec); } - - /* Deduce size of array from initialization, if not already known. */ - init = check_initializer (decl, init); - maybe_deduce_size_from_array_init (decl, init); + else if (TREE_CODE (decl) == RESULT_DECL) + init = check_initializer (decl, init); + else if (TREE_CODE (decl) == VAR_DECL) + { + /* Only PODs can have thread-local storage. Other types may require + various kinds of non-trivial initialization. */ + if (DECL_THREAD_LOCAL (decl) && !pod_type_p (TREE_TYPE (decl))) + error ("`%D' cannot be thread-local because it has non-POD type `%T'", + decl, TREE_TYPE (decl)); + /* Convert the initializer to the type of DECL, if we have not + already initialized DECL. */ + if (!DECL_INITIALIZED_P (decl) + /* If !DECL_EXTERNAL then DECL is being defined. In the + case of a static data memberm initialized inside the + class-specifier, there can be an initializer even if DECL + is *not* defined. */ + && (!DECL_EXTERNAL (decl) || init)) + { + init = check_initializer (decl, init); + /* If DECL has an array type without a specific bound, deduce the + array size from the initializer. Note that this must be done + after check_initializer is called because of cases like this: + + struct S { int a; int b; }; + struct S a[] = { 1, 2 }; + + which creates a one-element array, not a two-element array. */ + maybe_deduce_size_from_array_init (decl, init); + /* Handle: + + [dcl.init] + + The memory occupied by any object of static storage + duration is zero-initialized at program startup before + any other initialization takes place. + + We cannot create an appropriate initializer until after + the type of DECL is finalized. If DECL_INITIAL is set, + then the DECL is statically initialized, and any + necessary zero-initialization has already been performed. */ + if (TREE_STATIC (decl) && !DECL_INITIAL (decl)) + DECL_INITIAL (decl) = build_zero_init (TREE_TYPE (decl), + /*static_storage_p=*/true); + /* Remember that the initialization for this variable has + taken place. */ + DECL_INITIALIZED_P (decl) = 1; + } + } /* Add this declaration to the statement-tree. This needs to happen after the call to check_initializer so that the DECL_STMT for a |