summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2005-05-02 04:22:45 +0000
committermatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2005-05-02 04:22:45 +0000
commitae84079f60ba4b17406aa3cdf1eae1cea010ffe7 (patch)
tree81e0ec0700839598638506aadcfb471636db87e6
parent0dc02c83cfce5adc2119ed59f21c228aa392a606 (diff)
downloadgcc-ae84079f60ba4b17406aa3cdf1eae1cea010ffe7.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99091 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/c-common.c22
-rw-r--r--gcc/c-common.h11
-rw-r--r--gcc/c-opts.c4
-rw-r--r--gcc/c.opt4
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/lex.c5
-rw-r--r--gcc/doc/invoke.texi10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/warn/sentinel.C11
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" } */
+}