aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c54
-rw-r--r--gcc/cp/pt.c13
4 files changed, 67 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 965ee6e..d2dbe4e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2011-04-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/48707
+ * decl.c (type_dependent_init_p): New.
+ (cp_finish_decl): Check it.
+ * pt.c (any_type_dependent_elements_p): New.
+ * cp-tree.h: Declare it.
+
2011-04-20 Jason Merrill <jason@redhat.com>
* semantics.c (finish_compound_literal): Don't put an array
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e538825..66ac4e8 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5105,6 +5105,7 @@ extern bool dependent_template_p (tree);
extern bool dependent_template_id_p (tree, tree);
extern bool type_dependent_expression_p (tree);
extern bool any_type_dependent_arguments_p (const VEC(tree,gc) *);
+extern bool any_type_dependent_elements_p (const_tree);
extern bool type_dependent_expression_p_push (tree);
extern bool value_dependent_expression_p (tree);
extern bool any_value_dependent_elements_p (const_tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index cf4a40e..dcd18ab 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5701,6 +5701,36 @@ initialize_artificial_var (tree decl, VEC(constructor_elt,gc) *v)
}
/* INIT is the initializer for a variable, as represented by the
+ parser. Returns true iff INIT is type-dependent. */
+
+static bool
+type_dependent_init_p (tree init)
+{
+ if (TREE_CODE (init) == TREE_LIST)
+ /* A parenthesized initializer, e.g.: int i (3, 2); ? */
+ return any_type_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 (type_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 type_dependent_expression_p (init);
+
+ return false;
+}
+
+/* INIT is the initializer for a variable, as represented by the
parser. Returns true iff INIT is value-dependent. */
static bool
@@ -5876,19 +5906,25 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
template is instantiated. But, if DECL is a variable constant
then it can be used in future constant expressions, so its value
must be available. */
- if (init
- && init_const_expr_p
- && !type_dependent_p
- && decl_maybe_constant_var_p (decl)
- && !value_dependent_init_p (init))
- {
+
+ if (TREE_CODE (decl) != VAR_DECL || dependent_type_p (type))
+ /* We can't do anything if the decl has dependent type. */;
+ else if (init
+ && init_const_expr_p
+ && !type_dependent_p
+ && decl_maybe_constant_var_p (decl)
+ && !type_dependent_init_p (init)
+ && !value_dependent_init_p (init))
+ {
+ /* This variable seems to be a non-dependent constant, so process
+ its initializer. If check_initializer returns non-null the
+ initialization wasn't constant after all. */
tree init_code = check_initializer (decl, init, flags, &cleanup);
if (init_code == NULL_TREE)
init = NULL_TREE;
}
- else if (TREE_CODE (decl) == VAR_DECL
- && !DECL_PRETTY_FUNCTION_P (decl)
- && !type_dependent_p)
+ else if (!DECL_PRETTY_FUNCTION_P (decl))
+ /* Deduce array size even if the initializer is dependent. */
maybe_deduce_size_from_array_init (decl, init);
if (init)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index fc69a0c..70fcbba 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -18457,6 +18457,19 @@ any_type_dependent_arguments_p (const VEC(tree,gc) *args)
}
/* Returns TRUE if LIST (a TREE_LIST whose TREE_VALUEs are
+ expressions) contains any type-dependent expressions. */
+
+bool
+any_type_dependent_elements_p (const_tree list)
+{
+ for (; list; list = TREE_CHAIN (list))
+ if (value_dependent_expression_p (TREE_VALUE (list)))
+ return true;
+
+ return false;
+}
+
+/* Returns TRUE if LIST (a TREE_LIST whose TREE_VALUEs are
expressions) contains any value-dependent expressions. */
bool