diff mbox series

C++ PATCH for c++/80935, wrong error on lambda in C++17 mode

Message ID CADzB+2n+GPkqp4u-6L0W1k4PH04N6o-eSTdaBmtm9GuAchAAkQ@mail.gmail.com
State New
Headers show
Series C++ PATCH for c++/80935, wrong error on lambda in C++17 mode | expand

Commit Message

Jason Merrill Aug. 29, 2017, 7:48 p.m. UTC
In this testcase, trying to treat a lambda op() as a constexpr
function led to an inappropriate error; we should instead just decide
that it isn't constexpr after all.

This patch also tweaks a couple of other places to use
is_instantiation_of_constexpr and var_in_maybe_constexpr_fn
appropriately.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 5eeca22016ed9ff34e83afb88e8195796096acae
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Aug 29 15:45:47 2017 -0400

            PR c++/80935 - wrong C++17 error with lambda
    
            * decl.c (check_for_uninitialized_const_var): Check
            is_instantiation_of_constexpr.
            * constexpr.c (ensure_literal_type_for_constexpr_object): Check
            is_instantiation_of_constexpr.
            (potential_constant_expression_1): Check var_in_maybe_constexpr_fn.
diff mbox series

Patch

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index daeec9d..f3e868c 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -100,7 +100,7 @@  ensure_literal_type_for_constexpr_object (tree decl)
 	    }
 	  else
 	    {
-	      if (!DECL_TEMPLATE_INSTANTIATION (current_function_decl))
+	      if (!is_instantiation_of_constexpr (current_function_decl))
 		{
 		  error ("variable %qD of non-literal type %qT in %<constexpr%> "
 			 "function", decl, type);
@@ -5335,8 +5335,7 @@  potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
         STRIP_NOPS (x);
         if (is_this_parameter (x) && !is_capture_proxy (x))
 	  {
-	    if (DECL_CONTEXT (x)
-		&& !DECL_DECLARED_CONSTEXPR_P (DECL_CONTEXT (x)))
+	    if (!var_in_maybe_constexpr_fn (x))
 	      {
 		if (flags & tf_error)
 		  error_at (loc, "use of %<this%> in a constant expression");
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index ff3127e..23829b0 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5525,9 +5525,10 @@  check_for_uninitialized_const_var (tree decl)
 		   "uninitialized const %qD", decl);
       else
 	{
-	  error_at (DECL_SOURCE_LOCATION (decl),
-		    "uninitialized variable %qD in %<constexpr%> function",
-		    decl);
+	  if (!is_instantiation_of_constexpr (current_function_decl))
+	    error_at (DECL_SOURCE_LOCATION (decl),
+		      "uninitialized variable %qD in %<constexpr%> function",
+		      decl);
 	  cp_function_chain->invalid_constexpr = true;
 	}
 
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda16.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda16.C
new file mode 100644
index 0000000..ad5d885
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda16.C
@@ -0,0 +1,16 @@ 
+// PR c++/80642
+// { dg-do compile { target c++14 } }
+
+int main()
+{
+  [](auto i)
+    {
+      if (i)
+        {
+	  int j;
+	  static int k;
+	  return i + j;
+        }
+      return i;
+    }(0);
+}