Re: [PATCH 08/11] Make conversion warnings work on NULL with -ftrack-macro-expansion

2012-04-25 Thread Dodji Seketeli
Gabriel Dos Reis g...@integrable-solutions.net writes:

 On Wed, Apr 11, 2012 at 3:46 AM, Dodji Seketeli do...@redhat.com wrote:
 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 like the idea.  However, you should write a separate function
 (get_null_ptr_cst_location?) that computes the location of the null
 pointer constant token and call it from where you need the location.

OK.  I have introduced such a new function and I gave it the slightly
more generic name expansion_point_location_if_in_system_header as I
suspect it can be useful for macros that are similar to NULL.  I haven't
spotted such macros (from test regressions) yet, though.

Here is the updated patch that passes bootstrap with
-ftrack-macro-expansion turned off; it also passes bootstrap with
-ftrack-macro-expansion turned on with the whole series of patches I
have locally on my tree.

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.
---
 gcc/cp/call.c  |   16 ++-
 gcc/cp/cvt.c   |   16 ++-
 gcc/cp/typeck.c|   18 +++--
 gcc/input.c|   14 ++
 gcc/input.h|1 +
 gcc/testsuite/g++.dg/warn/Wconversion-null-2.C |   31 +++-
 6 files changed, 88 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f9a7f08..1dc57fc 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5598,12 +5598,24 @@ conversion_null_warnings (tree totype, tree expr, tree 
fn, int argnum)
   if (expr == null_node  TREE_CODE (totype) != BOOLEAN_TYPE
ARITHMETIC_TYPE_P (totype))
 {
+  /* The location of the warning here is most certainly the one for
+the token that represented null_node in the source code.
+That is either NULL or __null.  If it is NULL, then that
+macro is defined in a system header and, as a consequence,
+warning_at won't emit any diagnostic for it.  In this case,
+we are going to resolve that location to the point in the
+source code where the expression that triggered this error
+message is, rather than the point where the NULL macro is
+defined.  */
+  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);
 }
 
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 3dab372..8defc61 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -1472,8 +1472,20 @@ 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);
+{
+  /* The location of the warning here is the one for the
+(expansion of the) NULL macro, or for __null.  If it is for
+NULL, then, as that that macro is defined in a system header,
+warning_at won't emit any diagnostic.  In this case, we are
+going to resolve that location to the point in the source
+code where the expression that triggered this warning is,
+rather than the point where the NULL macro is defined.  */
+  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);
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c

Re: [PATCH 08/11] Make conversion warnings work on NULL with -ftrack-macro-expansion

2012-04-25 Thread Gabriel Dos Reis
On Wed, Apr 25, 2012 at 8:42 AM, Dodji Seketeli do...@redhat.com wrote:
 Gabriel Dos Reis g...@integrable-solutions.net writes:

 On Wed, Apr 11, 2012 at 3:46 AM, Dodji Seketeli do...@redhat.com wrote:
 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 like the idea.  However, you should write a separate function
 (get_null_ptr_cst_location?) that computes the location of the null
 pointer constant token and call it from where you need the location.

 OK.  I have introduced such a new function and I gave it the slightly
 more generic name expansion_point_location_if_in_system_header as I
 suspect it can be useful for macros that are similar to NULL.  I haven't
 spotted such macros (from test regressions) yet, though.

Thanks.  But a point of the suggestion was that we won't need the
same comment/explanation duplicated over at least 3 places.  Just
one.  All those three places deal exactly with one instance: null
pointer constant.  That deserves a function in and of itself, which
is documented by the duplicated comments.
Please make that change.  Everything else is OK.  thanks.


Re: [PATCH 08/11] Make conversion warnings work on NULL with -ftrack-macro-expansion

2012-04-25 Thread Dodji Seketeli
Gabriel Dos Reis g...@integrable-solutions.net writes:

 Thanks.  But a point of the suggestion was that we won't need the
 same comment/explanation duplicated over at least 3 places.  Just
 one.  All those three places deal exactly with one instance: null
 pointer constant.  That deserves a function in and of itself, which
 is documented by the duplicated comments.
 Please make that change.  Everything else is OK.  thanks.

