]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Prevent bogus -Wtype-limits warning with NTTP [PR100161]
authorMarek Polacek <polacek@redhat.com>
Wed, 21 Apr 2021 00:24:09 +0000 (20:24 -0400)
committerMarek Polacek <polacek@redhat.com>
Tue, 27 Apr 2021 16:41:34 +0000 (12:41 -0400)
Recently, we made sure that we never call value_dependent_expression_p
on an expression that isn't potential_constant_expression.  That caused
this bogus warning with a non-type template parameter, something that
users don't want to see.

The problem is that in tsubst_copy_and_build/LE_EXPR 't' is "i < n",
which, due to 'i', is not p_c_e, therefore we call t_d_e_p.  But the
type of 'n' isn't dependent, so we think the whole 't' expression is
not dependent.  It seems we need to test both op0 and op1 separately
to suppress this warning.

gcc/cp/ChangeLog:

PR c++/100161
* pt.c (tsubst_copy_and_build) <case PLUS_EXPR>: Test op0 and
op1 separately for value- or type-dependence.

gcc/testsuite/ChangeLog:

PR c++/100161
* g++.dg/warn/Wtype-limits6.C: New test.

(cherry picked from commit 244dfb95119106e9267f37583caac565c39eb0ec)

gcc/cp/pt.c
gcc/testsuite/g++.dg/warn/Wtype-limits6.C [new file with mode: 0644]

index 19fdafa4c43c8232bedd5beb9a717c9bdb166a86..ada2b63efb92b5a40ca2877d9c9a91826ec1aec3 100644 (file)
@@ -19900,15 +19900,21 @@ tsubst_copy_and_build (tree t,
     case MEMBER_REF:
     case DOTSTAR_EXPR:
       {
-       /* If T was type-dependent, suppress warnings that depend on the range
-          of the types involved.  */
-       ++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));
+       /* If either OP0 or OP1 was value- or type-dependent, suppress
+          warnings that depend on the range of the types involved.  */
+       tree op0 = TREE_OPERAND (t, 0);
+       tree op1 = TREE_OPERAND (t, 1);
+       auto dep_p = [](tree t) {
+         ++processing_template_decl;
+         bool r = (potential_constant_expression (t)
+                   ? value_dependent_expression_p (t)
+                   : type_dependent_expression_p (t));
+         --processing_template_decl;
+         return r;
+       };
+       const bool was_dep = dep_p (op0) || dep_p (op1);
+       op0 = RECUR (op0);
+       op1 = RECUR (op1);
 
        warning_sentinel s1(warn_type_limits, was_dep);
        warning_sentinel s2(warn_div_by_zero, was_dep);
diff --git a/gcc/testsuite/g++.dg/warn/Wtype-limits6.C b/gcc/testsuite/g++.dg/warn/Wtype-limits6.C
new file mode 100644 (file)
index 0000000..9d5886d
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/100161
+// { dg-additional-options "-Wtype-limits" }
+
+void f(unsigned);
+
+template<unsigned n>
+void g()
+{
+    for (unsigned i = 0; i < n; i++) { // { dg-bogus "always false" }
+        f(i);
+    }
+}
+
+void h()
+{
+    g<0>();
+}