diff mbox

[C++] PR 65775 ("Late-specified return type bypasses return type checks (qualified, function, array)")

Message ID 1a012c96-26ab-3fb3-ba01-5d93c508d28d@oracle.com
State New
Headers show

Commit Message

Paolo Carlini June 26, 2017, 12:18 a.m. UTC
... in fact, simply moving the checks forward, past the 
splice_late_return_type call, appears to work fine. I'm finishing 
testing the below.

Thanks!
Paolo.

/////////////////////
/cp
2017-06-25  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/65775
	* decl.c (grokdeclarator): Move checks on function return type after
	the splice_late_return_type call; if declspecs->locations[ds_type_spec]
	is UNKNOWN_LOCATION fall back to input_location.

/testsuite
2017-06-25  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/65775
	* g++.dg/cpp0x/trailing14.C: New.

Comments

Jason Merrill June 30, 2017, 10:49 p.m. UTC | #1
OK.

On Sun, Jun 25, 2017 at 8:18 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> ... in fact, simply moving the checks forward, past the
> splice_late_return_type call, appears to work fine. I'm finishing testing
> the below.
>
> Thanks!
> Paolo.
>
> /////////////////////
diff mbox

Patch

Index: testsuite/g++.dg/cpp0x/trailing14.C
===================================================================
--- testsuite/g++.dg/cpp0x/trailing14.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/trailing14.C	(working copy)
@@ -0,0 +1,15 @@ 
+// PR c++/65775
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wignored-qualifiers" }
+
+using Qi = int const volatile;
+Qi q1();           // { dg-warning "1: type qualifiers ignored" }
+auto q2() -> Qi;   // { dg-warning "1: type qualifiers ignored" }
+
+using Fi = int();
+Fi f1();           // { dg-error "1: 'f1' declared as function returning a function" }
+auto f2() -> Fi;   // { dg-error "1: 'f2' declared as function returning a function" }
+
+using Ai = int[5];
+Ai a1();           // { dg-error "1: 'a1' declared as function returning an array" }
+auto a2() -> Ai;   // { dg-error "1: 'a2' declared as function returning an array" }
Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 249632)
+++ cp/decl.c	(working copy)
@@ -9993,6 +9993,8 @@  grokdeclarator (const cp_declarator *declarator,
 						      declspecs->locations);
   if (typespec_loc == UNKNOWN_LOCATION)
     typespec_loc = declspecs->locations[ds_type_spec];
+  if (typespec_loc == UNKNOWN_LOCATION)
+    typespec_loc = input_location;
 
   /* Look inside a declarator for the name being declared
      and get it as a string, for an error message.  */
@@ -10825,34 +10827,8 @@  grokdeclarator (const cp_declarator *declarator,
 	    tree arg_types;
 	    int funcdecl_p;
 
-	    /* Declaring a function type.
-	       Make sure we have a valid type for the function to return.  */
+	    /* Declaring a function type.  */
 
-	    if (type_quals != TYPE_UNQUALIFIED)
-	      {
-		if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type))
-		  {
-		    warning_at (typespec_loc, OPT_Wignored_qualifiers, "type "
-				"qualifiers ignored on function return type");
-		  }
-		/* We now know that the TYPE_QUALS don't apply to the
-		   decl, but to its return type.  */
-		type_quals = TYPE_UNQUALIFIED;
-	      }
-
-	    /* Error about some types functions can't return.  */
-
-	    if (TREE_CODE (type) == FUNCTION_TYPE)
-	      {
-		error ("%qs declared as function returning a function", name);
-		return error_mark_node;
-	      }
-	    if (TREE_CODE (type) == ARRAY_TYPE)
-	      {
-		error ("%qs declared as function returning an array", name);
-		return error_mark_node;
-	      }
-
 	    input_location = declspecs->locations[ds_type_spec];
 	    abstract_virtuals_error (ACU_RETURN, type);
 	    input_location = saved_loc;
@@ -10959,8 +10935,36 @@  grokdeclarator (const cp_declarator *declarator,
 	      return error_mark_node;
 
 	    if (late_return_type)
-	      late_return_type_p = true;
+	      {
+		late_return_type_p = true;
+		type_quals = cp_type_quals (type);
+	      }
 
+	    if (type_quals != TYPE_UNQUALIFIED)
+	      {
+		if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type))
+		  warning_at (typespec_loc, OPT_Wignored_qualifiers, "type "
+			      "qualifiers ignored on function return type");
+		/* We now know that the TYPE_QUALS don't apply to the
+		   decl, but to its return type.  */
+		type_quals = TYPE_UNQUALIFIED;
+	      }
+
+	    /* Error about some types functions can't return.  */
+
+	    if (TREE_CODE (type) == FUNCTION_TYPE)
+	      {
+		error_at (typespec_loc, "%qs declared as function returning "
+			  "a function", name);
+		return error_mark_node;
+	      }
+	    if (TREE_CODE (type) == ARRAY_TYPE)
+	      {
+		error_at (typespec_loc, "%qs declared as function returning "
+			  "an array", name);
+		return error_mark_node;
+	      }
+
 	    if (ctype == NULL_TREE
 		&& decl_context == FIELD
 		&& funcdecl_p