c++: Avoid concept evaluation when uid-sensitive [PR94038]
authorPatrick Palka <ppalka@redhat.com>
Sat, 23 May 2020 18:39:28 +0000 (14:39 -0400)
committerPatrick Palka <ppalka@redhat.com>
Sat, 23 May 2020 18:39:28 +0000 (14:39 -0400)
Concept evaluation may entail DECL_UID generation and/or template
instantiation, so in general we can't perform it during uid-sensitive
constexpr evaluation.

gcc/cp/ChangeLog:

PR c++/94038
* constexpr.c (cxx_eval_constant_expression)
<case TEMPLATE_ID_EXPR>: Don't evaluate the concept when
constexpr evaluation is uid-sensitive.

gcc/testsuite/ChangeLog:

PR c++/94038
* g++.dg/warn/pr94038-3.C: New test.

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/pr94038-3.C [new file with mode: 0644]

index 385bfcd..2feeb12 100644 (file)
@@ -1,3 +1,10 @@
+2020-05-23  Patrick Palka  <ppalka@redhat.com>
+
+       PR c++/94038
+       * constexpr.c (cxx_eval_constant_expression)
+       <case TEMPLATE_ID_EXPR>: Don't evaluate the concept when
+       constexpr evaluation is uid-sensitive.
+
 2020-05-21  Patrick Palka  <ppalka@redhat.com>
 
        PR c++/94038
index 98c974e..4e441ac 100644 (file)
@@ -6486,7 +6486,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
            break;
          }
 
-       if (!processing_template_decl)
+       if (!processing_template_decl
+           && !uid_sensitive_constexpr_evaluation_p ())
          r = evaluate_concept_check (t, tf_warning_or_error);
        else
          *non_constant_p = true;
index 9711a27..80fd33d 100644 (file)
@@ -1,3 +1,8 @@
+2020-05-23  Patrick Palka  <ppalka@redhat.com>
+
+       PR c++/94038
+       * g++.dg/warn/pr94038-3.C: New test.
+
 2020-05-22  Mark Wielaard  <mark@klomp.org>
 
        * gcc.dg/spellcheck-stdint.c: New test.
diff --git a/gcc/testsuite/g++.dg/warn/pr94038-3.C b/gcc/testsuite/g++.dg/warn/pr94038-3.C
new file mode 100644 (file)
index 0000000..49b6d13
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/94038
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-Wall" }
+
+template<typename T>
+constexpr int foo() {
+  return T::x;
+}
+
+constexpr bool bar(bool a) { return a; }
+
+template<typename T>
+concept C = foo<T>() == 0;
+
+static_assert(decltype(bar(C<int>)){} == false);