]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Make conversion warnings work on NULL with -ftrack-macro-expansion
authorDodji Seketeli <dodji@redhat.com>
Mon, 30 Apr 2012 11:42:38 +0000 (11:42 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Mon, 30 Apr 2012 11:42:38 +0000 (13:42 +0200)
There are various conversion related warnings that trigger on
potentially dangerous uses of NULL (or __null).  NULL is defined as a
macro in a system header, so calling warning or warning_at on a
virtual location of NULL yields no diagnostic.  So the test
accompanying this patch (as well as others), was failling when run
with -ftrack-macro-expansion.

I think it's necessary to use the location of NULL that is in the main
source code (instead of, e.g, the spelling location that is in the
system header where the macro is defined) in those cases.  Note that
for __null, we don't have the issue.

I have augmented the test of this patch to check that we don't regress
when handling __null.

Tested on x86_64-unknown-linux-gnu against trunk.

Note that the bootstrap with -ftrack-macro-expansion exhibits other
separate issues that are addressed in subsequent patches.  This patch
just fixes one class of problems.

The patch does pass bootstrap with -ftrack-macro-expansion turned off,
though.

gcc/
* input.h (expansion_point_location_if_in_system_header): Declare
new function.
* input.c (expansion_point_location_if_in_system_header): Define it.
gcc/cp/

* call.c (conversion_null_warnings): Use the new
expansion_point_location_if_in_system_header.
* cvt.c (build_expr_type_conversion): Likewise.
* typeck.c (cp_build_binary_op): Likewise.

gcc/testsuite/

* g++.dg/warn/Wconversion-null-2.C: Add testing for __null,
alongside the previous testing for NULL.

From-SVN: r186972

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cvt.c
gcc/cp/typeck.c
gcc/input.c
gcc/input.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wconversion-null-2.C

index 470a1a5f29e76a8fb790c45caacd5d1498bc7a0d..5544d667392e5fdcbf41273e680cebf415554c2a 100644 (file)
@@ -1,5 +1,11 @@
 2012-04-30  Dodji Seketeli  <dodji@redhat.com>
 
+       Make conversion warnings work on NULL with -ftrack-macro-expansion
+       * input.h (expansion_point_location_if_in_system_header): Declare
+       new function.
+       * input.c (expansion_point_location_if_in_system_header): Define
+       it.
+
        Fix -Wuninitialized for -ftrack-macro-expansion
        * tree-ssa.c (warn_uninit): Use the spelling location of the
        variable declaration.  Use linemap_location_before_p for source
index 541e725ee8e193c1a7225de7eccb8c1fa5cd16e9..67dd067e867d55558c8e4acabc6f2422f00d460c 100644 (file)
@@ -1,3 +1,11 @@
+2012-04-30  Dodji Seketeli  <dodji@redhat.com>
+
+       Make conversion warnings work on NULL with -ftrack-macro-expansion
+       * call.c (conversion_null_warnings): Use the new
+       expansion_point_location_if_in_system_header.
+       * cvt.c (build_expr_type_conversion): Likewise.
+       * typeck.c (cp_build_binary_op): Likewise.
+
 2012-04-30  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        * typeck.c (convert_for_assignment):  Replace
index 2207f421c415109194898d4effc4cd9b36ed1f08..98d32c347e176d466732488598c442ae6aa0bbc4 100644 (file)
@@ -5598,12 +5598,15 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
   if (expr == null_node && TREE_CODE (totype) != BOOLEAN_TYPE
       && ARITHMETIC_TYPE_P (totype))
     {
+      source_location loc =
+       expansion_point_location_if_in_system_header (input_location);
+
       if (fn)
-       warning_at (input_location, OPT_Wconversion_null,
+       warning_at (loc, OPT_Wconversion_null,
                    "passing NULL to non-pointer argument %P of %qD",
                    argnum, fn);
       else
-       warning_at (input_location, OPT_Wconversion_null,
+       warning_at (loc, OPT_Wconversion_null,
                    "converting to non-pointer type %qT from NULL", totype);
     }
 
index 3dab372a301921e68754fd67844408be198a7316..49ba38a3f3961ec0724f4ac6e60861e7183bbd09 100644 (file)
@@ -1472,8 +1472,13 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
   if (expr == null_node
       && (desires & WANT_INT)
       && !(desires & WANT_NULL))
-    warning_at (input_location, OPT_Wconversion_null,
-               "converting NULL to non-pointer type");
+    {
+      source_location loc =
+       expansion_point_location_if_in_system_header (input_location);
+
+      warning_at (loc, OPT_Wconversion_null,
+                 "converting NULL to non-pointer type");
+    }
 
   basetype = TREE_TYPE (expr);
 
index 142402a0308bca77b7dcda6392386ecfb6906cd2..4f1e965c65ae2d8c382c2cc9f942689677043c8a 100644 (file)
@@ -3838,9 +3838,12 @@ cp_build_binary_op (location_t location,
          || (!null_ptr_cst_p (orig_op1) 
              && !TYPE_PTR_P (type1) && !TYPE_PTR_TO_MEMBER_P (type1)))
       && (complain & tf_warning))
-    /* Some sort of arithmetic operation involving NULL was
-       performed.  */
-    warning (OPT_Wpointer_arith, "NULL used in arithmetic");
+    {
+      source_location loc =
+       expansion_point_location_if_in_system_header (input_location);
+
+      warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic");
+    }
 
   switch (code)
     {
index 260be7e7d550c3e402015d77994b3590d233f224..5f14489753f20d408f1cf133e1a6be3e03808c1d 100644 (file)
@@ -162,6 +162,26 @@ expand_location_to_spelling_point (source_location loc)
   return expand_location_1 (loc, /*expansion_piont_p=*/false);
 }
 
+/* If LOCATION is in a sytem header and if it's a virtual location for
+   a token coming from the expansion of a macro M, unwind it to the
+   location of the expansion point of M.  Otherwise, just return
+   LOCATION.
+
+   This is used for instance when we want to emit diagnostics about a
+   token that is located in a macro that is itself defined in a system
+   header -- e.g for the NULL macro.  In that case, if LOCATION is
+   passed to diagnostics emitting functions like warning_at as is, no
+   diagnostic won't be emitted.  */
+
+source_location
+expansion_point_location_if_in_system_header (source_location location)
+{
+  if (in_system_header_at (location))
+    location = linemap_resolve_location (line_table, location,
+                                        LRK_MACRO_EXPANSION_POINT,
+                                        NULL);
+  return location;
+}
 
 #define ONE_K 1024
 #define ONE_M (ONE_K * ONE_K)
index ea19e0777979c23a305d16257607f466a6e1668a..d811255c9f46f564bf321ef357b81ac34ff222c1 100644 (file)
@@ -40,6 +40,7 @@ extern char builtins_location_check[(BUILTINS_LOCATION
 extern expanded_location expand_location (source_location);
 extern const char * location_get_source_line(expanded_location xloc);
 extern expanded_location expand_location_to_spelling_point (source_location);
+extern source_location expansion_point_location_if_in_system_header (source_location);
 
 /* Historically GCC used location_t, while cpp used source_location.
    This could be removed but it hardly seems worth the effort.  */
index 0b03515f96e518b489ad5a87c2806ef454260644..4fda9ae5e003af6ce12644acfddc3fa0bebdb3ee 100644 (file)
@@ -1,5 +1,9 @@
 2012-04-30  Dodji Seketeli  <dodji@redhat.com>
 
+       Make conversion warnings work on NULL with -ftrack-macro-expansion
+       * g++.dg/warn/Wconversion-null-2.C: Add testing for __null,
+       alongside the previous testing for NULL.
+
        Fix -Wuninitialized for -ftrack-macro-expansion
        * gcc.dg/cpp/pragma-diagnostic-2.c: Fix this.
 
index dd498c199d9b3495c3ee41ca3d8ba07371a40970..a71551fdf90a7a327ca22ac869de800854631841 100644 (file)
@@ -25,7 +25,7 @@ void l(long) {}
 template <>
 void l(long long) {}
 
-int main()
+void warn_for_NULL()
 {
   int i = NULL; // { dg-warning "" } converting NULL to non-pointer type
   float z = NULL; // { dg-warning "" } converting NULL to non-pointer type
@@ -47,3 +47,32 @@ int main()
   l(NULL);   // No warning: NULL is used to implicitly instantiate the template
   NULL && NULL; // No warning: converting NULL to bool is OK
 }
+
+int warn_for___null()
+{
+  int i = __null; // { dg-warning "" } converting __null to non-pointer type
+  float z = __null; // { dg-warning "" } converting __null to non-pointer type
+  int a[2];
+
+  i != __null; // { dg-warning "" } __null used in arithmetic
+  __null != z; // { dg-warning "" } __null used in arithmetic
+  k != __null; // No warning: decay conversion
+  __null != a; // Likewise.
+  -__null;     // { dg-warning "" } converting __null to non-pointer type
+  +__null;     // { dg-warning "" } converting __null to non-pointer type
+  ~__null;     // { dg-warning "" } converting __null to non-pointer type
+  a[__null] = 3; // { dg-warning "" } converting __null to non-pointer-type
+  i = __null;  // { dg-warning "" } converting __null to non-pointer type
+  z = __null;  // { dg-warning "" } converting __null to non-pointer type
+  k(__null);   // { dg-warning "" } converting __null to int
+  g(__null);   // { dg-warning "" } converting __null to int
+  h<__null>(); // No warning: __null bound to integer template parameter
+  l(__null);   // No warning: __null is used to implicitly instantiate the template
+  __null && __null; // No warning: converting NULL to bool is OK
+}
+
+int main()
+{
+  warn_for_NULL();
+  warn_for___null();
+}