aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2017-07-03 18:10:52 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2017-07-03 18:10:52 +0000
commit17c18221012ac66ae53cd40b85d96320e3f8884e (patch)
tree3d72335ffc4e9f62cf1b92499864e7cb3b306c11
parent370d975d77562e4f38738cfb7bcb16afa9aeabfb (diff)
downloadgcc-17c18221012ac66ae53cd40b85d96320e3f8884e.zip
gcc-17c18221012ac66ae53cd40b85d96320e3f8884e.tar.gz
gcc-17c18221012ac66ae53cd40b85d96320e3f8884e.tar.bz2
re PR c++/65775 (Late-specified return type bypasses return type checks (qualified, function, array))
/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
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c60
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/trailing14.C15
4 files changed, 59 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4754877..189edcb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 62877dc..d5b758a 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 681783f..03f9357 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..2544d0b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/trailing14.C
@@ -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" }