diff options
author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-18 21:35:42 +0000 |
---|---|---|
committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-18 21:35:42 +0000 |
commit | 985c6e3a7f5ac7ed72400d90fa5529c9370f61aa (patch) | |
tree | 7cac89ed01db35f3172a81cb7429efeb4d9798e7 /gcc/c-decl.c | |
parent | 985e7f1028ffb3c6e18d66e9c9ae8d0baaa3f74b (diff) | |
download | gcc-985c6e3a7f5ac7ed72400d90fa5529c9370f61aa.tar.gz |
* c-decl.c (shadow_tag_warned): Check for _Noreturn.
(quals_from_declspecs): Assert _Noreturn not present.
(grokdeclarator): Handle _Noreturn.
(build_null_declspecs): Initialize noreturn_p.
(declspecs_add_scspec): Handle RID_NORETURN.
* c-parser.c (c_token_starts_declspecs, c_parser_declspecs)
(c_parser_attributes): Handle RID_NORETURN.
* c-tree.h (struct c_declspecs): Add noreturn_p.
* ginclude/stdnoreturn.h: New.
* Makefile.in (USER_H): Add stdnoreturn.h.
c-family:
* c-common.c (c_common_reswords): Add _Noreturn.
(keyword_is_function_specifier): Handle RID_NORETURN.
* c-common.h (RID_NORETURN): New.
testsuite:
* gcc.dg/c1x-noreturn-1.c, gcc.dg/c1x-noreturn-2.c,
gcc.dg/c1x-noreturn-3.c, gcc.dg/c1x-noreturn-4.c,
gcc.dg/c1x-noreturn-5.c: New tests.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@177881 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 927beb0a33d..d824e12b5bb 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -3714,6 +3714,12 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) warned = 1; } + if (declspecs->noreturn_p) + { + error ("%<_Noreturn%> in empty declaration"); + warned = 1; + } + if (current_scope == file_scope && declspecs->storage_class == csc_auto) { error ("%<auto%> in file-scope empty declaration"); @@ -3780,6 +3786,7 @@ quals_from_declspecs (const struct c_declspecs *specs) && !specs->unsigned_p && !specs->complex_p && !specs->inline_p + && !specs->noreturn_p && !specs->thread_p); return quals; } @@ -5734,6 +5741,8 @@ grokdeclarator (const struct c_declarator *declarator, C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; if (declspecs->inline_p) pedwarn (loc, 0,"typedef %q+D declared %<inline%>", decl); + if (declspecs->noreturn_p) + pedwarn (loc, 0,"typedef %q+D declared %<_Noreturn%>", decl); if (warn_cxx_compat && declarator->u.id != NULL_TREE) { @@ -5765,7 +5774,7 @@ grokdeclarator (const struct c_declarator *declarator, /* Note that the grammar rejects storage classes in typenames and fields. */ gcc_assert (storage_class == csc_none && !threadp - && !declspecs->inline_p); + && !declspecs->inline_p && !declspecs->noreturn_p); if (pedantic && TREE_CODE (type) == FUNCTION_TYPE && type_quals) pedwarn (loc, OPT_pedantic, @@ -5862,13 +5871,15 @@ grokdeclarator (const struct c_declarator *declarator, DECL_ARG_TYPE (decl) = promoted_type; if (declspecs->inline_p) pedwarn (loc, 0, "parameter %q+D declared %<inline%>", decl); + if (declspecs->noreturn_p) + pedwarn (loc, 0, "parameter %q+D declared %<_Noreturn%>", decl); } else if (decl_context == FIELD) { /* Note that the grammar rejects storage classes in typenames and fields. */ gcc_assert (storage_class == csc_none && !threadp - && !declspecs->inline_p); + && !declspecs->inline_p && !declspecs->noreturn_p); /* Structure field. It may not be a function. */ @@ -5960,15 +5971,23 @@ grokdeclarator (const struct c_declarator *declarator, if (declspecs->default_int_p) C_FUNCTION_IMPLICIT_INT (decl) = 1; - /* Record presence of `inline', if it is reasonable. */ + /* Record presence of `inline' and `_Noreturn', if it is + reasonable. */ if (flag_hosted && MAIN_NAME_P (declarator->u.id)) { if (declspecs->inline_p) pedwarn (loc, 0, "cannot inline function %<main%>"); + if (declspecs->noreturn_p) + pedwarn (loc, 0, "%<main%> declared %<_Noreturn%>"); + } + else + { + if (declspecs->inline_p) + /* Record that the function is declared `inline'. */ + DECL_DECLARED_INLINE_P (decl) = 1; + if (declspecs->noreturn_p) + TREE_THIS_VOLATILE (decl) = 1; } - else if (declspecs->inline_p) - /* Record that the function is declared `inline'. */ - DECL_DECLARED_INLINE_P (decl) = 1; } else { @@ -6004,6 +6023,8 @@ grokdeclarator (const struct c_declarator *declarator, if (declspecs->inline_p) pedwarn (loc, 0, "variable %q+D declared %<inline%>", decl); + if (declspecs->noreturn_p) + pedwarn (loc, 0, "variable %q+D declared %<_Noreturn%>", decl); /* At file scope, an initialized extern declaration may follow a static declaration. In that case, DECL_EXTERNAL will be @@ -8646,6 +8667,7 @@ build_null_declspecs (void) ret->unsigned_p = false; ret->complex_p = false; ret->inline_p = false; + ret->noreturn_p = false; ret->thread_p = false; ret->const_p = false; ret->volatile_p = false; @@ -9367,6 +9389,11 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec) dupe = false; specs->inline_p = true; break; + case RID_NORETURN: + /* Duplicate _Noreturn is permitted. */ + dupe = false; + specs->noreturn_p = true; + break; case RID_THREAD: dupe = specs->thread_p; if (specs->storage_class == csc_auto) |