Commit e5613c55 by Marek Polacek

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.
parent 9a993849
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
......
......@@ -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,
......
// 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);
}
// 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);
}
// 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());
}
......@@ -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() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment