Hi,

thus I had to revert my first try, when it caused c++/85713. I added two testcases for the latter (the second one covering what I learned from yet another defective try which I attached to the trail of c++/84588 yesterday) and finally figured out that the problem was that I was incorrectly calling abort_fully_implicit_template while tentatively parsing (if you look at the new lambda-generic-85713.C, that made impossible correctly parsing 'auto (&array) [5]' as second lambda parameter).

Anyway, a few days ago, while looking for a completely different solution and comparing to other compilers too, I noticed that, more generally, we were missing a check in cp_parser_condition that we aren't declaring a function type when we are sure that we are handling a declaration: simply adding such a check covers as a special case c++/84588 too, and, being the check in cp_parser_condition, it automatically covers variants for conditions elsewhere, eg, for, while loops: with the patchlet below we handle all of them very similarly to clang and icc.

Tested x86_64-linux.

Thanks, Paolo.

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

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

        PR c++/84588
        * parser.c (cp_parser_condition): Reject a declaration of
        a function type.

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

        PR c++/84588
        * g++.dg/cpp1y/pr84588.C: New.
        * g++.old-deja/g++.jason/cond.C: Adjust.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 260308)
+++ cp/parser.c (working copy)
@@ -11571,6 +11571,7 @@ cp_parser_condition (cp_parser* parser)
       tree attributes;
       cp_declarator *declarator;
       tree initializer = NULL_TREE;
+      location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
       /* Parse the declarator.  */
       declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
@@ -11597,15 +11598,23 @@ cp_parser_condition (cp_parser* parser)
         for sure.  */
       if (cp_parser_parse_definitely (parser))
        {
-         tree pushed_scope;
+         tree pushed_scope = NULL_TREE;
          bool non_constant_p;
          int flags = LOOKUP_ONLYCONVERTING;
 
          /* Create the declaration.  */
-         decl = start_decl (declarator, &type_specifiers,
-                            /*initialized_p=*/true,
-                            attributes, /*prefix_attributes=*/NULL_TREE,
-                            &pushed_scope);
+         if (declarator->kind == cdk_function)
+           {
+             error_at (loc, "a function type is not allowed here");
+             if (parser->fully_implicit_function_template_p)
+               abort_fully_implicit_template (parser);
+             decl = error_mark_node;
+           }
+         else
+           decl = start_decl (declarator, &type_specifiers,
+                              /*initialized_p=*/true,
+                              attributes, /*prefix_attributes=*/NULL_TREE,
+                              &pushed_scope);
 
          /* Parse the initializer.  */
          if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
Index: testsuite/g++.dg/cpp1y/pr84588.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr84588.C    (nonexistent)
+++ testsuite/g++.dg/cpp1y/pr84588.C    (working copy)
@@ -0,0 +1,25 @@
+// { dg-do compile { target c++14 } }
+
+struct a {
+  void b() {}
+  void c(void (*) () = [] {
+      if (a a(int auto) {})  // { dg-error "two or more data types|function 
type" }
+      ;
+  }) {}
+};
+
+struct d {
+  void e() {}
+  void f(void (*) () = [] {
+      for (;d d(int auto) {};)  // { dg-error "two or more data types|function 
type" }
+      ;
+  }) {}
+};
+
+struct g {
+  void h() {}
+  void i(void (*) () = [] {
+      while (g g(int auto) {})  // { dg-error "two or more data types|function 
type" }
+      ;
+  }) {}
+};
Index: testsuite/g++.old-deja/g++.jason/cond.C
===================================================================
--- testsuite/g++.old-deja/g++.jason/cond.C     (revision 260308)
+++ testsuite/g++.old-deja/g++.jason/cond.C     (working copy)
@@ -47,8 +47,7 @@ int main()
   if (struct B * foo = new B)
     ;
 
-  if (int f () = 1)            // { dg-warning "extern" "extern" } 
-  // { dg-error "is initialized like a variable" "var" { target *-*-* } .-1 }
+  if (int f () = 1)            // { dg-error "function type" } 
     ;
   
   if (int a[2] = {1, 2})       // { dg-error "extended init" "" { target { ! 
c++11 } } }

Reply via email to