aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2016-05-13 22:35:39 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2016-05-13 22:35:39 +0100
commitaa4b467b680f230ab11922d1e29695e1eaba12af (patch)
tree67890b5377876cd47fa3c7b49af6bf90643bad65 /gcc/c
parent653fb4a289f340c37c18432ae50971b0be7f5ed8 (diff)
downloadgcc-aa4b467b680f230ab11922d1e29695e1eaba12af.zip
gcc-aa4b467b680f230ab11922d1e29695e1eaba12af.tar.gz
gcc-aa4b467b680f230ab11922d1e29695e1eaba12af.tar.bz2
Implement C11 DR#423 resolution (ignore function return type qualifiers).
The resolution of C11 DR#423, apart from doing things with the types of expressions cast to qualified types which are only in standard terms observable with _Generic and which agree with how GCC has implemented _Generic all along, also specifies that qualifiers are discarded from function return types: "derived-declarator-type-list function returning T" becomes "derived-declarator-type-list function returning the unqualified version of T" in the rules giving types for function declarators. This means that declarations of a function with both qualified and unqualified return types are now compatible, similar to how different declarations can vary in whether a function argument is declared with a qualifier or unqualified type. This patch implements this resolution. Since the motivation for the change was _Generic, the resolution is restricted to C11 mode; there's no reason to consider there to be a defect in this regard in older standard versions. Some less-obvious issues are handled as follows: * As usual, and as with function arguments, _Atomic is not considered a qualifier for this purpose; that is, function declarations must agree regarding whether the return type is atomic. * By 6.9.1#2, a function definition cannot return qualified void. But with this change, specifying "const void" in the declaration produces the type "function returning void", which is perfectly valid, so "const void f (void) {}" is no longer an error. * The application to restrict is less clear. The way I am interpreting it in this patch is that "unqualified version of T" is not valid if T is not valid, as in the case where T is a restrict-qualified version of a type that cannot be restrict qualified (non-pointer, or pointer-to-function). But it's possible to argue the other way from the wording. Bootstrapped with no regressions on x86_64-pc-linux-gnu. gcc/c: * c-decl.c (grokdeclarator): For C11, discard qualifiers on function return type. gcc/testsuite: * gcc.dg/qual-return-5.c, gcc.dg/qual-return-6.c: New tests. * gcc.dg/call-diag-2.c, gcc.dg/qual-return-2.c , gcc.dg/qual-return-3.c, gcc.dg/qual-return-4.c: Use -std=gnu99. From-SVN: r236231
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog5
-rw-r--r--gcc/c/c-decl.c21
2 files changed, 23 insertions, 3 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index af0bbe4..c726e9f 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,8 @@
+2016-05-13 Joseph Myers <joseph@codesourcery.com>
+
+ * c-decl.c (grokdeclarator): For C11, discard qualifiers on
+ function return type.
+
2016-05-12 Marek Polacek <polacek@redhat.com>
PR c/70756
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 1926034..b2dd644 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -6106,20 +6106,35 @@ grokdeclarator (const struct c_declarator *declarator,
qualify the return type, not the function type. */
if (type_quals)
{
+ int quals_used = type_quals;
/* Type qualifiers on a function return type are
normally permitted by the standard but have no
effect, so give a warning at -Wreturn-type.
Qualifiers on a void return type are banned on
function definitions in ISO C; GCC used to used
- them for noreturn functions. */
- if (VOID_TYPE_P (type) && really_funcdef)
+ them for noreturn functions. The resolution of C11
+ DR#423 means qualifiers (other than _Atomic) are
+ actually removed from the return type when
+ determining the function type. */
+ if (flag_isoc11)
+ quals_used &= TYPE_QUAL_ATOMIC;
+ if (quals_used && VOID_TYPE_P (type) && really_funcdef)
pedwarn (loc, 0,
"function definition has qualified void return type");
else
warning_at (loc, OPT_Wignored_qualifiers,
"type qualifiers ignored on function return type");
- type = c_build_qualified_type (type, type_quals);
+ /* Ensure an error for restrict on invalid types; the
+ DR#423 resolution is not entirely clear about
+ this. */
+ if (flag_isoc11
+ && (type_quals & TYPE_QUAL_RESTRICT)
+ && (!POINTER_TYPE_P (type)
+ || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
+ error_at (loc, "invalid use of %<restrict%>");
+ if (quals_used)
+ type = c_build_qualified_type (type, quals_used);
}
type_quals = TYPE_UNQUALIFIED;