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
This commit is contained in:
parent
4d583bb9fc
commit
d95f258e90
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
13
gcc/cp/pt.c
13
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. */
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
2011-04-25 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/cpp0x/regress/template-const2.C: New.
|
||||
|
||||
2011-04-25 Jeff Law <law@redhat.com>
|
||||
|
||||
* gcc.dg/tree-ssa/vrp56.c: new test.
|
||||
|
14
gcc/testsuite/g++.dg/cpp0x/regress/template-const2.C
Normal file
14
gcc/testsuite/g++.dg/cpp0x/regress/template-const2.C
Normal file
@ -0,0 +1,14 @@
|
||||
// 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();
|
Loading…
Reference in New Issue
Block a user