I am sorry for the round trips.  Please find below a patch udpated
accordingly.

I am bootstrapping the whole patch set, but the impacted files of this
patch have built fine so far.

Thanks.

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.
---
 gcc/cp/call.c  |7 -
 gcc/cp/cvt.c   |9 +-
 gcc/cp/typeck.c|9 --
 gcc/input.c|   20 +++
 gcc/input.h|1 +
 gcc/testsuite/g++.dg/warn/Wconversion-null-2.C |   31 +++-
 6 files changed, 69 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f9a7f08..85e45c2 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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);
 }
 
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 3dab372..49ba38a 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -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);
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index fb2f1bc..52d264b 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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)
 {
diff --git a/gcc/input.c b/gcc/input.c
index 260be7e..5f14489 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -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)
diff --git a/gcc/input.h b/gcc/input.h

Re: [PATCH 08/11] Make conversion warnings work on NULL with -ftrack-macro-expansion

2012-04-25 Thread Gabriel Dos Reis
OK, thanks!

-- Gaby


Re: [PATCH 08/11] Make conversion warnings work on NULL with -ftrack-macro-expansion

2012-04-11 Thread Gabriel Dos Reis
On Wed, Apr 11, 2012 at 3:46 AM, Dodji Seketeli do...@redhat.com wrote:
 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 like the idea.  However, you should write a separate function
(get_null_ptr_cst_location?) that computes the location of the null
pointer constant token and call it from where you need the location.

 @@ -5538,12 +5538,26 @@ 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 = input_location;
 +      /* The location of the warning here is most certainly the one for
 +        the token that represented null_node in the source code.
 +        That is either NULL or __null.  If it is NULL, then that
 +        macro is defined in a system header and, as a consequence,
 +        warning_at won't emit any diagnostic for it.  In this case,
 +        we are going to resolve that location to the point in the
 +        source code where the expression that triggered this error
 +        message is, rather than the point where the NULL macro is
 +        defined.  */
 +      if (in_system_header_at (input_location))
 +       loc = linemap_resolve_location (line_table, loc,
 +                                       LRK_MACRO_EXPANSION_POINT,
 +                                       NULL);
       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);
     }

 diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
 index c411a47..73bdf71 100644
 --- a/gcc/cp/cvt.c
 +++ b/gcc/cp/cvt.c
 @@ -1468,8 +1468,22 @@ 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 = input_location;
 +      /* The location of the warning here is the one for the
 +        (expansion of the) NULL macro, or for __null.  If it is for
 +        NULL, then, as that that macro is defined in a system header,
 +        warning_at won't emit any diagnostic.  In this case, we are
 +        going to resolve that location to the point in the source
 +        code where the expression that triggered this warning is,
 +        rather than the point where the NULL macro is defined.  */
 +      if (in_system_header_at (loc))
 +       loc = linemap_resolve_location (line_table, loc,
 +                                       LRK_MACRO_EXPANSION_POINT,
 +                                       NULL);
 +      warning_at (loc, OPT_Wconversion_null,
 +                 converting NULL to non-pointer type);
 +    }

   basetype = TREE_TYPE (expr);

 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
 index d2ed940..d096f1e 100644
 --- a/gcc/cp/typeck.c
 +++ b/gcc/cp/typeck.c
 @@ -3798,9 +3798,23 @@ 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 = input_location;
 +      /* Some sort of arithmetic operation involving NULL was
 +        performed.  The location of the warning here is the one for
 +        the (expansion of the) NULL macro, or for __null.  If it is
 +        for NULL, then, as that that macro is defined in a system
 +        header, warning_at won't emit any diagnostic.  In this case,
 +        we are going to resolve that location to the point in the
 +        source code where the expression that triggered this warning
 +        is, rather than the point where the NULL macro is
 +        defined.  */
 +      if (in_system_header_at (loc))
 +       loc = linemap_resolve_location (line_table, loc,
 +                                       LRK_MACRO_EXPANSION_POINT,
 +                                       NULL);
 +      warning_at (loc,