On 5/4/20 7:32 PM, Marek Polacek wrote:
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.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/10?

        PR c++/94938
        * pt.c (tsubst_copy_and_build): Don't call value_dependent_expression_p
        if the expression is not potential_constant_expression.

        * g++.dg/warn/template-2.C: New test.
---
  gcc/cp/pt.c                            |  5 ++++-
  gcc/testsuite/g++.dg/warn/template-2.C | 22 ++++++++++++++++++++++
  2 files changed, 26 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/warn/template-2.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 61cb75bf801..691f6e4df36 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -19423,7 +19423,10 @@ 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);
+       ++processing_template_decl;
+       bool was_dep = (!potential_constant_expression (t)
+                       || value_dependent_expression_p (t));
+       --processing_template_decl;

Hmm, it seems weird to condition the warning on whether or not the expression is constant.

Do we want type_dependent_expression_p or instantiation_dependent_expression_p here?

I also wonder if we want to move the warning_sentinels after the RECURs.

        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);
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());
+}

base-commit: 5e681acd3587285cc3c8c6d603e4ce93cf6dacf2


Reply via email to