Hi,

a rather simple ice on invalid (not sure why only P4 given that no meaningful diagnostic is emitted before ICEing). What happens is that the ill-formed capture naming b, an OVERLOAD, escapes the early check in cp_parser_lambda_introducer to eventually trigger a recently added gcc_assert in build_capture_proxy. Adjusting the check means we also provide slightly clearer (IMO, matching clang, anyway) error messages for two testcases we already have.

Tested x86_64-linux.

Thanks, Paolo.

///////////////////////////////////////

/cp
2018-03-05  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/84618
        * parser.c (cp_parser_lambda_introducer): Reject any capture not
        involving a VAR_DECL or a PARM_DECL.

/testsuite
2018-03-05  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/84618
        * g++.dg/cpp0x/lambda/lambda-ice29.C: New.
        * g++.dg/cpp0x/lambda/lambda-ice17.C: Adjust.
        * g++.dg/cpp0x/lambda/lambda-ice23.C: Likewise.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 258235)
+++ cp/parser.c (working copy)
@@ -10377,15 +10377,15 @@ cp_parser_lambda_introducer (cp_parser* parser, tr
              unqualified_name_lookup_error (capture_id);
              continue;
            }
-         else if (DECL_P (capture_init_expr)
-                  && (!VAR_P (capture_init_expr)
-                      && TREE_CODE (capture_init_expr) != PARM_DECL))
+         else if (!VAR_P (capture_init_expr)
+                  && TREE_CODE (capture_init_expr) != PARM_DECL)
            {
              error_at (capture_token->location,
-                       "capture of non-variable %qD ",
+                       "capture of non-variable %qE ",
                        capture_init_expr);
-             inform (DECL_SOURCE_LOCATION (capture_init_expr),
-                     "%q#D declared here", capture_init_expr);
+             if (DECL_P (capture_init_expr))
+               inform (DECL_SOURCE_LOCATION (capture_init_expr),
+                       "%q#D declared here", capture_init_expr);
              continue;
            }
          if (VAR_P (capture_init_expr)
Index: testsuite/g++.dg/cpp0x/lambda/lambda-ice17.C
===================================================================
--- testsuite/g++.dg/cpp0x/lambda/lambda-ice17.C        (revision 258235)
+++ testsuite/g++.dg/cpp0x/lambda/lambda-ice17.C        (working copy)
@@ -5,7 +5,7 @@ void foo (int);
 
 void foo (void)
 {
-  [&foo] // { dg-error "cannot capture" }
+  [&foo] // { dg-error "5:capture of non-variable" }
   {
     foo (0);
   };
Index: testsuite/g++.dg/cpp0x/lambda/lambda-ice23.C
===================================================================
--- testsuite/g++.dg/cpp0x/lambda/lambda-ice23.C        (revision 258235)
+++ testsuite/g++.dg/cpp0x/lambda/lambda-ice23.C        (working copy)
@@ -3,7 +3,7 @@
 
 template <typename T>
 constexpr int r(T x) {
-  auto f = [r,x]() { return r(x); }; // { dg-error "incomplete type" }
+  auto f = [r,x]() { return r(x); }; // { dg-error "13:capture of 
non-variable" }
   return 0;
 }
 
Index: testsuite/g++.dg/cpp0x/lambda/lambda-ice29.C
===================================================================
--- testsuite/g++.dg/cpp0x/lambda/lambda-ice29.C        (nonexistent)
+++ testsuite/g++.dg/cpp0x/lambda/lambda-ice29.C        (working copy)
@@ -0,0 +1,8 @@
+// PR c++/84618
+// { dg-do compile { target c++11 } }
+
+template <int>
+struct S {
+  void b() const;
+  void b() { [b] {}; } // { dg-error "15:capture of non-variable" }
+};

Reply via email to