diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 54 | ||||
-rw-r--r-- | gcc/cp/pt.c | 13 |
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 |