diff options
author | Joseph Myers <joseph@codesourcery.com> | 2016-05-13 22:35:39 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2016-05-13 22:35:39 +0100 |
commit | aa4b467b680f230ab11922d1e29695e1eaba12af (patch) | |
tree | 67890b5377876cd47fa3c7b49af6bf90643bad65 /gcc/c | |
parent | 653fb4a289f340c37c18432ae50971b0be7f5ed8 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 21 |
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; |