extern void warn_for_multistatement_macros (location_t, location_t,
location_t, enum rid);
+extern void check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val,
+ location_t operator_loc,
+ tree rhs_val);
+
/* In c-attribs.cc. */
extern bool attribute_takes_identifier_p (const_tree);
extern tree handle_deprecated_attribute (tree *, tree, tree, int, bool *);
/* C++ uses '0' to mark virtual functions as pure.
Set PURE_ZERO to pass this information to the C++ parser. */
if (tok->val.str.len == 1 && *tok->val.str.text == '0')
- add_flags = PURE_ZERO;
+ add_flags = PURE_ZERO | DECIMAL_INT;
+ else if ((flags & CPP_N_INTEGER) && (flags & CPP_N_DECIMAL))
+ /* -Wxor-used-as-pow is only active for LHS of ^ expressed
+ as a decimal integer. */
+ add_flags = DECIMAL_INT;
*value = interpret_integer (tok, flags, &overflow);
break;
op0, op_symbol_code (code), 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. */
+
+void
+check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val,
+ location_t operator_loc,
+ tree rhs_val)
+{
+ /* Only complain if both args are non-negative integer constants. */
+ if (!(TREE_CODE (lhs_val) == INTEGER_CST
+ && tree_int_cst_sgn (lhs_val) >= 0))
+ return;
+ if (!(TREE_CODE (rhs_val) == INTEGER_CST
+ && tree_int_cst_sgn (rhs_val) >= 0))
+ return;
+
+ /* Only complain if the LHS is 2 or 10. */
+ unsigned HOST_WIDE_INT lhs_uhwi = tree_to_uhwi (lhs_val);
+ if (lhs_uhwi != 2 && lhs_uhwi != 10)
+ return;
+
+ unsigned HOST_WIDE_INT rhs_uhwi = tree_to_uhwi (rhs_val);
+ unsigned HOST_WIDE_INT xor_result = lhs_uhwi ^ rhs_uhwi;
+ binary_op_rich_location loc (operator_loc,
+ lhs_val, rhs_val, false);
+
+ /* 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. */
+ loc.fixits_cannot_be_auto_applied ();
+
+ auto_diagnostic_group d;
+ bool warned = false;
+ if (lhs_uhwi == 2)
+ {
+ /* Would exponentiation fit in int, in long long, or not at all? */
+ if (rhs_uhwi < (INT_TYPE_SIZE - 1))
+ {
+ unsigned HOST_WIDE_INT suggested_result = 1 << rhs_uhwi;
+ loc.add_fixit_replace (lhs_loc, "1");
+ loc.add_fixit_replace (operator_loc, "<<");
+ warned = warning_at (&loc, OPT_Wxor_used_as_pow,
+ "result of %<%wu^%wu%> is %wu;"
+ " did you mean %<1 << %wu%> (%wu)?",
+ lhs_uhwi, rhs_uhwi, xor_result,
+ rhs_uhwi, suggested_result);
+ }
+ else if (rhs_uhwi < (LONG_LONG_TYPE_SIZE - 1))
+ {
+ loc.add_fixit_replace (lhs_loc, "1LL");
+ loc.add_fixit_replace (operator_loc, "<<");
+ warned = warning_at (&loc, OPT_Wxor_used_as_pow,
+ "result of %<%wu^%wu%> is %wu;"
+ " did you mean %<1LL << %wu%>?",
+ lhs_uhwi, rhs_uhwi, xor_result,
+ rhs_uhwi);
+ }
+ else if (rhs_uhwi <= LONG_LONG_TYPE_SIZE)
+ warned = warning_at (&loc, OPT_Wxor_used_as_pow,
+ "result of %<%wu^%wu%> is %wu;"
+ " did you mean exponentiation?",
+ lhs_uhwi, rhs_uhwi, xor_result);
+ /* Otherwise assume it's an xor. */
+ }
+ else
+ {
+ gcc_assert (lhs_uhwi == 10);
+ loc.add_fixit_replace (lhs_loc, "1");
+ loc.add_fixit_replace (operator_loc, "e");
+ warned = warning_at (&loc, OPT_Wxor_used_as_pow,
+ "result of %<%wu^%wu%> is %wu;"
+ " did you mean %<1e%wu%>?",
+ lhs_uhwi, rhs_uhwi, xor_result,
+ rhs_uhwi);
+ }
+ if (warned)
+ {
+ gcc_rich_location note_loc (lhs_loc);
+ if (lhs_uhwi == 2)
+ note_loc.add_fixit_replace (lhs_loc, "0x2");
+ else
+ {
+ gcc_assert (lhs_uhwi == 10);
+ note_loc.add_fixit_replace (lhs_loc, "0xa");
+ }
+ note_loc.fixits_cannot_be_auto_applied ();
+ inform (¬e_loc,
+ "you can silence this warning by using a hexadecimal constant"
+ " (%wx rather than %wd)",
+ lhs_uhwi, lhs_uhwi);
+ }
+}
C ObjC C++ ObjC++ Var(warn_write_strings) Warning
In C++, nonzero means warn about deprecated conversion from string literals to 'char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard.
+Wxor-used-as-pow
+C ObjC C++ ObjC++ Var(warn_xor_used_as_pow) Warning Init(1)
+Warn about xor operators where it appears the user meant exponentiation.
+
Wzero-as-null-pointer-constant
C++ ObjC++ Var(warn_zero_as_null_pointer_constant) Warning
Warn when a literal '0' is used as null pointer.
ret.original_code = STRING_CST;
ret.original_type = NULL_TREE;
set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
+ ret.m_decimal = 0;
parser->seen_string_literal = true;
return ret;
}
ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
code, exp_location, rhs.value,
rhs.original_type);
+ ret.m_decimal = 0;
set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
if (code == NOP_EXPR)
ret.original_code = MODIFY_EXPR;
: NULL);
}
set_c_expr_source_range (&ret, start, exp2.get_finish ());
+ ret.m_decimal = 0;
return ret;
}
TREE_OPERAND (t, 0) = stack[0].expr.value; \
TREE_OPERAND (t, 1) = stack[1].expr.value; \
stack[0].expr.value = t; \
+ stack[0].expr.m_decimal = 0; \
} \
else \
stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
ret.src_range.m_start = op_loc;
ret.src_range.m_finish = finish;
+ ret.m_decimal = 0;
return ret;
}
case CPP_PLUS:
result.value = boolean_false_node;
set_c_expr_source_range (&result, start, finish);
+ result.m_decimal = 0;
return result;
}
expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
c_parser_peek_token (parser)->value);
set_c_expr_source_range (&expr, loc, loc);
+ expr.m_decimal = 0;
c_parser_consume_token (parser);
return expr;
}
source_range tok_range = c_parser_peek_token (parser)->get_range ();
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
+ expr.m_decimal = 0;
switch (c_parser_peek_token (parser)->type)
{
case CPP_NUMBER:
expr.value = c_parser_peek_token (parser)->value;
set_c_expr_source_range (&expr, tok_range);
loc = c_parser_peek_token (parser)->location;
+ expr.m_decimal = c_parser_peek_token (parser)->flags & DECIMAL_INT;
c_parser_consume_token (parser);
if (TREE_CODE (expr.value) == FIXED_CST
&& !targetm.fixed_point_supported_p ())
etc), so we stash a copy here. */
source_range src_range;
+ /* True if this was directly from a decimal constant token. */
+ bool m_decimal : 1;
+
/* Access to the first and last locations within the source spelling
of this expression. */
location_t get_start () const { return src_range.m_start; }
struct c_expr arg1, struct c_expr arg2)
{
struct c_expr result;
+ result.m_decimal = 0;
enum tree_code code1 = arg1.original_code;
enum tree_code code2 = arg2.original_code;
"comparison between %qT and %qT",
type1, type2);
+ if (warn_xor_used_as_pow
+ && code == BIT_XOR_EXPR
+ && arg1.m_decimal
+ && arg2.m_decimal)
+ check_for_xor_used_as_pow (arg1.get_location (), arg1.value,
+ location,
+ arg2.value);
+
return result;
}
\f
{
public:
cp_expr () :
- m_value (NULL), m_loc (UNKNOWN_LOCATION) {}
+ m_value (NULL), m_loc (UNKNOWN_LOCATION),
+ m_decimal (false)
+ {}
cp_expr (tree value) :
- m_value (value), m_loc (cp_expr_location (m_value)) {}
+ m_value (value), m_loc (cp_expr_location (m_value)),
+ m_decimal (false)
+ {}
cp_expr (tree value, location_t loc):
- m_value (value), m_loc (loc)
+ m_value (value), m_loc (loc), m_decimal (false)
+ {
+ protected_set_expr_location (value, loc);
+ }
+
+ cp_expr (tree value, location_t loc, bool decimal):
+ m_value (value), m_loc (loc), m_decimal (decimal)
{
protected_set_expr_location (value, loc);
}
return *this;
}
+ bool decimal_p () const { return m_decimal; }
+
private:
tree m_value;
location_t m_loc;
+ bool m_decimal : 1;
};
inline bool
enum cp_parser_prec prec;
/* Location of the binary operation we are parsing. */
location_t loc;
+ /* Flags from the operator token. */
+ unsigned char flags;
};
/* The stack for storing partial expressions. We only need NUM_PREC_VALUES
if (!cast_p)
cp_parser_non_integral_constant_expression (parser, NIC_FLOAT);
}
- return (cp_expr (token->u.value, token->location)
+ return (cp_expr (token->u.value, token->location, token->flags & DECIMAL_INT)
.maybe_add_location_wrapper ());
case CPP_CHAR_USERDEF:
get_rhs:
current.tree_type = binops_by_token[token->type].tree_type;
current.loc = token->location;
+ current.flags = token->flags;
/* We used the operator token. */
cp_lexer_consume_token (parser->lexer);
warn_logical_not_parentheses (current.loc, current.tree_type,
current.lhs, maybe_constant_value (rhs));
+ if (warn_xor_used_as_pow
+ && current.tree_type == BIT_XOR_EXPR
+ /* Don't warn for named "xor" (as opposed to '^'). */
+ && !(current.flags & NAMED_OP)
+ && current.lhs.decimal_p ()
+ && rhs.decimal_p ())
+ check_for_xor_used_as_pow
+ (current.lhs.get_location (),
+ tree_strip_any_location_wrapper (current.lhs),
+ current.loc,
+ tree_strip_any_location_wrapper (rhs));
+
overload = NULL;
location_t combined_loc = make_location (current.loc,
-Wvector-operation-performance @gol
-Wvla -Wvla-larger-than=@var{byte-size} -Wno-vla-larger-than @gol
-Wvolatile-register-var -Wwrite-strings @gol
+-Wxor-used-as-pow @gol
-Wzero-length-bounds}
@item Static Analyzer Options
and/or writes to register variables. This warning is enabled by
@option{-Wall}.
+@item -Wxor-used-as-pow @r{(C, C++, Objective-C and Objective-C++ only)}
+@opindex Wxor-used-as-pow
+@opindex Wno-xor-used-as-pow
+Warn about uses of @code{^}, the exclusive or operator, where it appears
+the user meant exponentiation. Specifically, the warning occurs when the
+left-hand side is the decimal constant 2 or 10 and the right-hand side
+is also a decimal constant.
+
+In C and C++, @code{^} means exclusive or, whereas in some other languages
+(e.g. TeX and some versions of BASIC) it means exponentiation.
+
+This warning is enabled by default. It can be silenced by converting one
+of the operands to hexadecimal.
+
@item -Wdisabled-optimization
@opindex Wdisabled-optimization
@opindex Wno-disabled-optimization
--- /dev/null
+/* The precise output depends of sizeof(int) and sizeof(long long), so
+ filter by target. */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+
+/* Apparent uses of ^ for powers of 2. */
+
+short t2_16 = 2^16; /* { dg-warning "result of '2\\^16' is 18; did you mean '1 << 16' \\(65536\\)\\? \\\[-Wxor-used-as-pow\\\]" } */
+int t2_17 = 2^17; /* { dg-warning "result of '2\\^17' is 19; did you mean '1 << 17' \\(131072\\)\\?" } */
+int t2_30 = 2^30; /* { dg-warning "result of '2\\^30' is 28; did you mean '1 << 30' \\(1073741824\\)\\?" } */
+
+/* Should be 1LL at 31 and above, due to overflow. */
+int t2_31 = 2^31; /* { dg-warning "result of '2\\^31' is 29; did you mean '1LL << 31'\\?" } */
+int t2_32 = 2^32; /* { dg-warning "result of '2\\^32' is 34; did you mean '1LL << 32'\\?" } */
+
+long t2_63 = 2^63; /* { dg-warning "result of '2\\^63' is 61; did you mean exponentiation\\?" } */
+long t2_64 = 2^64; /* { dg-warning "result of '2\\^64' is 66; did you mean exponentiation\\?" } */
+
+/* ...but don't warn when RHS is large enough. */
+long t2_65 = 2^65;
+long t2_127 = 2^127;
+long t2_128 = 2^128;
+long t2_129 = 2^129;
+
+/* Verify that -Wxor-used-as-pow happens before folding. */
+long t2_32_m1 = ((2^32)-1); /* { dg-warning "result of '2\\^32' is 34; did you mean '1LL << 32'\\?" } */
+
+
+/* Apparent uses of ^ for powers of 10. */
+
+long t10_2 = 10^2; /* { dg-warning "result of '10\\^2' is 8; did you mean '1e2'\\?" } */
+long t10_9 = 10^9; /* { dg-warning "result of '10\\^9' is 3; did you mean '1e9'\\?" } */
+long t10_10 = 10^10; /* { dg-warning "result of '10\\^10' is 0; did you mean '1e10'\\?" } */
+long t10_100 = 10^100; /* { dg-warning "result of '10\\^100' is 110; did you mean '1e100'\\?" } */
+
+/* Don't warn on negatives. */
+long tm2_2 = -2^2;
+long t2_m2 = 2^-2;
+long tm10_10 = -10^10;
+long t10_m10 = 10^-10;
+
+/* If LHS is not 2 or 10, we shouldn't complain. */
+int t0_0 = 0 ^ 0;
+int t6_7 = 6 ^ 7;
+
+/* Floating point is already covered by type-checking. */
+float f10_10 = 10.f^10; /* { dg-error "invalid operands to binary \\^ \\(have 'float' and 'int'\\)" "" { target c } } */
+/* { dg-error "invalid operands of types 'float' and 'int' to binary 'operator\\^'" "" { target c++ } .-1 } */
+
+/* Don't complain if the LHS isn't literal decimal 2 or 10. */
+int t1p1_16 = (1 + 1) ^ 16;
+int t5p5_6 = (5 + 5) ^ 6;
+int h2_8 = 0x2 ^ 8;
+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;
--- /dev/null
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+/* Test fixit hints for -Wxor-used-as-pow. */
+
+int t2_8 = 2^8; /* { dg-line line_a } */
+/* { dg-warning "result of '2\\^8' is 10; did you mean '1 << 8' \\(256\\)\\?" "warn" { target *-*-* } line_a } */
+/* { dg-begin-multiline-output "" }
+ int t2_8 = 2^8;
+ ^
+ --
+ 1<<
+ { dg-end-multiline-output "" } */
+/* { dg-message "you can silence this warning by using a hexadecimal constant \\(0x2 rather than 2\\)" "note" { target *-*-* } line_a } */
+/* { dg-begin-multiline-output "" }
+ int t2_8 = 2^8;
+ ^
+ 0x2
+ { dg-end-multiline-output "" } */
+
+
+int t10_6 = 10^6; /* { dg-line line_b } */
+/* { dg-warning "result of '10\\^6' is 12; did you mean '1e6'\\?" "warn" { target *-*-* } line_b } */
+/* { dg-begin-multiline-output "" }
+ int t10_6 = 10^6;
+ ^
+ ---
+ 1e
+ { dg-end-multiline-output "" } */
+/* { dg-message "you can silence this warning by using a hexadecimal constant \\(0xa rather than 10\\)" "note" { target *-*-* } line_b } */
+/* { dg-begin-multiline-output "" }
+ int t10_6 = 10^6;
+ ^~
+ 0xa
+ { dg-end-multiline-output "" } */
test (||, &&, 1, 1, 0, 0)
test (&&, |, 5, 1, 1, 19)
-test (|, ^, 1, 2, 2, 1)
+test (|, ^, 1, 2, 0x2, 1)
test (^, &, 1, 3, 2, 6)
test (&, ==, 1, 3, 2, 0)
test (==, <, 2, 0, 0, 0)
foo (1 & (2 ^ c));
foo (1 & 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) ^ 3);
- foo (1 & (2 ^ 3));
+ foo (1 & (0x2 ^ 3));
foo (a ^ b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) & c);
foo (a ^ (b & c));
foo (1 + (2 ^ c));
foo (1 + 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) ^ 3);
- foo (1 + (2 ^ 3));
+ foo (1 + (0x2 ^ 3));
foo (a ^ b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) + c);
foo (a ^ (b + c));
foo (1 - (2 ^ c));
foo (1 - 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) ^ 3);
- foo (1 - (2 ^ 3));
+ foo (1 - (0x2 ^ 3));
foo (a ^ b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) - c);
foo (a ^ (b - c));
foo (1 >= (2 ^ c));
foo (1 >= 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 >= 2) ^ 3);
- foo (1 >= (2 ^ 3));
+ foo (1 >= (0x2 ^ 3));
foo (a ^ b >= c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) >= c);
foo (a ^ (b >= c));
foo (1 == (2 ^ c));
foo (1 == 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 == 2) ^ 3);
- foo (1 == (2 ^ 3));
+ foo (1 == (0x2 ^ 3));
foo (a ^ b == c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) == c);
foo (a ^ (b == c));
foo (1 < 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 < 2) ^ c);
foo (1 < (2 ^ c));
- foo (1 < 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
+ foo (1 < 0x2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 < 2) ^ 3);
- foo (1 < (2 ^ 3));
+ foo (1 < (0x2 ^ 3));
foo (a ^ b < c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) < c);
foo (a ^ (b < c));
foo (1 | 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) ^ c);
foo (1 | (2 ^ c));
- foo (1 | 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
+ foo (1 | 0x2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) ^ 3);
- foo (1 | (2 ^ 3));
+ foo (1 | (0x2 ^ 3));
foo (a + b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) | c);
foo (a + (b | c));
foo (1 & (2 ^ c));
foo (1 & 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) ^ 3);
- foo (1 & (2 ^ 3));
+ foo (1 & (0x2 ^ 3));
foo (a ^ b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) & c);
foo (a ^ (b & c));
foo (1 + (2 ^ c));
foo (1 + 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) ^ 3);
- foo (1 + (2 ^ 3));
+ foo (1 + (0x2 ^ 3));
foo (a ^ b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) + c);
foo (a ^ (b + c));
foo (1 - (2 ^ c));
foo (1 - 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) ^ 3);
- foo (1 - (2 ^ 3));
+ foo (1 - (0x2 ^ 3));
foo (a ^ b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) - c);
foo (a ^ (b - c));
foo (1 >= (2 ^ c));
foo (1 >= 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 >= 2) ^ 3);
- foo (1 >= (2 ^ 3));
+ foo (1 >= (0x2 ^ 3));
foo (a ^ b >= c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) >= c);
foo (a ^ (b >= c));
foo (1 == (2 ^ c));
foo (1 == 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 == 2) ^ 3);
- foo (1 == (2 ^ 3));
+ foo (1 == (0x2 ^ 3));
foo (a ^ b == c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) == c);
foo (a ^ (b == c));
foo (1 < (2 ^ c));
foo (1 < 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 < 2) ^ 3);
- foo (1 < (2 ^ 3));
+ foo (1 < (0x2 ^ 3));
foo (a ^ b < c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) < c);
foo (a ^ (b < c));
foo (1 | 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) ^ c);
foo (1 | (2 ^ c));
- foo (1 | 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
+ foo (1 | 0x2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) ^ 3);
- foo (1 | (2 ^ 3));
+ foo (1 | (0x2 ^ 3));
foo (a + b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) | c);
foo (a + (b | c));
--- /dev/null
+/* Verify that -Wxor-used-as-pow only warns with ^ and not with
+ named "xor". */
+
+int t2_16 = 2^16; /* { dg-warning "result of '2\\^16' is 18; did you mean '1 << 16' \\(65536\\)\\?" } */
+int t2x16 = 2 xor 16;
+
+int t10_6 = 10^6; /* { dg-warning "result of '10\\^6' is 12; did you mean '1e6'\\?" } */
+int t10x6 = 10 xor 6;
foo (1 | 2 ^ c); /* { dg-warning "parentheses" "correct warning" } */
foo ((1 | 2) ^ c);
foo (1 | (2 ^ c));
- foo (1 | 2 ^ 3); /* { dg-warning "parentheses" "correct warning" } */
+ foo (1 | 0x2 ^ 3); /* { dg-warning "parentheses" "correct warning" } */
foo ((1 | 2) ^ 3);
- foo (1 | (2 ^ 3));
+ foo (1 | (0x2 ^ 3));
foo (a + b | c); /* { dg-warning "parentheses" "correct warning" } */
foo ((a + b) | c);
foo (a + (b | c));
foo (1 & (2 ^ c));
foo (1 & 2 ^ 3); /* { dg-warning "parentheses" "correct warning" } */
foo ((1 & 2) ^ 3);
- foo (1 & (2 ^ 3));
+ foo (1 & (0x2 ^ 3));
foo (a ^ b & c); /* { dg-warning "parentheses" "correct warning" } */
foo ((a ^ b) & c);
foo (a ^ (b & c));
foo (1 + (2 ^ c));
foo (1 + 2 ^ 3); /* { dg-warning "parentheses" "correct warning" } */
foo ((1 + 2) ^ 3);
- foo (1 + (2 ^ 3));
+ foo (1 + (0x2 ^ 3));
foo (a ^ b + c); /* { dg-warning "parentheses" "correct warning" } */
foo ((a ^ b) + c);
foo (a ^ (b + c));
foo (1 - (2 ^ c));
foo (1 - 2 ^ 3); /* { dg-warning "parentheses" "correct warning" } */
foo ((1 - 2) ^ 3);
- foo (1 - (2 ^ 3));
+ foo (1 - (0x2 ^ 3));
foo (a ^ b - c); /* { dg-warning "parentheses" "correct warning" } */
foo ((a ^ b) - c);
foo (a ^ (b - c));
foo (1 >= (2 ^ c));
foo (1 >= 2 ^ 3); /* { dg-warning "parentheses" "correct warning" } */
foo ((1 >= 2) ^ 3);
- foo (1 >= (2 ^ 3));
+ foo (1 >= (0x2 ^ 3));
foo (a ^ b >= c); /* { dg-warning "parentheses" "correct warning" } */
foo ((a ^ b) >= c);
foo (a ^ (b >= c));
foo (1 == (2 ^ c));
foo (1 == 2 ^ 3); /* { dg-warning "parentheses" "correct warning" } */
foo ((1 == 2) ^ 3);
- foo (1 == (2 ^ 3));
+ foo (1 == (0x2 ^ 3));
foo (a ^ b == c); /* { dg-warning "parentheses" "correct warning" } */
foo ((a ^ b) == c);
foo (a ^ (b == c));
foo (1 < (2 ^ c));
foo (1 < 2 ^ 3); /* { dg-warning "parentheses" "correct warning" } */
foo ((1 < 2) ^ 3);
- foo (1 < (2 ^ 3));
+ foo (1 < (0x2 ^ 3));
foo (a ^ b < c); /* { dg-warning "parentheses" "correct warning" } */
foo ((a ^ b) < c);
foo (a ^ (b < c));
ASSERT_BIN (0, !=, 2, &, 1, 1, 1, 0);
ASSERT_BIN (1, &, 2, ==, 0, 0, 1, 0);
ASSERT_BIN (1, &, 2, !=, 0, 1, 0, 1);
- ASSERT_BIN (1, &, 2, ^, 3, 3, 3, 1);
+ ASSERT_BIN (1, &, 0x2, ^, 3, 3, 3, 1);
ASSERT_BIN (3, ^, 2, &, 1, 3, 1, 3);
ASSERT_BIN (3, ^, 2, |, 1, 1, 1, 0);
- ASSERT_BIN (3, |, 2, ^, 1, 3, 2, 3);
+ ASSERT_BIN (3, |, 0x2, ^, 1, 3, 2, 3);
ASSERT_BIN (2, |, 0, &&, 2, 1, 1, 2);
ASSERT_BIN (2, &&, 0, |, 2, 1, 2, 1);
ASSERT_BIN (0, &&, 0, ||, 1, 1, 1, 0);
#define NAMED_OP (1 << 4) /* C++ named operators. */
#define PREV_FALLTHROUGH (1 << 5) /* On a token preceeded by FALLTHROUGH
comment. */
-#define BOL (1 << 6) /* Token at beginning of line. */
+#define DECIMAL_INT (1 << 6) /* Decimal integer, set in c-lex.cc. */
#define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend,
set in c-lex.cc. */
#define SP_DIGRAPH (1 << 8) /* # or ## token was a digraph. */
after a # operator. */
#define NO_EXPAND (1 << 10) /* Do not macro-expand this token. */
#define PRAGMA_OP (1 << 11) /* _Pragma token. */
+#define BOL (1 << 12) /* Token at beginning of line. */
/* Specify which field, if any, of the cpp_token union is used. */