From 976e7ef1a2d54f46021f74d071d9fdb9631298f8 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Sat, 24 Oct 2020 15:26:27 -0400 Subject: [PATCH] c++: Prevent warnings for value-dependent exprs [PR96742] 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 fdeaa02c887..b0344ac2506 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -19616,8 +19616,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 +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 +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::val }; // { dg-error "constant expression" "valid" { target *-*-* } .-1 } // { dg-message "template argument" "valid" { target *-*-* } .-2 } -// { dg-warning "division by" "" { target *-*-* } .-3 } }; int main() { -- 2.30.2