aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2023-03-28 14:34:49 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2023-03-28 14:34:49 -0400
commit22c3a6c3c118283dfef1b9928dd21110098679b7 (patch)
tree4e0c0bb61d608e1603f1b6fabf4f2460a718a0a2 /gcc/c-family
parentaf45b17d0a8fe3e7ae08662008a1f41e48a4a3eb (diff)
downloadgcc-22c3a6c3c118283dfef1b9928dd21110098679b7.zip
gcc-22c3a6c3c118283dfef1b9928dd21110098679b7.tar.gz
gcc-22c3a6c3c118283dfef1b9928dd21110098679b7.tar.bz2
Don't emit -Wxor-used-as-pow on macro expansions [PR107002]
PR c/107002 reports an assertion failure from deep inside the diagnostic_shows_locus when attempting to print fix-it hints relating to -Wxor-used-as-pow. The case involves macro expansions with -ftrack-macro-expansion=0. It doesn't seem to make much sense to emit this warning for macro expansions, so this patch updates the warning not to (which seems to also be clang's behavior). The patch also adds some bulletproofing to diagnostic-show-locus.cc to be more robust against such invalid fix-it hints. Doing so fixes the ICE. gcc/c-family/ChangeLog: PR c/107002 * c-common.h (check_for_xor_used_as_pow): Add "rhs_loc" param. * c-warn.cc (check_for_xor_used_as_pow): Add "rhs_loc" param. Reject cases where involving macro expansions. gcc/c/ChangeLog: PR c/107002 * c-typeck.cc (parser_build_binary_op): Update for new param of check_for_xor_used_as_pow. gcc/cp/ChangeLog: PR c/107002 * parser.cc (cp_parser_binary_expression): Update for new param of check_for_xor_used_as_pow. gcc/ChangeLog: PR c/107002 * diagnostic-show-locus.cc (column_range::column_range): Factor out assertion conditional into... (column_range::valid_p): ...this new function. (line_corrections::add_hint): Don't attempt to consolidate hints if it would lead to invalid column_range instances. gcc/testsuite/ChangeLog: PR c/107002 * c-c++-common/Wxor-used-as-pow-1.c: Add macro test. * c-c++-common/Wxor-used-as-pow-pr107002-0.c: New test. * c-c++-common/Wxor-used-as-pow-pr107002-1.c: New test. * c-c++-common/Wxor-used-as-pow-pr107002-2.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/c-common.h2
-rw-r--r--gcc/c-family/c-warn.cc23
2 files changed, 20 insertions, 5 deletions
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index e128e3e..f96350b 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1524,7 +1524,7 @@ extern void warn_for_multistatement_macros (location_t, location_t,
extern void check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val,
location_t operator_loc,
- tree rhs_val);
+ location_t rhs_loc, tree rhs_val);
/* In c-attribs.cc. */
extern bool attribute_takes_identifier_p (const_tree);
diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index ccbede9..9ac43a1 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -3835,14 +3835,15 @@ do_warn_array_compare (location_t location, tree_code code, tree op0, tree op1)
}
}
-/* Given LHS_VAL ^ RHS_VAL, where LHS_LOC is the location of the LHS and
- OPERATOR_LOC is the location of the ^, complain with -Wxor-used-as-pow
- if it looks like the user meant exponentiation rather than xor. */
+/* Given LHS_VAL ^ RHS_VAL, where LHS_LOC is the location of the LHS,
+ OPERATOR_LOC is the location of the ^, and RHS_LOC the location of the
+ RHS, complain with -Wxor-used-as-pow if it looks like the user meant
+ exponentiation rather than xor. */
void
check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val,
location_t operator_loc,
- tree rhs_val)
+ location_t rhs_loc, tree rhs_val)
{
/* Only complain if both args are non-negative integer constants that fit
in uhwi. */
@@ -3859,6 +3860,20 @@ check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val,
binary_op_rich_location loc (operator_loc,
lhs_val, rhs_val, false);
+ /* Reject cases where we don't have 3 distinct locations.
+ This can happen e.g. due to macro expansion with
+ -ftrack-macro-expansion=0 */
+ if (!(lhs_loc != operator_loc
+ && lhs_loc != rhs_loc
+ && operator_loc != rhs_loc))
+ return;
+
+ /* Reject cases in which any of the locations came from a macro. */
+ if (from_macro_expansion_at (lhs_loc)
+ || from_macro_expansion_at (operator_loc)
+ || from_macro_expansion_at (rhs_loc))
+ return;
+
/* If we issue fix-it hints with the warning then we will also issue a
note suggesting how to suppress the warning with a different change.
These proposed changes are incompatible. */