re PR c++/65775 (Late-specified return type bypasses return type checks (qualified...
authorPaolo Carlini <paolo.carlini@oracle.com>
Mon, 3 Jul 2017 18:10:52 +0000 (18:10 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 3 Jul 2017 18:10:52 +0000 (18:10 +0000)
/cp
2017-07-03  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-07-03  Paolo Carlini  <paolo.carlini@oracle.com>

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

From-SVN: r249935

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/trailing14.C [new file with mode: 0644]

index 47548775e0af7ccbe1315bc3ef28137f678b571f..189edcb097588bb024770c76fc67ff7f69df67b7 100644 (file)
@@ -1,3 +1,10 @@
+2017-07-03  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.
+
 2017-07-03  David Malcolm  <dmalcolm@redhat.com>
 
        * parser.c (enum required_token): Fix spelling of
index 62877dc2851450a98a8a03a1842683bbe6ca88dd..d5b758a89ee87ab9a0a89bfa9d3a130a1d30c4c0 100644 (file)
@@ -9992,6 +9992,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.  */
@@ -10822,33 +10824,7 @@ 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.  */
-
-           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;
-             }
+           /* Declaring a function type.  */
 
            input_location = declspecs->locations[ds_type_spec];
            abstract_virtuals_error (ACU_RETURN, type);
@@ -10956,7 +10932,35 @@ 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
index 681783fa50c8441125e10d81be492fcbb7a24556..03f935754643ea67f30383a841b854bbdb21eb92 100644 (file)
@@ -1,3 +1,8 @@
+2017-07-03  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/65775
+       * g++.dg/cpp0x/trailing14.C: New.
+
 2017-07-03  Dominique d'Humieres  <dominiq@lps.ens.fr>
 
        PR testsuite/79866
diff --git a/gcc/testsuite/g++.dg/cpp0x/trailing14.C b/gcc/testsuite/g++.dg/cpp0x/trailing14.C
new file mode 100644 (file)
index 0000000..2544d0b
--- /dev/null
@@ -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" }