On Tue, Oct 27, 2020 at 01:36:30PM -0400, Jason Merrill wrote: > On 10/24/20 6:52 PM, Marek Polacek wrote: > > Here, in r11-155, I changed the call to uses_template_parms to > > type_dependent_expression_p_push to avoid a crash in C++98 in > > value_dependent_expression_p on a non-constant expression. But that > > prompted a host of complaints that we now warn for value-dependent > > expressions in templates. Those warnings are technically valid, but > > people still don't want them because they're awkward to avoid. So let's > > partially revert my earlier fix and make sure that we don't ICE in > > value_dependent_expression_p by checking potential_constant_expression > > first. > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/10? > > > > gcc/cp/ChangeLog: > > > > PR c++/96675 > > PR c++/96742 > > * pt.c (tsubst_copy_and_build): Call uses_template_parms instead of > > type_dependent_expression_p_push. Only call uses_template_parms > > for expressions that are potential_constant_expression. > > > > gcc/testsuite/ChangeLog: > > > > PR c++/96675 > > PR c++/96742 > > * g++.dg/warn/Wdiv-by-zero-3.C: Turn dg-warning into dg-bogus. > > * g++.dg/warn/Wtautological-compare3.C: New test. > > * g++.dg/warn/Wtype-limits5.C: New test. > > * g++.old-deja/g++.pt/crash10.C: Remove dg-warning. > > --- > > gcc/cp/pt.c | 6 ++++-- > > gcc/testsuite/g++.dg/warn/Wdiv-by-zero-3.C | 6 ++++-- > > gcc/testsuite/g++.dg/warn/Wtautological-compare3.C | 11 +++++++++++ > > gcc/testsuite/g++.dg/warn/Wtype-limits5.C | 11 +++++++++++ > > gcc/testsuite/g++.old-deja/g++.pt/crash10.C | 1 - > > 5 files changed, 30 insertions(+), 5 deletions(-) > > create mode 100644 gcc/testsuite/g++.dg/warn/Wtautological-compare3.C > > create mode 100644 gcc/testsuite/g++.dg/warn/Wtype-limits5.C > > > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > > index dc664ec3798..8aa0bc2c0d8 100644 > > --- a/gcc/cp/pt.c > > +++ b/gcc/cp/pt.c > > @@ -19618,8 +19618,10 @@ tsubst_copy_and_build (tree t, > > { > > /* If T was type-dependent, suppress warnings that depend on the range > > of the types involved. */ > > - bool was_dep = type_dependent_expression_p_push (t); > > - > > + ++processing_template_decl; > > + const bool was_dep = (!potential_constant_expression (t) > > + || uses_template_parms (t)); > > We don't want to suppress warnings for a non-constant expression that uses > no template parms. So maybe
Fair enough. > potential_c_e ? value_d : type_d That works for all the cases I have. > ? Or perhaps instantiation_dependent_expression_p. i_d_e_p would still crash in C++98 :(. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/10? -- >8 -- Here, in r11-155, I changed the call to uses_template_parms to type_dependent_expression_p_push to avoid a crash in C++98 in value_dependent_expression_p on a non-constant expression. But that prompted a host of complaints that we now warn for value-dependent expressions in templates. Those warnings are technically valid, but people still don't want them because they're awkward to avoid. This patch uses value_dependent_expression_p or type_dependent_expression_p. But make sure that we don't ICE in value_dependent_expression_p by checking potential_constant_expression first. gcc/cp/ChangeLog: PR c++/96675 PR c++/96742 * pt.c (tsubst_copy_and_build): Call value_dependent_expression_p or type_dependent_expression_p instead of type_dependent_expression_p_push. But only call value_dependent_expression_p for expressions that are potential_constant_expression. gcc/testsuite/ChangeLog: PR c++/96675 PR c++/96742 * g++.dg/warn/Wdiv-by-zero-3.C: Turn dg-warning into dg-bogus. * g++.dg/warn/Wtautological-compare3.C: New test. * g++.dg/warn/Wtype-limits5.C: New test. * g++.old-deja/g++.pt/crash10.C: Remove dg-warning. --- gcc/cp/pt.c | 7 +++++-- gcc/testsuite/g++.dg/warn/Wdiv-by-zero-3.C | 6 ++++-- gcc/testsuite/g++.dg/warn/Wtautological-compare3.C | 11 +++++++++++ gcc/testsuite/g++.dg/warn/Wtype-limits5.C | 11 +++++++++++ gcc/testsuite/g++.old-deja/g++.pt/crash10.C | 1 - 5 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wtautological-compare3.C create mode 100644 gcc/testsuite/g++.dg/warn/Wtype-limits5.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3c0f2546489..57db476645e 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -19618,8 +19618,11 @@ tsubst_copy_and_build (tree t, { /* If T was type-dependent, suppress warnings that depend on the range of the types involved. */ - bool was_dep = type_dependent_expression_p_push (t); - + ++processing_template_decl; + const bool was_dep = (potential_constant_expression (t) + ? value_dependent_expression_p (t) + : type_dependent_expression_p (t)); + --processing_template_decl; tree op0 = RECUR (TREE_OPERAND (t, 0)); tree op1 = RECUR (TREE_OPERAND (t, 1)); diff --git a/gcc/testsuite/g++.dg/warn/Wdiv-by-zero-3.C b/gcc/testsuite/g++.dg/warn/Wdiv-by-zero-3.C index 424eb0c3d49..01f691f2878 100644 --- a/gcc/testsuite/g++.dg/warn/Wdiv-by-zero-3.C +++ b/gcc/testsuite/g++.dg/warn/Wdiv-by-zero-3.C @@ -5,8 +5,10 @@ foo (T t, int i) { int m1 = 10 / t; int m2 = 10 / i; - int m3 = 10 / (sizeof(T) - sizeof(int)); // { dg-warning "division by" } - int m4 = 10 / N; // { dg-warning "division by" } + // People don't want to see warnings for type- or value-dependent + // expressions. + int m3 = 10 / (sizeof(T) - sizeof(int)); // { dg-bogus "division by" } + int m4 = 10 / N; // { dg-bogus "division by" } return m1 + m2 + m3 + m4; } diff --git a/gcc/testsuite/g++.dg/warn/Wtautological-compare3.C b/gcc/testsuite/g++.dg/warn/Wtautological-compare3.C new file mode 100644 index 00000000000..89bf1b619a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wtautological-compare3.C @@ -0,0 +1,11 @@ +// PR c++/96675 +// { dg-do compile { target c++11 } } +// { dg-additional-options "-Wtautological-compare" } + +template<char c> +constexpr bool f(char d) { + return 'a' <= c && c <= 'z' ? (d | 0x20) == c : + 'A' <= c && c <= 'Z' ? (d & ~0x20) == c : + d == c; +} +static_assert(f<'p'>('P'), ""); diff --git a/gcc/testsuite/g++.dg/warn/Wtype-limits5.C b/gcc/testsuite/g++.dg/warn/Wtype-limits5.C new file mode 100644 index 00000000000..5e79123b622 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wtype-limits5.C @@ -0,0 +1,11 @@ +// PR c++/96742 +// { dg-additional-options "-Wtype-limits" } + +template <unsigned N> +bool f(unsigned x) { + return unsigned(x < N); +} + +int main() { + f<0>(1); +} diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash10.C b/gcc/testsuite/g++.old-deja/g++.pt/crash10.C index 012e3d0c11b..a84b19004ee 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/crash10.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash10.C @@ -6,7 +6,6 @@ public: enum { val = (N == 0) ? M : GCD<N, M % N>::val }; // { dg-error "constant expression" "valid" { target *-*-* } .-1 } // { dg-message "template argument" "valid" { target *-*-* } .-2 } -// { dg-warning "division by" "" { target *-*-* } .-3 } }; int main() { base-commit: 176b8b9679dfec881b7cf379f808cca3950b1e74 -- 2.28.0