Message ID | 4F10750E.2070606@oracle.com |
---|---|
State | New |
Headers | show |
On 01/13/2012 01:16 PM, Paolo Carlini wrote: > in C++11 mode after erroring out for an undeclared name we can easily > end up calling cxx_eval_constant_expression on a CAST_EXPR etc, which > has error_mark_node as argument. We should never pass uninstantiated trees to cxx_eval_constant_expression; they need to go through tsubst first. Jason
Hi, > On 01/13/2012 01:16 PM, Paolo Carlini wrote: >> in C++11 mode after erroring out for an undeclared name we can easily >> end up calling cxx_eval_constant_expression on a CAST_EXPR etc, which >> has error_mark_node as argument. > > We should never pass uninstantiated trees to > cxx_eval_constant_expression; they need to go through tsubst first. Actually, I'm pretty sure you explained that already in the past, and I have more generally a deja-vu... Anyway, the reason we are not tsubst-ing such trees - eg, a CAST_EXPR on a single element TREE_LIST as argument, with error_mark_node as value - is that potential_constant_expression is false in fold_non_dependent_expr_sfinae, thus tsubst_copy_and_build is not called at all. The reason why potential_constant_expression is false is that recursion leads to the argument as a TREE_LIST and then the next call to the error_mark_node itself, which eventually leads to false. Back to my deja-vu feeling, I'm pretty sure that a few weeks ago I experimented with changing potential_constant_expression to actually return *true* for error_mark_node, and that worked for a similar problem. But maybe my few lines of analysis already inspire you something? Thanks, Paolo.
On 01/13/2012 03:57 PM, Paolo Carlini wrote: > Anyway, the reason we are not tsubst-ing such trees - eg, a CAST_EXPR on > a single element TREE_LIST as argument, with error_mark_node as value - > is that potential_constant_expression is false in > fold_non_dependent_expr_sfinae, thus tsubst_copy_and_build is not called > at all. We also shouldn't call cxx_eval_constant_expression if potential_constant_expression is false. Jason
Index: testsuite/g++.dg/cpp0x/pr51225.C =================================================================== --- testsuite/g++.dg/cpp0x/pr51225.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr51225.C (revision 0) @@ -0,0 +1,14 @@ +// PR c++/51225 +// { dg-options "-std=c++0x" } + +template<int> struct A {}; + +template<typename> void foo() +{ + A<int(x)> a; // { dg-error "not declared|invalid type" } +} + +template<typename> struct bar +{ + static constexpr A<1> a = A<1>(x); // { dg-error "not declared" } +}; Index: cp/semantics.c =================================================================== --- cp/semantics.c (revision 183153) +++ cp/semantics.c (working copy) @@ -7769,6 +7769,15 @@ cxx_eval_constant_expression (const constexpr_call used, and they can't do anything with it, so just return it. */ return t; + case CAST_EXPR: + case CONST_CAST_EXPR: + case STATIC_CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case IMPLICIT_CONV_EXPR: + gcc_assert (errorcount); + *non_constant_p = true; + return t; + case LAMBDA_EXPR: case PREINCREMENT_EXPR: case POSTINCREMENT_EXPR: