diff options
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/c-common.c | 22 | ||||
-rw-r--r-- | gcc/c-common.h | 11 | ||||
-rw-r--r-- | gcc/c-opts.c | 4 | ||||
-rw-r--r-- | gcc/c.opt | 4 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/lex.c | 5 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/sentinel.C | 11 |
11 files changed, 85 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f0e58f4153d..8efc9dc7c9b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2005-05-02 Michael Matz <matz@suse.de> + + PR c++/19542 + * c-common.c (c_common_nodes_and_builtins): Create global null_node. + (warn_strict_null_sentinel): Define. + (check_function_sentinel): Check for null_node as valid sentinel too. + * c-common.h (c_tree_index): Added CTI_NULL. + (null_node) Define global_tree[CTI_NULL]. + (warn_strict_null_sentinel): Declare. + * c-opts.c: (c_common_handle_option): Handle -Wstrict-null-sentinel. + * c.opt: (Wstrict-null-sentinel): New C++ option. + * doc/invoke.texi (C++ Options): Document -Wstrict-null-sentinel. + 2005-05-01 Kazu Hirata <kazu@cs.umass.edu> * gimplify.c (gimplify_compound_lval): Use VEC instead of diff --git a/gcc/c-common.c b/gcc/c-common.c index 8aa0aea4c97..22aa82e8d48 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -284,6 +284,12 @@ int warn_unknown_pragmas; /* Tri state variable. */ int warn_format; +/* Warn about using __null (as NULL in C++) as sentinel. For code compiled + with GCC this doesn't matter as __null is guaranteed to have the right + size. */ + +int warn_strict_null_sentinel; + /* Zero means that faster, ...NonNil variants of objc_msgSend... calls will be used in ObjC; passing nil receivers to such calls will most likely result in crashes. */ @@ -3279,6 +3285,11 @@ c_common_nodes_and_builtins (void) mudflap_init (); main_identifier_node = get_identifier ("main"); + + /* Create the built-in __null node. It is important that this is + not shared. */ + null_node = make_node (INTEGER_CST); + TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0); } /* Look up the function in built_in_decls that corresponds to DECL @@ -5134,8 +5145,15 @@ check_function_sentinel (tree attrs, tree params) } /* Validate the sentinel. */ - if (!POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (sentinel))) - || !integer_zerop (TREE_VALUE (sentinel))) + if ((!POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (sentinel))) + || !integer_zerop (TREE_VALUE (sentinel))) + /* Although __null (in C++) is only an integer we allow it + nevertheless, as we are guaranteed that it's exactly + as wide as a pointer, and we don't want to force + users to cast the NULL they have written there. + We warn with -Wstrict-null-sentinel, though. */ + && (warn_strict_null_sentinel + || null_node != TREE_VALUE (sentinel))) warning (0, "missing sentinel in function call"); } } diff --git a/gcc/c-common.h b/gcc/c-common.h index 5c9330b3c90..c43531bc88a 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -159,6 +159,8 @@ enum c_tree_index CTI_VOID_ZERO, + CTI_NULL, + CTI_MAX }; @@ -203,6 +205,9 @@ struct c_common_identifier GTY(()) /* A node for `((void) 0)'. */ #define void_zero_node c_global_trees[CTI_VOID_ZERO] +/* The node for C++ `__null'. */ +#define null_node c_global_trees[CTI_NULL] + extern GTY(()) tree c_global_trees[CTI_MAX]; /* In a RECORD_TYPE, a sorted array of the fields of the type, not a @@ -570,6 +575,12 @@ extern int flag_threadsafe_statics; extern int warn_implicit; +/* Warn about using __null (as NULL in C++) as sentinel. For code compiled + with GCC this doesn't matter as __null is guaranteed to have the right + size. */ + +extern int warn_strict_null_sentinel; + /* Maximum template instantiation depth. This limit is rather arbitrary, but it exists to limit the time it takes to notice infinite template instantiations. */ diff --git a/gcc/c-opts.c b/gcc/c-opts.c index 4ac8e9d4395..ebf23e571d7 100644 --- a/gcc/c-opts.c +++ b/gcc/c-opts.c @@ -477,6 +477,10 @@ c_common_handle_option (size_t scode, const char *arg, int value) warn_return_type = value; break; + case OPT_Wstrict_null_sentinel: + warn_strict_null_sentinel = value; + break; + case OPT_Wsystem_headers: cpp_opts->warn_system_headers = value; break; diff --git a/gcc/c.opt b/gcc/c.opt index ee456fc45cc..4467df3eb80 100644 --- a/gcc/c.opt +++ b/gcc/c.opt @@ -354,6 +354,10 @@ Wsign-promo C++ ObjC++ Var(warn_sign_promo) Warn when overload promotes from unsigned to signed +Wstrict-null-sentinel +C++ ObjC++ +Warn about uncasted NULL used as sentinel + Wstrict-prototypes C ObjC Var(warn_strict_prototypes) Warn about unprototyped function declarations diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 09677e8f645..30fbba682d8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2005-05-02 Michael Matz <matz@suse.de> + + PR c++/19542 + * cp-tree.h (cp_tree_index): Remove CPTI_NULL, to be defined in C + common frontend. + (null_node): Remove. + * lex.c (cxx_init): Move null_node initialisation to C common frontend. + 2005-04-25 Ian Lance Taylor <ian@airs.com> * cp-tree.def: Add EXPR_STMT. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 05b28dde06f..87129241f35 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -518,7 +518,6 @@ enum cp_tree_index CPTI_LANG_NAME_JAVA, CPTI_EMPTY_EXCEPT_SPEC, - CPTI_NULL, CPTI_JCLASS, CPTI_TERMINATE, CPTI_CALL_UNEXPECTED, @@ -614,9 +613,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; /* Exception specifier used for throw(). */ #define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC] -/* The node for `__null'. */ -#define null_node cp_global_trees[CPTI_NULL] - /* If non-NULL, a POINTER_TYPE equivalent to (java::lang::Class*). */ #define jclass_node cp_global_trees[CPTI_JCLASS] diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index c5f21d1b195..04f648fddc8 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -347,11 +347,6 @@ cxx_init (void) cxx_init_decl_processing (); - /* Create the built-in __null node. It is important that this is - not shared. */ - null_node = make_node (INTEGER_CST); - TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0); - /* The fact that G++ uses COMDAT for many entities (inline functions, template instantiations, virtual tables, etc.) mean that it is fundamentally unreliable to try to make decisions diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 659fa5a731d..2bb87440a5c 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -185,7 +185,7 @@ in the following sections. -fno-default-inline -fvisibility-inlines-hidden @gol -Wabi -Wctor-dtor-privacy @gol -Wnon-virtual-dtor -Wreorder @gol --Weffc++ -Wno-deprecated @gol +-Weffc++ -Wno-deprecated -Wstrict-null-sentinel @gol -Wno-non-template-friend -Wold-style-cast @gol -Woverloaded-virtual -Wno-pmf-conversions @gol -Wsign-promo} @@ -1741,6 +1741,14 @@ to filter out those warnings. @opindex Wno-deprecated Do not warn about usage of deprecated features. @xref{Deprecated Features}. +@item -Wstrict-null-sentinel @r{(C++ only)} +@opindex Wstrict-null-sentinel +Warn also about the use of an uncasted @code{NULL} as sentinel. When +compiling only with GCC this is a valid sentinel, as @code{NULL} is defined +to @code{__null}. Although it is a null pointer constant not a null pointer, +it is guaranteed to of the same size as a pointer. But this use is +not portable across different compilers. + @item -Wno-non-template-friend @r{(C++ only)} @opindex Wno-non-template-friend Disable warnings when non-templatized friend functions are declared diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 33dca447a1e..a2fcc8b7a65 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-05-02 Michael Matz <matz@suse.de> + + PR c++/19542 + * g++.dg/warn/sentinel.C: New testcase for __null sentinels added. + 2005-05-01 Mark Mitchell <mark@codesourcery.com> * g++.dg/cpp/weak.C: New test. diff --git a/gcc/testsuite/g++.dg/warn/sentinel.C b/gcc/testsuite/g++.dg/warn/sentinel.C new file mode 100644 index 00000000000..5f718f83047 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/sentinel.C @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ +extern void ex (int i, ...) __attribute__ ((__sentinel__(0))); + +void f() +{ + ex (1, 0); /* { dg-warning "missing sentinel in function call" "" } */ + ex (1, 0L); /* { dg-warning "missing sentinel in function call" "" } */ + ex (1, (void *)0); + ex (1, __null); /* { dg-bogus "sentinel" } */ +} |