Commit b2f97e4a by Michael Matz Committed by Michael Matz

re PR c++/19542 (attribute(sentinel) has problems with C++ __null)

        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.

        * 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.

        * g++.dg/warn/sentinel.C: New testcase for __null sentinels added.

From-SVN: r99091
parent f8f9fb45
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> 2005-05-01 Kazu Hirata <kazu@cs.umass.edu>
* gimplify.c (gimplify_compound_lval): Use VEC instead of * gimplify.c (gimplify_compound_lval): Use VEC instead of
......
...@@ -284,6 +284,12 @@ int warn_unknown_pragmas; /* Tri state variable. */ ...@@ -284,6 +284,12 @@ int warn_unknown_pragmas; /* Tri state variable. */
int warn_format; 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... /* Zero means that faster, ...NonNil variants of objc_msgSend...
calls will be used in ObjC; passing nil receivers to such calls calls will be used in ObjC; passing nil receivers to such calls
will most likely result in crashes. */ will most likely result in crashes. */
...@@ -3279,6 +3285,11 @@ c_common_nodes_and_builtins (void) ...@@ -3279,6 +3285,11 @@ c_common_nodes_and_builtins (void)
mudflap_init (); mudflap_init ();
main_identifier_node = get_identifier ("main"); 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 /* Look up the function in built_in_decls that corresponds to DECL
...@@ -5134,8 +5145,15 @@ check_function_sentinel (tree attrs, tree params) ...@@ -5134,8 +5145,15 @@ check_function_sentinel (tree attrs, tree params)
} }
/* Validate the sentinel. */ /* Validate the sentinel. */
if (!POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (sentinel))) if ((!POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (sentinel)))
|| !integer_zerop (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"); warning (0, "missing sentinel in function call");
} }
} }
......
...@@ -159,6 +159,8 @@ enum c_tree_index ...@@ -159,6 +159,8 @@ enum c_tree_index
CTI_VOID_ZERO, CTI_VOID_ZERO,
CTI_NULL,
CTI_MAX CTI_MAX
}; };
...@@ -203,6 +205,9 @@ struct c_common_identifier GTY(()) ...@@ -203,6 +205,9 @@ struct c_common_identifier GTY(())
/* A node for `((void) 0)'. */ /* A node for `((void) 0)'. */
#define void_zero_node c_global_trees[CTI_VOID_ZERO] #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]; extern GTY(()) tree c_global_trees[CTI_MAX];
/* In a RECORD_TYPE, a sorted array of the fields of the type, not a /* In a RECORD_TYPE, a sorted array of the fields of the type, not a
...@@ -570,6 +575,12 @@ extern int flag_threadsafe_statics; ...@@ -570,6 +575,12 @@ extern int flag_threadsafe_statics;
extern int warn_implicit; 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 /* Maximum template instantiation depth. This limit is rather
arbitrary, but it exists to limit the time it takes to notice arbitrary, but it exists to limit the time it takes to notice
infinite template instantiations. */ infinite template instantiations. */
......
...@@ -477,6 +477,10 @@ c_common_handle_option (size_t scode, const char *arg, int value) ...@@ -477,6 +477,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
warn_return_type = value; warn_return_type = value;
break; break;
case OPT_Wstrict_null_sentinel:
warn_strict_null_sentinel = value;
break;
case OPT_Wsystem_headers: case OPT_Wsystem_headers:
cpp_opts->warn_system_headers = value; cpp_opts->warn_system_headers = value;
break; break;
......
...@@ -354,6 +354,10 @@ Wsign-promo ...@@ -354,6 +354,10 @@ Wsign-promo
C++ ObjC++ Var(warn_sign_promo) C++ ObjC++ Var(warn_sign_promo)
Warn when overload promotes from unsigned to signed Warn when overload promotes from unsigned to signed
Wstrict-null-sentinel
C++ ObjC++
Warn about uncasted NULL used as sentinel
Wstrict-prototypes Wstrict-prototypes
C ObjC Var(warn_strict_prototypes) C ObjC Var(warn_strict_prototypes)
Warn about unprototyped function declarations Warn about unprototyped function declarations
......
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> 2005-04-25 Ian Lance Taylor <ian@airs.com>
* cp-tree.def: Add EXPR_STMT. * cp-tree.def: Add EXPR_STMT.
......
...@@ -518,7 +518,6 @@ enum cp_tree_index ...@@ -518,7 +518,6 @@ enum cp_tree_index
CPTI_LANG_NAME_JAVA, CPTI_LANG_NAME_JAVA,
CPTI_EMPTY_EXCEPT_SPEC, CPTI_EMPTY_EXCEPT_SPEC,
CPTI_NULL,
CPTI_JCLASS, CPTI_JCLASS,
CPTI_TERMINATE, CPTI_TERMINATE,
CPTI_CALL_UNEXPECTED, CPTI_CALL_UNEXPECTED,
...@@ -614,9 +613,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; ...@@ -614,9 +613,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
/* Exception specifier used for throw(). */ /* Exception specifier used for throw(). */
#define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC] #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*). */ /* If non-NULL, a POINTER_TYPE equivalent to (java::lang::Class*). */
#define jclass_node cp_global_trees[CPTI_JCLASS] #define jclass_node cp_global_trees[CPTI_JCLASS]
......
...@@ -347,11 +347,6 @@ cxx_init (void) ...@@ -347,11 +347,6 @@ cxx_init (void)
cxx_init_decl_processing (); 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 /* The fact that G++ uses COMDAT for many entities (inline
functions, template instantiations, virtual tables, etc.) mean functions, template instantiations, virtual tables, etc.) mean
that it is fundamentally unreliable to try to make decisions that it is fundamentally unreliable to try to make decisions
......
...@@ -185,7 +185,7 @@ in the following sections. ...@@ -185,7 +185,7 @@ in the following sections.
-fno-default-inline -fvisibility-inlines-hidden @gol -fno-default-inline -fvisibility-inlines-hidden @gol
-Wabi -Wctor-dtor-privacy @gol -Wabi -Wctor-dtor-privacy @gol
-Wnon-virtual-dtor -Wreorder @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 -Wno-non-template-friend -Wold-style-cast @gol
-Woverloaded-virtual -Wno-pmf-conversions @gol -Woverloaded-virtual -Wno-pmf-conversions @gol
-Wsign-promo} -Wsign-promo}
...@@ -1741,6 +1741,14 @@ to filter out those warnings. ...@@ -1741,6 +1741,14 @@ to filter out those warnings.
@opindex Wno-deprecated @opindex Wno-deprecated
Do not warn about usage of deprecated features. @xref{Deprecated Features}. 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)} @item -Wno-non-template-friend @r{(C++ only)}
@opindex Wno-non-template-friend @opindex Wno-non-template-friend
Disable warnings when non-templatized friend functions are declared Disable warnings when non-templatized friend functions are declared
......
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> 2005-05-01 Mark Mitchell <mark@codesourcery.com>
* g++.dg/cpp/weak.C: New test. * g++.dg/cpp/weak.C: New test.
......
/* { 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" } */
}
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