From 5d4e573b28a74218ea9db6b00f50f5e323899e6d Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Tue, 29 Aug 2017 15:51:30 -0400
Subject: [PATCH] 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.

From-SVN: r251429
---
 gcc/cp/ChangeLog                                |  9 +++++++++
 gcc/cp/constexpr.c                              |  5 ++---
 gcc/cp/decl.c                                   |  7 ++++---
 gcc/testsuite/g++.dg/cpp1z/constexpr-lambda16.C | 16 ++++++++++++++++
 4 files changed, 31 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-lambda16.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 08a8ac8c1b79..4d6df428efd4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2017-08-28  Jason Merrill  <jason@redhat.com>
+
+	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.
+
 2017-08-23  Jason Merrill  <jason@redhat.com>
 
 	* lambda.c (build_lambda_object): Check for error_mark_node.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index daeec9dedbcd..f3e868cff022 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 ff3127e4a604..23829b0f18e2 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 000000000000..ad5d885427cb
--- /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);
+}
-- 
GitLab