diff mbox series

C++ PATCH for c++/82373, constexpr if and non-constant condition

Message ID CADzB+2nvoBUYyU2eVsMbfNU1vedee4to6ufscN99XAXennd0mQ@mail.gmail.com
State New
Headers show
Series C++ PATCH for c++/82373, constexpr if and non-constant condition | expand

Commit Message

Jason Merrill Dec. 4, 2017, 10:51 p.m. UTC
We need to require a constant-expression here, not just check for it.

The constexpr.c change was necessary to fix constexpr-lambda17.C.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 6ba5b86d80f9aea859b7d2b9bf7c517dadf3a701
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Dec 4 15:40:51 2017 -0500

            PR c++/83273 - constexpr if allows non-constant condition
    
            * semantics.c (finish_if_stmt_cond): Use require_constant_expression
            rather than is_constant_expression.
            * constexpr.c (potential_constant_expression_1) [LAMBDA_EXPR]: Allow
            in C++17.
diff mbox series

Patch

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index f0370cc2aff..6dfecfc1b14 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -5524,6 +5524,14 @@  potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
       return RECUR (STMT_EXPR_STMT (t), rval);
 
     case LAMBDA_EXPR:
+      if (cxx_dialect >= cxx17)
+	/* In C++17 lambdas can be constexpr, don't give up yet.  */
+	return true;
+      else if (flags & tf_error)
+	error_at (loc, "lambda-expression is not a constant expression "
+		  "before C++17");
+      return false;
+
     case DYNAMIC_CAST_EXPR:
     case PSEUDO_DTOR_EXPR:
     case NEW_EXPR:
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index e2daab4339e..c6726324ae6 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -731,7 +731,7 @@  finish_if_stmt_cond (tree cond, tree if_stmt)
 {
   cond = maybe_convert_cond (cond);
   if (IF_STMT_CONSTEXPR_P (if_stmt)
-      && is_constant_expression (cond)
+      && require_constant_expression (cond)
       && !value_dependent_expression_p (cond))
     {
       cond = instantiate_non_dependent_expr (cond);
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C
index 4e887f3b939..db984a64677 100644
--- a/gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C
@@ -7,7 +7,7 @@  struct T {
 
 template <class MustBeTemplate>
 constexpr auto bf(T t) {
-    if constexpr(t.foo()) {
+    if constexpr(t.foo()) {	// { dg-error "constant expression" }
         return false;
     }
     return true;
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if13.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if13.C
new file mode 100644
index 00000000000..55dbfd902ee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if13.C
@@ -0,0 +1,10 @@ 
+// PR c++/83273
+// { dg-options -std=c++17 }
+
+int main()
+{
+  auto d = 42;
+  if constexpr (d > 0) {	// { dg-error "constant expression" }
+      return d;
+  }
+}