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 index f755cdf..f588838 100644 --- a/gcc/input.h +++ b/gcc/input.h @@ -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. */ diff --git a/gcc/testsuite/g++.dg/warn/Wconversion-null-2.C b/gcc/testsuite/g++.dg/warn/Wconversion-null-2.C index dd498c1..a71551f 100644 --- a/gcc/testsuite/g++.dg/warn/Wconversion-null-2.C +++ b/gcc/testsuite/g++.dg/warn/Wconversion-null-2.C @@ -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(); +} -- Dodji