Commit df061a43 by Roger Sayle Committed by Roger Sayle

re PR c++/7099 (G++ doesn't set the noreturn attribute on std::exit and std::abort)


	PR c++/7099
	* builtin-attrs.def: Define new attribute lists for use in
	builtins.def.
	* builtins.def [DEF_BUILTIN]: Modify to take an additional
	ATTRS argument, an enumerated value defined in builtin-attrs.def
	that represents the attribute list for the builtins.  Modify
	all builtin functions to pass an appropriate attribute list.
	Specify "abort", "exit", "_exit" and "_Exit" builtins here with
	their required noreturn attributes.
	* tree.h (enum_builtin_function): Ignore the additional parameter
	to DEF_BUILTIN.
	* builtins.c (built_in_names): Likewise.
	* c-common.c: (builtin_function_2): Replace the "int noreturn_p"
	argument with a tree representing the functions attribute list.
	Pass this "attrs" argument to builtin_function.  No longer handle
	the noreturn_p processing manually.
	(built_in_attributes): Move the definitions from builtin-attrs.def
	before c_common_nodes_and_builtins.
	(c_common_nodes_and_builtins): Handle the new ATTRS parameter in
	DEF_BUILTIN, passing it to both builtin_function and the changed
	builtin_function_2.

	* doc/extend.texi: Document __builtin_abort, __builtin_exit,
	__builtin__exit and __builtin__Exit.

	* java/builtins.c (initialize_builtins): Ignore the additional
	parameter to DEF_BUILTIN.  Handle more C/C++ specific junk in
	the builtins.def file.

From-SVN: r55276
parent e5eb8de8
2002-07-05 Roger Sayle <roger@eyesopen.com>
PR c++/7099
* builtin-attrs.def: Define new attribute lists for use in
builtins.def.
* builtins.def [DEF_BUILTIN]: Modify to take an additional
ATTRS argument, an enumerated value defined in builtin-attrs.def
that represents the attribute list for the builtins. Modify
all builtin functions to pass an appropriate attribute list.
Specify "abort", "exit", "_exit" and "_Exit" builtins here with
their required noreturn attributes.
* tree.h (enum_builtin_function): Ignore the additional parameter
to DEF_BUILTIN.
* builtins.c (built_in_names): Likewise.
* c-common.c: (builtin_function_2): Replace the "int noreturn_p"
argument with a tree representing the functions attribute list.
Pass this "attrs" argument to builtin_function. No longer handle
the noreturn_p processing manually.
(built_in_attributes): Move the definitions from builtin-attrs.def
before c_common_nodes_and_builtins.
(c_common_nodes_and_builtins): Handle the new ATTRS parameter in
DEF_BUILTIN, passing it to both builtin_function and the changed
builtin_function_2.
* doc/extend.texi: Document __builtin_abort, __builtin_exit,
__builtin__exit and __builtin__Exit.
2002-07-05 Stephane Carrez <stcarrez@nerim.fr> 2002-07-05 Stephane Carrez <stcarrez@nerim.fr>
* config/m68hc11/m68hc11.md ("*movqi_68hc12"): Avoid allocating * config/m68hc11/m68hc11.md ("*movqi_68hc12"): Avoid allocating
......
...@@ -77,15 +77,30 @@ DEF_LIST_INT_INT (3,0) ...@@ -77,15 +77,30 @@ DEF_LIST_INT_INT (3,0)
DEF_LIST_INT_INT (3,4) DEF_LIST_INT_INT (3,4)
#undef DEF_LIST_INT_INT #undef DEF_LIST_INT_INT
/* Construct tress for identifiers. */
DEF_ATTR_IDENT (ATTR_CONST, "const")
DEF_ATTR_IDENT (ATTR_FORMAT, "format")
DEF_ATTR_IDENT (ATTR_FORMAT_ARG, "format_arg")
DEF_ATTR_IDENT (ATTR_MALLOC, "malloc")
DEF_ATTR_IDENT (ATTR_NONNULL, "nonnull")
DEF_ATTR_IDENT (ATTR_NORETURN, "noreturn")
DEF_ATTR_IDENT (ATTR_NOTHROW, "nothrow")
DEF_ATTR_IDENT (ATTR_PRINTF, "printf") DEF_ATTR_IDENT (ATTR_PRINTF, "printf")
DEF_ATTR_IDENT (ATTR_PURE, "pure")
DEF_ATTR_IDENT (ATTR_SCANF, "scanf") DEF_ATTR_IDENT (ATTR_SCANF, "scanf")
DEF_ATTR_IDENT (ATTR_STRFTIME, "strftime")
DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon") DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon")
DEF_ATTR_IDENT (ATTR_STRFTIME, "strftime")
DEF_ATTR_IDENT (ATTR_FORMAT, "format") DEF_ATTR_TREE_LIST (ATTR_NOTHROW_LIST, ATTR_NOTHROW, ATTR_NULL, ATTR_NULL)
DEF_ATTR_IDENT (ATTR_FORMAT_ARG, "format_arg")
DEF_ATTR_IDENT (ATTR_NONNULL, "nonnull") DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_LIST, ATTR_CONST, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_LIST, ATTR_PURE, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LIST, ATTR_NORETURN, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_LIST, ATTR_MALLOC, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, ATTR_NULL) DEF_ATTR_TREE_LIST (ATTR_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, ATTR_NULL)
DEF_ATTR_TREE_LIST (ATTR_NONNULL_2, ATTR_NONNULL, ATTR_LIST_2, ATTR_NULL) DEF_ATTR_TREE_LIST (ATTR_NONNULL_2, ATTR_NONNULL, ATTR_LIST_2, ATTR_NULL)
...@@ -132,17 +147,8 @@ DEF_FORMAT_ARG_ATTRIBUTE(2) ...@@ -132,17 +147,8 @@ DEF_FORMAT_ARG_ATTRIBUTE(2)
-ffreestanding, these default attributes are disabled, and must be -ffreestanding, these default attributes are disabled, and must be
specified manually if desired. */ specified manually if desired. */
/* __builtin functions should be checked unconditionally, even with
-ffreestanding. */
DEF_FN_ATTR_IDENT (__builtin_printf, ATTR_FORMAT_PRINTF_1_2, true)
DEF_FN_ATTR_IDENT (__builtin_fprintf, ATTR_FORMAT_PRINTF_2_3, true)
DEF_FN_ATTR_IDENT (__builtin_printf_unlocked, ATTR_FORMAT_PRINTF_1_2, true)
DEF_FN_ATTR_IDENT (__builtin_fprintf_unlocked, ATTR_FORMAT_PRINTF_2_3, true)
/* Functions from ISO/IEC 9899:1990. */ /* Functions from ISO/IEC 9899:1990. */
#define DEF_C89_ATTR(NAME, ATTRS) DEF_FN_ATTR_IDENT (NAME, ATTRS, flag_hosted) #define DEF_C89_ATTR(NAME, ATTRS) DEF_FN_ATTR_IDENT (NAME, ATTRS, flag_hosted)
DEF_C89_ATTR (printf, ATTR_FORMAT_PRINTF_1_2)
DEF_C89_ATTR (fprintf, ATTR_FORMAT_PRINTF_2_3)
DEF_C89_ATTR (sprintf, ATTR_FORMAT_PRINTF_2_3) DEF_C89_ATTR (sprintf, ATTR_FORMAT_PRINTF_2_3)
DEF_C89_ATTR (scanf, ATTR_FORMAT_SCANF_1_2) DEF_C89_ATTR (scanf, ATTR_FORMAT_SCANF_1_2)
DEF_C89_ATTR (fscanf, ATTR_FORMAT_SCANF_2_3) DEF_C89_ATTR (fscanf, ATTR_FORMAT_SCANF_2_3)
...@@ -175,8 +181,5 @@ DEF_EXT_ATTR (dgettext, ATTR_FORMAT_ARG_2) ...@@ -175,8 +181,5 @@ DEF_EXT_ATTR (dgettext, ATTR_FORMAT_ARG_2)
DEF_EXT_ATTR (dcgettext, ATTR_FORMAT_ARG_2) DEF_EXT_ATTR (dcgettext, ATTR_FORMAT_ARG_2)
/* X/Open strfmon function. */ /* X/Open strfmon function. */
DEF_EXT_ATTR (strfmon, ATTR_FORMAT_STRFMON_3_4) DEF_EXT_ATTR (strfmon, ATTR_FORMAT_STRFMON_3_4)
/* Glibc thread-unsafe stdio functions. */
DEF_EXT_ATTR (printf_unlocked, ATTR_FORMAT_PRINTF_1_2)
DEF_EXT_ATTR (fprintf_unlocked, ATTR_FORMAT_PRINTF_2_3)
#undef DEF_EXT_ATTR #undef DEF_EXT_ATTR
#undef DEF_FN_ATTR_IDENT #undef DEF_FN_ATTR_IDENT
...@@ -63,7 +63,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -63,7 +63,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
const char *const built_in_class_names[4] const char *const built_in_class_names[4]
= {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"}; = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA) STRINGX(X), #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT) STRINGX(X),
const char *const built_in_names[(int) END_BUILTINS] = const char *const built_in_names[(int) END_BUILTINS] =
{ {
#include "builtins.def" #include "builtins.def"
......
...@@ -2456,7 +2456,7 @@ c_common_truthvalue_conversion (expr) ...@@ -2456,7 +2456,7 @@ c_common_truthvalue_conversion (expr)
static tree builtin_function_2 PARAMS ((const char *, const char *, tree, tree, static tree builtin_function_2 PARAMS ((const char *, const char *, tree, tree,
int, enum built_in_class, int, int, int, enum built_in_class, int, int,
int)); tree));
/* Make a variant type in the proper way for C/C++, propagating qualifiers /* Make a variant type in the proper way for C/C++, propagating qualifiers
down to the element type of an array. */ down to the element type of an array. */
...@@ -2681,6 +2681,30 @@ c_alignof_expr (expr) ...@@ -2681,6 +2681,30 @@ c_alignof_expr (expr)
return fold (build1 (NOP_EXPR, c_size_type_node, t)); return fold (build1 (NOP_EXPR, c_size_type_node, t));
} }
/* Handle C and C++ default attributes. */
enum built_in_attribute
{
#define DEF_ATTR_NULL_TREE(ENUM) ENUM,
#define DEF_ATTR_INT(ENUM, VALUE) ENUM,
#define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
#define DEF_FN_ATTR(NAME, ATTRS, PREDICATE) /* No entry needed in enum. */
#include "builtin-attrs.def"
#undef DEF_ATTR_NULL_TREE
#undef DEF_ATTR_INT
#undef DEF_ATTR_IDENT
#undef DEF_ATTR_TREE_LIST
#undef DEF_FN_ATTR
ATTR_LAST
};
static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
static bool c_attrs_initialized = false;
static void c_init_attributes PARAMS ((void));
/* Build tree nodes and builtin functions common to both C and C++ language /* Build tree nodes and builtin functions common to both C and C++ language
frontends. */ frontends. */
...@@ -3041,8 +3065,11 @@ c_common_nodes_and_builtins () ...@@ -3041,8 +3065,11 @@ c_common_nodes_and_builtins ()
#undef DEF_FUNCTION_TYPE_VAR_1 #undef DEF_FUNCTION_TYPE_VAR_1
#undef DEF_POINTER_TYPE #undef DEF_POINTER_TYPE
#define DEF_BUILTIN(ENUM, NAME, CLASS, \ if (!c_attrs_initialized)
TYPE, LIBTYPE, BOTH_P, FALLBACK_P, NONANSI_P) \ c_init_attributes ();
#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, \
BOTH_P, FALLBACK_P, NONANSI_P, ATTRS) \
if (NAME) \ if (NAME) \
{ \ { \
tree decl; \ tree decl; \
...@@ -3055,7 +3082,8 @@ c_common_nodes_and_builtins () ...@@ -3055,7 +3082,8 @@ c_common_nodes_and_builtins ()
CLASS, \ CLASS, \
(FALLBACK_P \ (FALLBACK_P \
? (NAME + strlen ("__builtin_")) \ ? (NAME + strlen ("__builtin_")) \
: NULL), NULL_TREE); \ : NULL), \
built_in_attributes[(int) ATTRS]); \
else \ else \
decl = builtin_function_2 (NAME, \ decl = builtin_function_2 (NAME, \
NAME + strlen ("__builtin_"), \ NAME + strlen ("__builtin_"), \
...@@ -3065,35 +3093,13 @@ c_common_nodes_and_builtins () ...@@ -3065,35 +3093,13 @@ c_common_nodes_and_builtins ()
CLASS, \ CLASS, \
FALLBACK_P, \ FALLBACK_P, \
NONANSI_P, \ NONANSI_P, \
/*noreturn_p=*/0); \ built_in_attributes[(int) ATTRS]); \
\ \
built_in_decls[(int) ENUM] = decl; \ built_in_decls[(int) ENUM] = decl; \
} }
#include "builtins.def" #include "builtins.def"
#undef DEF_BUILTIN #undef DEF_BUILTIN
/* Declare _exit and _Exit just to mark them as non-returning. */
builtin_function_2 (NULL, "_exit", NULL_TREE,
builtin_types[BT_FN_VOID_INT],
0, NOT_BUILT_IN, 0, 1, 1);
builtin_function_2 (NULL, "_Exit", NULL_TREE,
builtin_types[BT_FN_VOID_INT],
0, NOT_BUILT_IN, 0, !flag_isoc99, 1);
/* Declare these functions non-returning
to avoid spurious "control drops through" warnings. */
builtin_function_2 (NULL, "abort",
NULL_TREE, ((c_language == clk_cplusplus)
? builtin_types[BT_FN_VOID]
: builtin_types[BT_FN_VOID_VAR]),
0, NOT_BUILT_IN, 0, 0, 1);
builtin_function_2 (NULL, "exit",
NULL_TREE, ((c_language == clk_cplusplus)
? builtin_types[BT_FN_VOID_INT]
: builtin_types[BT_FN_VOID_VAR]),
0, NOT_BUILT_IN, 0, 0, 1);
main_identifier_node = get_identifier ("main"); main_identifier_node = get_identifier ("main");
} }
...@@ -3161,15 +3167,15 @@ builtin_function_disabled_p (name) ...@@ -3161,15 +3167,15 @@ builtin_function_disabled_p (name)
conflicts with headers. FUNCTION_CODE and CLASS are as for conflicts with headers. FUNCTION_CODE and CLASS are as for
builtin_function. If LIBRARY_NAME_P is nonzero, NAME is passed as builtin_function. If LIBRARY_NAME_P is nonzero, NAME is passed as
the LIBRARY_NAME parameter to builtin_function when declaring BUILTIN_NAME. the LIBRARY_NAME parameter to builtin_function when declaring BUILTIN_NAME.
If NONANSI_P is nonzero, the name NAME is treated as a non-ANSI name; if If NONANSI_P is nonzero, the name NAME is treated as a non-ANSI name;
NORETURN_P is nonzero, the function is marked as non-returning. ATTRS is the tree list representing the builtin's function attributes.
Returns the declaration of BUILTIN_NAME, if any, otherwise Returns the declaration of BUILTIN_NAME, if any, otherwise
the declaration of NAME. Does not declare NAME if flag_no_builtin, the declaration of NAME. Does not declare NAME if flag_no_builtin,
or if NONANSI_P and flag_no_nonansi_builtin. */ or if NONANSI_P and flag_no_nonansi_builtin. */
static tree static tree
builtin_function_2 (builtin_name, name, builtin_type, type, function_code, builtin_function_2 (builtin_name, name, builtin_type, type, function_code,
class, library_name_p, nonansi_p, noreturn_p) class, library_name_p, nonansi_p, attrs)
const char *builtin_name; const char *builtin_name;
const char *name; const char *name;
tree builtin_type; tree builtin_type;
...@@ -3178,7 +3184,7 @@ builtin_function_2 (builtin_name, name, builtin_type, type, function_code, ...@@ -3178,7 +3184,7 @@ builtin_function_2 (builtin_name, name, builtin_type, type, function_code,
enum built_in_class class; enum built_in_class class;
int library_name_p; int library_name_p;
int nonansi_p; int nonansi_p;
int noreturn_p; tree attrs;
{ {
tree bdecl = NULL_TREE; tree bdecl = NULL_TREE;
tree decl = NULL_TREE; tree decl = NULL_TREE;
...@@ -3186,25 +3192,15 @@ builtin_function_2 (builtin_name, name, builtin_type, type, function_code, ...@@ -3186,25 +3192,15 @@ builtin_function_2 (builtin_name, name, builtin_type, type, function_code,
{ {
bdecl = builtin_function (builtin_name, builtin_type, function_code, bdecl = builtin_function (builtin_name, builtin_type, function_code,
class, library_name_p ? name : NULL, class, library_name_p ? name : NULL,
NULL_TREE); attrs);
if (noreturn_p)
{
TREE_THIS_VOLATILE (bdecl) = 1;
TREE_SIDE_EFFECTS (bdecl) = 1;
}
} }
if (name != 0 && !flag_no_builtin && !builtin_function_disabled_p (name) if (name != 0 && !flag_no_builtin && !builtin_function_disabled_p (name)
&& !(nonansi_p && flag_no_nonansi_builtin)) && !(nonansi_p && flag_no_nonansi_builtin))
{ {
decl = builtin_function (name, type, function_code, class, NULL, decl = builtin_function (name, type, function_code, class, NULL,
NULL_TREE); attrs);
if (nonansi_p) if (nonansi_p)
DECL_BUILT_IN_NONANSI (decl) = 1; DECL_BUILT_IN_NONANSI (decl) = 1;
if (noreturn_p)
{
TREE_THIS_VOLATILE (decl) = 1;
TREE_SIDE_EFFECTS (decl) = 1;
}
} }
return (bdecl != 0 ? bdecl : decl); return (bdecl != 0 ? bdecl : decl);
} }
...@@ -4232,30 +4228,6 @@ boolean_increment (code, arg) ...@@ -4232,30 +4228,6 @@ boolean_increment (code, arg)
return val; return val;
} }
/* Handle C and C++ default attributes. */
enum built_in_attribute
{
#define DEF_ATTR_NULL_TREE(ENUM) ENUM,
#define DEF_ATTR_INT(ENUM, VALUE) ENUM,
#define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
#define DEF_FN_ATTR(NAME, ATTRS, PREDICATE) /* No entry needed in enum. */
#include "builtin-attrs.def"
#undef DEF_ATTR_NULL_TREE
#undef DEF_ATTR_INT
#undef DEF_ATTR_IDENT
#undef DEF_ATTR_TREE_LIST
#undef DEF_FN_ATTR
ATTR_LAST
};
static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
static bool c_attrs_initialized = false;
static void c_init_attributes PARAMS ((void));
/* Common initialization before parsing options. */ /* Common initialization before parsing options. */
void void
c_common_init_options (lang) c_common_init_options (lang)
......
...@@ -4519,7 +4519,9 @@ The functions @code{abort}, @code{exit}, @code{_Exit} and @code{_exit} ...@@ -4519,7 +4519,9 @@ The functions @code{abort}, @code{exit}, @code{_Exit} and @code{_exit}
are recognized and presumed not to return, but otherwise are not built are recognized and presumed not to return, but otherwise are not built
in. @code{_exit} is not recognized in strict ISO C mode (@option{-ansi}, in. @code{_exit} is not recognized in strict ISO C mode (@option{-ansi},
@option{-std=c89} or @option{-std=c99}). @code{_Exit} is not recognized in @option{-std=c89} or @option{-std=c99}). @code{_Exit} is not recognized in
strict C89 mode (@option{-ansi} or @option{-std=c89}). strict C89 mode (@option{-ansi} or @option{-std=c89}). All these functions
have corresponding versions prefixed with @code{__builtin_}, which may be
used even in strict C89 mode.
Outside strict ISO C mode, the functions @code{alloca}, @code{bcmp}, Outside strict ISO C mode, the functions @code{alloca}, @code{bcmp},
@code{bzero}, @code{index}, @code{rindex}, @code{ffs}, @code{fputs_unlocked}, @code{bzero}, @code{index}, @code{rindex}, @code{ffs}, @code{fputs_unlocked},
......
2002-07-05 Roger Sayle <roger@eyesopen.com>
* java/builtins.c (initialize_builtins): Ignore the additional
parameter to DEF_BUILTIN. Handle more C/C++ specific junk in
the builtins.def file.
2002-07-01 Tom Tromey <tromey@redhat.com> 2002-07-01 Tom Tromey <tromey@redhat.com>
For PR libgcj/7073: For PR libgcj/7073:
......
...@@ -284,6 +284,8 @@ initialize_builtins () ...@@ -284,6 +284,8 @@ initialize_builtins ()
#define va_list_ref_type_node NULL_TREE #define va_list_ref_type_node NULL_TREE
#define va_list_arg_type_node NULL_TREE #define va_list_arg_type_node NULL_TREE
#define flag_isoc99 0 #define flag_isoc99 0
#define c_language 0
#define clk_cplusplus 0
#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \ #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
builtin_types[(int) ENUM] = VALUE; builtin_types[(int) ENUM] = VALUE;
...@@ -314,7 +316,7 @@ initialize_builtins () ...@@ -314,7 +316,7 @@ initialize_builtins ()
#include "builtin-types.def" #include "builtin-types.def"
#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, \ #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, \
FALLBACK_P, NONANSI_P) \ FALLBACK_P, NONANSI_P, ATTRS) \
define_builtin (ENUM, NAME, CLASS, builtin_types[TYPE], FALLBACK_P); define_builtin (ENUM, NAME, CLASS, builtin_types[TYPE], FALLBACK_P);
#include "builtins.def" #include "builtins.def"
} }
......
...@@ -80,7 +80,7 @@ extern const char *const built_in_class_names[4]; ...@@ -80,7 +80,7 @@ extern const char *const built_in_class_names[4];
/* Codes that identify the various built in functions /* Codes that identify the various built in functions
so that expand_call can identify them quickly. */ so that expand_call can identify them quickly. */
#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA) ENUM, #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT) ENUM,
enum built_in_function enum built_in_function
{ {
#include "builtins.def" #include "builtins.def"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment