aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c134
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