@@ -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);
@@ -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. */
@@ -4083,7 +4083,7 @@ parser_build_binary_op (location_t location, enum tree_code code,
&& arg2.m_decimal)
check_for_xor_used_as_pow (arg1.get_location (), arg1.value,
location,
- arg2.value);
+ arg2.get_location (), arg2.value);
return result;
}
@@ -10289,6 +10289,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
(current.lhs.get_location (),
tree_strip_any_location_wrapper (current.lhs),
current.loc,
+ rhs.get_location (),
tree_strip_any_location_wrapper (rhs));
overload = NULL;
@@ -2232,8 +2232,7 @@ class column_range
public:
column_range (int start_, int finish_) : start (start_), finish (finish_)
{
- /* We must have either a range, or an insertion. */
- gcc_assert (start <= finish || finish == start - 1);
+ gcc_assert (valid_p (start, finish));
}
bool operator== (const column_range &other) const
@@ -2241,6 +2240,12 @@ public:
return start == other.start && finish == other.finish;
}
+ static bool valid_p (int start, int finish)
+ {
+ /* We must have either a range, or an insertion. */
+ return (start <= finish || finish == start - 1);
+ }
+
int start;
int finish;
};
@@ -2470,7 +2475,9 @@ line_corrections::add_hint (const fixit_hint *hint)
gcc_assert (printed_columns.start
>= last_correction->m_printed_columns.start);
- if (printed_columns.start <= last_correction->m_printed_columns.finish)
+ if (printed_columns.start <= last_correction->m_printed_columns.finish
+ && column_range::valid_p (last_correction->m_affected_bytes.finish + 1,
+ affected_bytes.start - 1))
{
/* We have two hints for which the printed forms of the hints
would touch or overlap, so we need to consolidate them to avoid
@@ -55,3 +55,7 @@ int h10_3 = 0xa ^ 3;
/* Don't complain if the RHS isn't literal decimal. */
int t2_x16 = 2^0x10;
int h10_x3 = 10 ^ 0x3;
+
+/* Don't complain about uses in macros. */
+#define AMT (10^2)
+int amt = AMT;
new file mode 100644
@@ -0,0 +1,9 @@
+/* Regression test for ICE seen in -Wxor-used-as-pow with
+ -ftrack-macro-expansion=0 in source-printing (fix-it-hints,
+ specifically). */
+
+/* { dg-options "-ftrack-macro-expansion=0 -fdiagnostics-show-caret" } */
+
+#define test(lower, higher, a, b, c, d) \
+ char test##line[ (a higher b lower c higher d) == 0 ? -1 : 1];
+test (|, ^, 1, 2, 2, 1)
new file mode 100644
@@ -0,0 +1,5 @@
+/* { dg-options "-ftrack-macro-expansion=1 -fdiagnostics-show-caret" } */
+
+#define test(lower, higher, a, b, c, d) \
+ char test##line[ (a higher b lower c higher d) == 0 ? -1 : 1];
+test (|, ^, 1, 2, 2, 1)
new file mode 100644
@@ -0,0 +1,5 @@
+/* { dg-options "-ftrack-macro-expansion=2 -fdiagnostics-show-caret" } */
+
+#define test(lower, higher, a, b, c, d) \
+ char test##line[ (a higher b lower c higher d) == 0 ? -1 : 1];
+test (|, ^, 1, 2, 2, 1)