* 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.
From-SVN: r177881
+2011-08-18 Joseph Myers <joseph@codesourcery.com>
+
+ * 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.
+
2011-08-18 Kirill Yukhin <kirill.yukhin@intel.com>
* common/config/i386/i386-common.c (OPTION_MASK_ISA_AVX2_SET): New.
$(srcdir)/ginclude/stddef.h \
$(srcdir)/ginclude/varargs.h \
$(srcdir)/ginclude/stdfix.h \
+ $(srcdir)/ginclude/stdnoreturn.h \
$(EXTRA_HEADERS)
USER_H_INC_NEXT_PRE = @user_headers_inc_next_pre@
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");
&& !specs->unsigned_p
&& !specs->complex_p
&& !specs->inline_p
+ && !specs->noreturn_p
&& !specs->thread_p);
return quals;
}
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)
{
/* 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,
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. */
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
{
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
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;
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)
+2011-08-18 Joseph Myers <joseph@codesourcery.com>
+
+ * c-common.c (c_common_reswords): Add _Noreturn.
+ (keyword_is_function_specifier): Handle RID_NORETURN.
+ * c-common.h (RID_NORETURN): New.
+
2011-08-10 Artjoms Sinkarovs <artyom.shinakroff@gmail.com>
* c-common.c (unsafe_conversion_p): New function. Check if it is
{ "_Accum", RID_ACCUM, D_CONLY | D_EXT },
{ "_Sat", RID_SAT, D_CONLY | D_EXT },
{ "_Static_assert", RID_STATIC_ASSERT, D_CONLY },
+ { "_Noreturn", RID_NORETURN, D_CONLY },
{ "__FUNCTION__", RID_FUNCTION_NAME, 0 },
{ "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
{ "__alignof", RID_ALIGNOF, 0 },
switch (keyword)
{
case RID_INLINE:
+ case RID_NORETURN:
case RID_VIRTUAL:
case RID_EXPLICIT:
return true;
/* Reserved identifiers. This is the union of all the keywords for C,
C++, and Objective-C. All the type modifiers have to be in one
block at the beginning, because they are used as mask bits. There
- are 27 type modifiers; if we add many more we will have to redesign
+ are 28 type modifiers; if we add many more we will have to redesign
the mask mechanism. */
enum rid
RID_UNSIGNED, RID_LONG, RID_CONST, RID_EXTERN,
RID_REGISTER, RID_TYPEDEF, RID_SHORT, RID_INLINE,
RID_VOLATILE, RID_SIGNED, RID_AUTO, RID_RESTRICT,
+ RID_NORETURN,
/* C extensions */
RID_COMPLEX, RID_THREAD, RID_SAT,
case RID_REGISTER:
case RID_TYPEDEF:
case RID_INLINE:
+ case RID_NORETURN:
case RID_AUTO:
case RID_THREAD:
case RID_UNSIGNED:
case RID_REGISTER:
case RID_TYPEDEF:
case RID_INLINE:
+ case RID_NORETURN:
case RID_AUTO:
case RID_THREAD:
if (!scspec_ok)
goto out;
attrs_ok = true;
- /* TODO: Distinguish between function specifiers (inline)
+ /* TODO: Distinguish between function specifiers (inline, noreturn)
and storage class specifiers, either here or in
declspecs_add_scspec. */
declspecs_add_scspec (specs, c_parser_peek_token (parser)->value);
case RID_TYPEDEF:
case RID_SHORT:
case RID_INLINE:
+ case RID_NORETURN:
case RID_VOLATILE:
case RID_SIGNED:
case RID_AUTO:
BOOL_BITFIELD complex_p : 1;
/* Whether "inline" was specified. */
BOOL_BITFIELD inline_p : 1;
+ /* Whether "_Noreturn" was speciied. */
+ BOOL_BITFIELD noreturn_p : 1;
/* Whether "__thread" was specified. */
BOOL_BITFIELD thread_p : 1;
/* Whether "const" was specified. */
--- /dev/null
+/* Copyright (C) 2011 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* ISO C1X: 7.23 _Noreturn <stdnoreturn.h>. */
+
+#ifndef _STDNORETURN_H
+#define _STDNORETURN_H
+
+#define noreturn _Noreturn
+
+#endif /* stdnoreturn.h */
+2011-08-18 Joseph Myers <joseph@codesourcery.com>
+
+ * 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.
+
2011-08-18 Joseph Myers <joseph@codesourcery.com>
* gcc.dg/c1x-uni-string-1.c, gcc.dg/c1x-uni-string-2.c: New tests.
--- /dev/null
+/* Test C1X _Noreturn. Test valid code. */
+/* { dg-do compile } */
+/* { dg-options "-std=c1x -pedantic-errors" } */
+
+_Noreturn void exit (int);
+
+_Noreturn int f1 (void);
+
+_Noreturn void f2 (void);
+
+static void _Noreturn f3 (void) { exit (0); }
+
+/* Returning from a noreturn function is undefined at runtime, not a
+ constraint violation, but recommended practice is to diagnose if
+ such a return appears possible. */
+
+_Noreturn int
+f4 (void)
+{
+ return 1; /* { dg-warning "has a 'return' statement" } */
+ /* { dg-warning "does return" "second warning" { target *-*-* } 20 } */
+}
+
+_Noreturn void
+f5 (void)
+{
+ return; /* { dg-warning "has a 'return' statement" } */
+ /* { dg-warning "does return" "second warning" { target *-*-* } 27 } */
+}
+
+_Noreturn void
+f6 (void)
+{
+} /* { dg-warning "does return" } */
+
+_Noreturn void
+f7 (int a)
+{
+ if (a)
+ exit (0);
+} /* { dg-warning "does return" } */
+
+/* Declarations need not all have _Noreturn. */
+
+void f2 (void);
+
+void f8 (void);
+_Noreturn void f8 (void);
+
+/* Duplicate _Noreturn is OK. */
+_Noreturn _Noreturn void _Noreturn f9 (void);
+
+/* _Noreturn does not affect type compatibility. */
+
+void (*fp) (void) = f5;
+
+/* noreturn is an ordinary identifier. */
+
+int noreturn;
--- /dev/null
+/* Test C1X _Noreturn. Test valid code using stdnoreturn.h. */
+/* { dg-do run } */
+/* { dg-options "-std=c1x -pedantic-errors" } */
+
+#include <stdnoreturn.h>
+
+extern int strcmp (const char *, const char *);
+
+noreturn void exit (int);
+noreturn void abort (void);
+
+noreturn int f1 (void);
+
+noreturn void f2 (void);
+
+static void noreturn f3 (void) { exit (0); }
+
+/* Returning from a noreturn function is undefined at runtime, not a
+ constraint violation, but recommended practice is to diagnose if
+ such a return appears possible. */
+
+noreturn int
+f4 (void)
+{
+ return 1; /* { dg-warning "has a 'return' statement" } */
+ /* { dg-warning "does return" "second warning" { target *-*-* } 25 } */
+}
+
+noreturn void
+f5 (void)
+{
+ return; /* { dg-warning "has a 'return' statement" } */
+ /* { dg-warning "does return" "second warning" { target *-*-* } 32 } */
+}
+
+noreturn void
+f6 (void)
+{
+} /* { dg-warning "does return" } */
+
+noreturn void
+f7 (int a)
+{
+ if (a)
+ exit (0);
+} /* { dg-warning "does return" } */
+
+/* Declarations need not all have noreturn. */
+
+void f2 (void);
+
+void f8 (void);
+noreturn void f8 (void);
+
+/* Duplicate noreturn is OK. */
+noreturn noreturn void noreturn f9 (void);
+
+/* noreturn does not affect type compatibility. */
+
+void (*fp) (void) = f5;
+
+#ifndef noreturn
+#error "noreturn not defined"
+#endif
+
+#define str(x) #x
+#define xstr(x) str(x)
+
+const char *s = xstr(noreturn);
+
+int
+main (void)
+{
+ if (strcmp (s, "_Noreturn") != 0)
+ abort ();
+ exit (0);
+}
--- /dev/null
+/* Test C1X _Noreturn. Test _Noreturn on main, hosted. */
+/* { dg-do compile } */
+/* { dg-options "-std=c1x -pedantic-errors -fhosted" } */
+
+_Noreturn void exit (int);
+
+_Noreturn int
+main (void) /* { dg-error "'main' declared '_Noreturn'" } */
+{
+ exit (0);
+}
--- /dev/null
+/* Test C1X _Noreturn. Test _Noreturn on main, freestanding. */
+/* { dg-do compile } */
+/* { dg-options "-std=c1x -pedantic-errors -ffreestanding" } */
+
+_Noreturn void exit (int);
+
+_Noreturn int
+main (void)
+{
+ exit (0);
+}
--- /dev/null
+/* Test C1X _Noreturn. Test invalid uses. */
+/* { dg-do compile } */
+/* { dg-options "-std=c1x -pedantic-errors" } */
+
+_Noreturn struct s; /* { dg-error "empty declaration" } */
+
+typedef _Noreturn void f (void); /* { dg-error "typedef" } */
+
+void g (_Noreturn void fp (void)); /* { dg-error "parameter" } */
+
+_Noreturn void (*p) (void); /* { dg-error "variable" } */
+
+struct t { int a; _Noreturn void (*f) (void); }; /* { dg-error "expected" } */
+
+int *_Noreturn *q; /* { dg-error "expected" } */
+
+int i = sizeof (_Noreturn int (*) (void)); /* { dg-error "expected" } */