This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/67012, c++/86942, detect invalid cases with function return type deduction


As I promised in <https://gcc.gnu.org/ml/gcc-patches/2018-08/msg00908.html>,
this patch fixes a couple of invalid cases we weren't detecting.  It's got
testcases from two PRs and another case I found out; they're intertwined so
I think it makes sense to fix them in one go.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-08-16  Marek Polacek  <polacek@redhat.com>

	PR c++/86942
	PR c++/67012
	* 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.

diff --git gcc/cp/decl.c gcc/cp/decl.c
index fa58bc4d2b3..8261f8e30e5 100644
--- gcc/cp/decl.c
+++ gcc/cp/decl.c
@@ -11238,7 +11238,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))
 		  {
@@ -11270,6 +11273,18 @@ grokdeclarator (const cp_declarator *declarator,
 			       name, type);
 			return error_mark_node;
 		      }
+		    else if (is_auto (type)
+			     && (TYPE_IDENTIFIER (type)
+				 == decltype_auto_identifier))
+		      {
+			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))
diff --git gcc/testsuite/g++.dg/cpp0x/auto52.C gcc/testsuite/g++.dg/cpp0x/auto52.C
index e69de29bb2d..9bfe7c754b5 100644
--- gcc/testsuite/g++.dg/cpp0x/auto52.C
+++ gcc/testsuite/g++.dg/cpp0x/auto52.C
@@ -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 gcc/testsuite/g++.dg/cpp1y/auto-fn52.C gcc/testsuite/g++.dg/cpp1y/auto-fn52.C
index e69de29bb2d..e239bc27dc2 100644
--- gcc/testsuite/g++.dg/cpp1y/auto-fn52.C
+++ gcc/testsuite/g++.dg/cpp1y/auto-fn52.C
@@ -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 gcc/testsuite/g++.dg/cpp1y/auto-fn53.C gcc/testsuite/g++.dg/cpp1y/auto-fn53.C
index e69de29bb2d..720aeeb215d 100644
--- gcc/testsuite/g++.dg/cpp1y/auto-fn53.C
+++ gcc/testsuite/g++.dg/cpp1y/auto-fn53.C
@@ -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 gcc/testsuite/g++.dg/cpp1y/auto-fn54.C gcc/testsuite/g++.dg/cpp1y/auto-fn54.C
index e69de29bb2d..f3391ddfd75 100644
--- gcc/testsuite/g++.dg/cpp1y/auto-fn54.C
+++ gcc/testsuite/g++.dg/cpp1y/auto-fn54.C
@@ -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." }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]