From d95f258e9027e7d797bde4eace3e29ab7d9382db Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 25 Apr 2011 17:51:33 -0400 Subject: [PATCH] re PR c++/48707 ([c++0x] ICE initializing static const int) 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. From-SVN: r172941 --- gcc/cp/ChangeLog | 8 +++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl.c | 54 +++++++++++++++---- gcc/cp/pt.c | 13 +++++ gcc/testsuite/ChangeLog | 4 ++ .../g++.dg/cpp0x/regress/template-const2.C | 14 +++++ 6 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/regress/template-const2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 965ee6ee73b..d2dbe4ea2e8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2011-04-25 Jason Merrill + + 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 * 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 e5388259ae6..66ac4e8d26d 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 cf4a40efed3..dcd18ab5b88 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5700,6 +5700,36 @@ initialize_artificial_var (tree decl, VEC(constructor_elt,gc) *v) 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 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. */ @@ -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 fc69a0c11e0..70fcbba7395 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -18456,6 +18456,19 @@ any_type_dependent_arguments_p (const VEC(tree,gc) *args) return false; } +/* 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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 793c8266ca4..cd361e7e18c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2011-04-25 Jason Merrill + + * g++.dg/cpp0x/regress/template-const2.C: New. + 2011-04-25 Jeff Law * gcc.dg/tree-ssa/vrp56.c: new test. diff --git a/gcc/testsuite/g++.dg/cpp0x/regress/template-const2.C b/gcc/testsuite/g++.dg/cpp0x/regress/template-const2.C new file mode 100644 index 00000000000..25354b3a54a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/regress/template-const2.C @@ -0,0 +1,14 @@ +// PR c++/48707 +// { dg-options -std=c++0x } + +struct A { + static int a(); +}; + +template +struct B: A { + static int const b; +}; + +template +int const B::b=B::a(); -- 2.30.2