Commit d95f258e by Jason Merrill Committed by Jason Merrill

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
parent 4d583bb9
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> 2011-04-20 Jason Merrill <jason@redhat.com>
* semantics.c (finish_compound_literal): Don't put an array * semantics.c (finish_compound_literal): Don't put an array
......
...@@ -5105,6 +5105,7 @@ extern bool dependent_template_p (tree); ...@@ -5105,6 +5105,7 @@ extern bool dependent_template_p (tree);
extern bool dependent_template_id_p (tree, tree); extern bool dependent_template_id_p (tree, tree);
extern bool type_dependent_expression_p (tree); extern bool type_dependent_expression_p (tree);
extern bool any_type_dependent_arguments_p (const VEC(tree,gc) *); 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 type_dependent_expression_p_push (tree);
extern bool value_dependent_expression_p (tree); extern bool value_dependent_expression_p (tree);
extern bool any_value_dependent_elements_p (const_tree); extern bool any_value_dependent_elements_p (const_tree);
......
...@@ -5701,6 +5701,36 @@ initialize_artificial_var (tree decl, VEC(constructor_elt,gc) *v) ...@@ -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 /* 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. */ parser. Returns true iff INIT is value-dependent. */
static bool static bool
...@@ -5876,19 +5906,25 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, ...@@ -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 template is instantiated. But, if DECL is a variable constant
then it can be used in future constant expressions, so its value then it can be used in future constant expressions, so its value
must be available. */ must be available. */
if (init
&& init_const_expr_p if (TREE_CODE (decl) != VAR_DECL || dependent_type_p (type))
&& !type_dependent_p /* We can't do anything if the decl has dependent type. */;
&& decl_maybe_constant_var_p (decl) else if (init
&& !value_dependent_init_p (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); tree init_code = check_initializer (decl, init, flags, &cleanup);
if (init_code == NULL_TREE) if (init_code == NULL_TREE)
init = NULL_TREE; init = NULL_TREE;
} }
else if (TREE_CODE (decl) == VAR_DECL else if (!DECL_PRETTY_FUNCTION_P (decl))
&& !DECL_PRETTY_FUNCTION_P (decl) /* Deduce array size even if the initializer is dependent. */
&& !type_dependent_p)
maybe_deduce_size_from_array_init (decl, init); maybe_deduce_size_from_array_init (decl, init);
if (init) if (init)
......
...@@ -18457,6 +18457,19 @@ any_type_dependent_arguments_p (const VEC(tree,gc) *args) ...@@ -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 /* 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. */ expressions) contains any value-dependent expressions. */
bool bool
......
2011-04-25 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/regress/template-const2.C: New.
2011-04-25 Jeff Law <law@redhat.com> 2011-04-25 Jeff Law <law@redhat.com>
* gcc.dg/tree-ssa/vrp56.c: new test. * gcc.dg/tree-ssa/vrp56.c: new test.
......
// PR c++/48707
// { dg-options -std=c++0x }
struct A {
static int a();
};
template<typename X>
struct B: A {
static int const b;
};
template<typename X>
int const B<X>::b=B<X>::a();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment