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

Reply via email to