Message ID | 20180313150701.GQ3522@redhat.com |
---|---|
State | New |
Headers | show |
Series | C++ PATCH to fix another ICE with stray template code (PR c++/84596) | expand |
On Tue, Mar 13, 2018 at 11:07 AM, Marek Polacek <polacek@redhat.com> wrote: > Here's another case of a template code leaking into cxx_constant_value. > While I recently added the require_rvalue_constant_expression check, it > doesn't help here, because the problem is that we have a MODOP_EXPR (a > template code), whose op1 is a TRUNC_DIV_EXPR without a type, so it's > considered dependent, so fold_non_dependent_expr doesn't do its job. If it's dependent, we should have taken the dependent path earlier in the function. Should that test use instantiation_dependent_expression_p rather than the existing type or value dependent check? Jason
On Tue, Mar 13, 2018 at 01:33:45PM -0400, Jason Merrill wrote: > On Tue, Mar 13, 2018 at 11:07 AM, Marek Polacek <polacek@redhat.com> wrote: > > Here's another case of a template code leaking into cxx_constant_value. > > While I recently added the require_rvalue_constant_expression check, it > > doesn't help here, because the problem is that we have a MODOP_EXPR (a > > template code), whose op1 is a TRUNC_DIV_EXPR without a type, so it's > > considered dependent, so fold_non_dependent_expr doesn't do its job. > > If it's dependent, we should have taken the dependent path earlier in > the function. Should that test use > instantiation_dependent_expression_p rather than the existing type or > value dependent check? I guess so. It fixes the ICE, though the error disappears unless we call a.b(). But that's probably expected. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2018-03-13 Marek Polacek <polacek@redhat.com> PR c++/84596 * semantics.c (finish_static_assert): Check instantiation_dependent_expression_p instead of {type,value}_dependent_expression_p. * g++.dg/cpp0x/static_assert15.C: New test. diff --git gcc/cp/semantics.c gcc/cp/semantics.c index bb8b5953539..fdf37bea770 100644 --- gcc/cp/semantics.c +++ gcc/cp/semantics.c @@ -8630,8 +8630,7 @@ finish_static_assert (tree condition, tree message, location_t location, if (check_for_bare_parameter_packs (condition)) condition = error_mark_node; - if (type_dependent_expression_p (condition) - || value_dependent_expression_p (condition)) + if (instantiation_dependent_expression_p (condition)) { /* We're in a template; build a STATIC_ASSERT and put it in the right place. */ diff --git gcc/testsuite/g++.dg/cpp0x/static_assert15.C gcc/testsuite/g++.dg/cpp0x/static_assert15.C index e69de29bb2d..a740f73fd4a 100644 --- gcc/testsuite/g++.dg/cpp0x/static_assert15.C +++ gcc/testsuite/g++.dg/cpp0x/static_assert15.C @@ -0,0 +1,10 @@ +// PR c++/84596 +// { dg-do compile { target c++11 } } + +template<int x> +struct a { + constexpr void b() { + int c; + static_assert(c %= 1, ""); + } +}; Marek
OK. On Tue, Mar 13, 2018 at 6:18 PM, Marek Polacek <polacek@redhat.com> wrote: > On Tue, Mar 13, 2018 at 01:33:45PM -0400, Jason Merrill wrote: >> On Tue, Mar 13, 2018 at 11:07 AM, Marek Polacek <polacek@redhat.com> wrote: >> > Here's another case of a template code leaking into cxx_constant_value. >> > While I recently added the require_rvalue_constant_expression check, it >> > doesn't help here, because the problem is that we have a MODOP_EXPR (a >> > template code), whose op1 is a TRUNC_DIV_EXPR without a type, so it's >> > considered dependent, so fold_non_dependent_expr doesn't do its job. >> >> If it's dependent, we should have taken the dependent path earlier in >> the function. Should that test use >> instantiation_dependent_expression_p rather than the existing type or >> value dependent check? > > I guess so. It fixes the ICE, though the error disappears unless we call > a.b(). But that's probably expected. > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > 2018-03-13 Marek Polacek <polacek@redhat.com> > > PR c++/84596 > * semantics.c (finish_static_assert): Check > instantiation_dependent_expression_p instead of > {type,value}_dependent_expression_p. > > * g++.dg/cpp0x/static_assert15.C: New test. > > diff --git gcc/cp/semantics.c gcc/cp/semantics.c > index bb8b5953539..fdf37bea770 100644 > --- gcc/cp/semantics.c > +++ gcc/cp/semantics.c > @@ -8630,8 +8630,7 @@ finish_static_assert (tree condition, tree message, location_t location, > if (check_for_bare_parameter_packs (condition)) > condition = error_mark_node; > > - if (type_dependent_expression_p (condition) > - || value_dependent_expression_p (condition)) > + if (instantiation_dependent_expression_p (condition)) > { > /* We're in a template; build a STATIC_ASSERT and put it in > the right place. */ > diff --git gcc/testsuite/g++.dg/cpp0x/static_assert15.C gcc/testsuite/g++.dg/cpp0x/static_assert15.C > index e69de29bb2d..a740f73fd4a 100644 > --- gcc/testsuite/g++.dg/cpp0x/static_assert15.C > +++ gcc/testsuite/g++.dg/cpp0x/static_assert15.C > @@ -0,0 +1,10 @@ > +// PR c++/84596 > +// { dg-do compile { target c++11 } } > + > +template<int x> > +struct a { > + constexpr void b() { > + int c; > + static_assert(c %= 1, ""); > + } > +}; > > Marek
diff --git gcc/cp/semantics.c gcc/cp/semantics.c index bb8b5953539..8680322a76c 100644 --- gcc/cp/semantics.c +++ gcc/cp/semantics.c @@ -8681,7 +8681,8 @@ finish_static_assert (tree condition, tree message, location_t location, else if (condition && condition != error_mark_node) { error ("non-constant condition for static assertion"); - if (require_rvalue_constant_expression (condition)) + if (!processing_template_decl + && require_rvalue_constant_expression (condition)) cxx_constant_value (condition); } input_location = saved_loc; diff --git gcc/testsuite/g++.dg/cpp0x/static_assert15.C gcc/testsuite/g++.dg/cpp0x/static_assert15.C index e69de29bb2d..dfb64ad5e1b 100644 --- gcc/testsuite/g++.dg/cpp0x/static_assert15.C +++ gcc/testsuite/g++.dg/cpp0x/static_assert15.C @@ -0,0 +1,10 @@ +// PR c++/84596 +// { dg-do compile { target c++11 } } + +template<int x> +struct a { + constexpr void b() { + int c; + static_assert(c %= 1, ""); // { dg-error "non-constant" } + } +};