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.
(cherry picked from commit
976e7ef1a2d54f46021f74d071d9fdb9631298f8)
{
/* 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));
{
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;
}
--- /dev/null
+// 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'), "");
--- /dev/null
+// PR c++/96742
+// { dg-additional-options "-Wtype-limits" }
+
+template <unsigned N>
+bool f(unsigned x) {
+ return unsigned(x < N);
+}
+
+int main() {
+ f<0>(1);
+}
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() {