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 <ja...@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 --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);
+}

Reply via email to