[gcc(refs/vendors/ARM/heads/arm-struct-reorg-wip)] c++: ICE in value_dependent_expression_p in C++98 mode [PR94938]

Tamar Christina tnfchris@gcc.gnu.org
Fri Jul 17 14:58:48 GMT 2020


https://gcc.gnu.org/g:e5613c55c2900cd23c9e78592f10258e19c74ab3

commit e5613c55c2900cd23c9e78592f10258e19c74ab3
Author: Marek Polacek <polacek@redhat.com>
Date:   Thu May 7 14:34:15 2020 -0400

    c++: ICE in value_dependent_expression_p in C++98 mode [PR94938]
    
    Here we ICE with -std=c++98 since the newly added call to uses_template_parms
    (r10-6357): we hit
    26530             gcc_assert (cxx_dialect >= cxx11
    26531                         || INTEGRAL_OR_ENUMERATION_TYPE_P (type));
    and TYPE is a record type.  The problem is that the argument to
    value_dependent_expression_p does not satisfy potential_constant_expression
    which it must, as the comment explains.  I thought about fixing this in
    uses_template_parms -- only call v_d_e_p if p_c_e is true, but in this
    case we want to also suppress the warnings if we don't have a constant
    expression.  I couldn't simply check TREE_CONSTANT as in
    compute_array_index_type_loc, because then we'd stop warning in the new
    Wtype-limits3.C test.
    
    Fixed by using type_dependent_expression_p_push instead.  This means
    that we won't suppress the warnings for value-dependent expressions that
    aren't type-dependent, e.g. sizeof (T).  This only seems to make a
    difference for -Wdiv-by-zero, now tested in Wdiv-by-zero-3.C, where I
    think it's reasonable to warn.  It could make -Wtautological-compare
    warn more, but that warning doesn't trigger when it gets constant arguments.
    Wtype-limits4.C is a test reduced from poly-int.h and it tests a scenario
    that was missing in our testsuite.
    
    This patch also moves the warning_sentinels after the RECURs -- we mean
    to use them for build_x_binary_op purposes only.
    
            PR c++/94938
            * pt.c (tsubst_copy_and_build): Call type_dependent_expression_p_push
            instead of uses_template_parms.  Move the warning_sentinels after the
            RECURs.
    
            * g++.dg/warn/Wdiv-by-zero-3.C: New test.
            * g++.dg/warn/Wtype-limits4.C: New test.
            * g++.dg/warn/template-2.C: New test.
            * g++.old-deja/g++.pt/crash10.C: Add dg-warning.

Diff:
---
 gcc/cp/ChangeLog                            | 10 ++++++++++
 gcc/cp/pt.c                                 |  8 +++++---
 gcc/testsuite/g++.dg/warn/Wdiv-by-zero-3.C  | 17 +++++++++++++++++
 gcc/testsuite/g++.dg/warn/Wtype-limits4.C   | 23 +++++++++++++++++++++++
 gcc/testsuite/g++.dg/warn/template-2.C      | 22 ++++++++++++++++++++++
 gcc/testsuite/g++.old-deja/g++.pt/crash10.C |  1 +
 6 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b5201634053..4d0a69c1586 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2020-05-07  Marek Polacek  <polacek@redhat.com>
+	
+	Backported from mainline
+	2020-05-06  Marek Polacek  <polacek@redhat.com>
+
+	PR c++/94938
+	* pt.c (tsubst_copy_and_build): Call type_dependent_expression_p_push
+	instead of uses_template_parms.  Move the warning_sentinels after the
+	RECURs.
+
 2020-05-07  Jakub Jelinek  <jakub@redhat.com>
 
 	Backported from mainline
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d28585efd17..b8f03d18541 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -19408,14 +19408,16 @@ 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 = uses_template_parms (t);
+	bool was_dep = type_dependent_expression_p_push (t);
+
+	tree op0 = RECUR (TREE_OPERAND (t, 0));
+	tree op1 = RECUR (TREE_OPERAND (t, 1));
+
 	warning_sentinel s1(warn_type_limits, was_dep);
 	warning_sentinel s2(warn_div_by_zero, was_dep);
 	warning_sentinel s3(warn_logical_op, was_dep);
 	warning_sentinel s4(warn_tautological_compare, was_dep);
 
-	tree op0 = RECUR (TREE_OPERAND (t, 0));
-	tree op1 = RECUR (TREE_OPERAND (t, 1));
 	tree r = build_x_binary_op
 	  (input_location, TREE_CODE (t),
 	   op0,
diff --git a/gcc/testsuite/g++.dg/warn/Wdiv-by-zero-3.C b/gcc/testsuite/g++.dg/warn/Wdiv-by-zero-3.C
new file mode 100644
index 00000000000..424eb0c3d49
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wdiv-by-zero-3.C
@@ -0,0 +1,17 @@
+// PR c++/94938
+
+template <typename T, int N> int
+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" }
+  return m1 + m2 + m3 + m4;
+}
+
+void
+f ()
+{
+  foo<int, 0>(0, 0);
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wtype-limits4.C b/gcc/testsuite/g++.dg/warn/Wtype-limits4.C
new file mode 100644
index 00000000000..3ae44b4f25a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wtype-limits4.C
@@ -0,0 +1,23 @@
+// PR c++/94938
+// { dg-additional-options "-Wtype-limits" }
+
+template<unsigned N> struct B { unsigned arr[N]; };
+template<> struct B<1u> { int arr[10]; };
+
+template <unsigned N> bool
+foo(B<N> l)
+{
+  int i = 0;
+  return l.arr[i] < 0;
+}
+
+void
+j()
+{
+  B<1u> b;
+  foo (b);
+  B<2u> b2;
+  // I think that in this instantiation we could warn, but it breaks
+  // gcc bootstrap (marek 5/2020).
+  foo (b2);
+}
diff --git a/gcc/testsuite/g++.dg/warn/template-2.C b/gcc/testsuite/g++.dg/warn/template-2.C
new file mode 100644
index 00000000000..1d29528b2ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/template-2.C
@@ -0,0 +1,22 @@
+// PR c++/94938 - ICE in value_dependent_expression_p in C++98 mode.
+// { dg-do compile }
+
+template <typename> struct S { S(); S(bool); };
+
+struct C {
+  bool operator()(S<float>);
+};
+
+S<float> fn (bool);
+
+template<typename T> void
+foo (T)
+{
+  S<float> s;
+  S<float> x = fn(false || C()(s));
+}
+
+int main ()
+{
+  foo(int());
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash10.C b/gcc/testsuite/g++.old-deja/g++.pt/crash10.C
index a84b19004ee..012e3d0c11b 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/crash10.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash10.C
@@ -6,6 +6,7 @@ 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() {


More information about the Gcc-cvs mailing list