c++: Prevent warnings for value-dependent exprs [PR96742]
authorMarek Polacek <polacek@redhat.com>
Sat, 24 Oct 2020 19:26:27 +0000 (15:26 -0400)
committerMarek Polacek <polacek@redhat.com>
Wed, 28 Oct 2020 21:26:45 +0000 (17:26 -0400)
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
gcc/testsuite/g++.dg/warn/Wdiv-by-zero-3.C
gcc/testsuite/g++.dg/warn/Wtautological-compare3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wtype-limits5.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/crash10.C

index fdeaa02c887e2b875bc77ee06c43dca160859223..b0344ac2506be6613825a518a78e57b629e07b58 100644 (file)
@@ -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));
 
index 424eb0c3d49d9e15839b13634f9f2d785cff3490..01f691f287803d8b6ee9ffd3b0e5992b27323763 100644 (file)
@@ -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 (file)
index 0000000..89bf1b6
--- /dev/null
@@ -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 (file)
index 0000000..5e79123
--- /dev/null
@@ -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);
+}
index 012e3d0c11b6e1985a54e8d687dbcec0e1c4ca7f..a84b19004eed4b82c02ce8869b10c131baaae0b5 100644 (file)
@@ -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() {