re PR c++/67012 (decltype(auto) with trailing return type)
authorMarek Polacek <polacek@redhat.com>
Fri, 24 Aug 2018 15:48:43 +0000 (15:48 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Fri, 24 Aug 2018 15:48:43 +0000 (15:48 +0000)
PR c++/67012
PR c++/86942
* decl.c (grokdeclarator): Disallow functions with trailing return
        type with decltype(auto) as its type.  Also check the function if
        it's inner declarator doesn't exist

* g++.dg/cpp0x/auto52.C: New test.
* g++.dg/cpp1y/auto-fn52.C: New test.
* g++.dg/cpp1y/auto-fn53.C: New test.
* g++.dg/cpp1y/auto-fn54.C: New test.

From-SVN: r263836

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/auto52.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/auto-fn52.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/auto-fn53.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/auto-fn54.C [new file with mode: 0644]

index 0fbd8167a047e1654055d252c620d971ba3eff59..ccb771b278556dcf6b88457a7555dc0fd78f6522 100644 (file)
@@ -1,3 +1,11 @@
+2018-08-24  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/67012
+       PR c++/86942
+       * decl.c (grokdeclarator): Disallow functions with trailing return
+       type with decltype(auto) as its type.  Also check the function if
+       it's inner declarator doesn't exist
+
 2018-08-21  Marek Polacek  <polacek@redhat.com>
 
        PR c++/86499
index 82ec4af87be9e87136d0a6bbcb9355f230a57d3b..9056ad0dbcebc364401c12b1b72b3f82a2ca54ec 100644 (file)
@@ -11246,7 +11246,10 @@ grokdeclarator (const cp_declarator *declarator,
 
            /* Handle a late-specified return type.  */
            tree late_return_type = declarator->u.function.late_return_type;
-           if (funcdecl_p)
+           if (funcdecl_p
+               /* This is the case e.g. for
+                  using T = auto () -> int.  */
+               || inner_declarator == NULL)
              {
                if (tree auto_node = type_uses_auto (type))
                  {
@@ -11278,6 +11281,16 @@ grokdeclarator (const cp_declarator *declarator,
                               name, type);
                        return error_mark_node;
                      }
+                   else if (is_auto (type) && AUTO_IS_DECLTYPE (type))
+                     {
+                       if (funcdecl_p)
+                         error ("%qs function with trailing return type has "
+                                "%<decltype(auto)%> as its type rather than "
+                                "plain %<auto%>", name);
+                       else
+                         error ("invalid use of %<decltype(auto)%>");
+                       return error_mark_node;
+                     }
                    tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node);
                    if (!tmpl)
                      if (tree late_auto = type_uses_auto (late_return_type))
index c6b61981c3dcccc433ac393890772131d0483689..eafd7ecd2926ea1b2b8d1ba9ffdc48fe44e90b14 100644 (file)
@@ -1,3 +1,12 @@
+2018-08-24  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/67012
+       PR c++/86942
+       * g++.dg/cpp0x/auto52.C: New test.
+       * g++.dg/cpp1y/auto-fn52.C: New test.
+       * g++.dg/cpp1y/auto-fn53.C: New test.
+       * g++.dg/cpp1y/auto-fn54.C: New test.
+
 2018-08-24  Richard Sandiford  <richard.sandiford@arm.com>
 
        * lib/target-supports.exp (vect_perm_supported): Only return
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto52.C b/gcc/testsuite/g++.dg/cpp0x/auto52.C
new file mode 100644 (file)
index 0000000..9bfe7c7
--- /dev/null
@@ -0,0 +1,6 @@
+// PR c++/86942
+// { dg-do compile { target c++11 } }
+
+using T = auto() -> int;
+using U = void() -> int; // { dg-error "function with trailing return type not declared with .auto." }
+using W = auto(); // { dg-error "invalid use of .auto." }
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn52.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn52.C
new file mode 100644 (file)
index 0000000..e239bc2
--- /dev/null
@@ -0,0 +1,4 @@
+// PR c++/67012
+// { dg-do compile { target c++14 } }
+
+decltype(auto) f() -> int; // { dg-error "function with trailing return type has" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn53.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn53.C
new file mode 100644 (file)
index 0000000..720aeeb
--- /dev/null
@@ -0,0 +1,4 @@
+// PR c++/86942
+// { dg-do compile { target c++14 } }
+
+using T = decltype(auto) () -> int; // { dg-error "invalid use of" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn54.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn54.C
new file mode 100644 (file)
index 0000000..f3391dd
--- /dev/null
@@ -0,0 +1,3 @@
+// { dg-do compile { target c++14 } }
+
+using T = int () -> decltype(auto); // { dg-error "function with trailing return type not declared with .auto." }