summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/decl.c')
-rw-r--r--contrib/gcc/cp/decl.c86
1 files changed, 71 insertions, 15 deletions
diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c
index c3d71bc..28e653b 100644
--- a/contrib/gcc/cp/decl.c
+++ b/contrib/gcc/cp/decl.c
@@ -1573,6 +1573,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
DECL_PURE_VIRTUAL_P (newdecl) |= DECL_PURE_VIRTUAL_P (olddecl);
DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
+ DECL_INVALID_OVERRIDER_P (newdecl) |= DECL_INVALID_OVERRIDER_P (olddecl);
DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
if (DECL_OVERLOADED_OPERATOR_P (olddecl) != ERROR_MARK)
SET_OVERLOADED_OPERATOR_CODE
@@ -2161,8 +2162,24 @@ redeclaration_error_message (tree newdecl, tree olddecl)
}
else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl))
{
- /* Objects declared at top level: */
- /* If at least one is a reference, it's ok. */
+ /* The objects have been declared at namespace scope. If either
+ is a member of an anonymous union, then this is an invalid
+ redeclaration. For example:
+
+ int i;
+ union { int i; };
+
+ is invalid. */
+ if (DECL_ANON_UNION_VAR_P (newdecl)
+ || DECL_ANON_UNION_VAR_P (olddecl))
+ return "redeclaration of %q#D";
+ /* If at least one declaration is a reference, there is no
+ conflict. For example:
+
+ int i = 3;
+ extern int i;
+
+ is valid. */
if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
return NULL;
/* Reject two definitions. */
@@ -5076,6 +5093,36 @@ initialize_artificial_var (tree decl, tree init)
make_rtl_for_nonlocal_decl (decl, init, /*asmspec=*/NULL);
}
+/* INIT is the initializer for a variable, as represented by the
+ parser. Returns true iff INIT is value-dependent. */
+
+static bool
+value_dependent_init_p (tree init)
+{
+ if (TREE_CODE (init) == TREE_LIST)
+ /* A parenthesized initializer, e.g.: int i (3, 2); ? */
+ return any_value_dependent_elements_p (init);
+ else if (TREE_CODE (init) == CONSTRUCTOR)
+ /* A brace-enclosed initializer, e.g.: int i = { 3 }; ? */
+ {
+ VEC(constructor_elt, gc) *elts;
+ size_t nelts;
+ size_t i;
+
+ elts = CONSTRUCTOR_ELTS (init);
+ nelts = VEC_length (constructor_elt, elts);
+ for (i = 0; i < nelts; ++i)
+ if (value_dependent_init_p (VEC_index (constructor_elt,
+ elts, i)->value))
+ return true;
+ }
+ else
+ /* It must be a simple expression, e.g., int i = 3; */
+ return value_dependent_expression_p (init);
+
+ return false;
+}
+
/* Finish processing of a declaration;
install its line number and initial value.
If the length of an array type is not known before,
@@ -5148,18 +5195,16 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
TREE_CONSTANT (decl) = 1;
}
- if (!init
- || !DECL_CLASS_SCOPE_P (decl)
- || !DECL_INTEGRAL_CONSTANT_VAR_P (decl)
- || type_dependent_p
- || value_dependent_expression_p (init)
- /* Check also if initializer is a value dependent
- { integral_constant_expression }. */
- || (TREE_CODE (init) == CONSTRUCTOR
- && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)) == 1
- && value_dependent_expression_p
- (VEC_index (constructor_elt,
- CONSTRUCTOR_ELTS (init), 0)->value)))
+ /* Generally, initializers in templates are expanded when the
+ template is instantiated. But, if DECL is an integral
+ constant static data member, then it can be used in future
+ integral constant expressions, and its value must be
+ available. */
+ if (!(init
+ && DECL_CLASS_SCOPE_P (decl)
+ && DECL_INTEGRAL_CONSTANT_VAR_P (decl)
+ && !type_dependent_p
+ && !value_dependent_init_p (init)))
{
if (init)
DECL_INITIAL (decl) = init;
@@ -5368,7 +5413,18 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
initializer. It is not legal to redeclare a static data
member, so this issue does not arise in that case. */
if (var_definition_p && TREE_STATIC (decl))
- expand_static_init (decl, init);
+ {
+ /* If a TREE_READONLY variable needs initialization
+ at runtime, it is no longer readonly and we need to
+ avoid MEM_READONLY_P being set on RTL created for it. */
+ if (init)
+ {
+ if (TREE_READONLY (decl))
+ TREE_READONLY (decl) = 0;
+ was_readonly = 0;
+ }
+ expand_static_init (decl, init);
+ }
}
}
OpenPOWER on IntegriCloud