Skip to content
Permalink
Browse files

C++: more location wrapper nodes (PR c++/43064, PR c++/43486)

This is v6 of the patch, as posted to:
  https://gcc.gnu.org/ml/gcc-patches/2018-12/msg01331.html


The C++ frontend gained various location wrapper nodes in r256448 (GCC 8).
That patch:
  https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00799.html
added wrapper nodes around all nodes with !CAN_HAVE_LOCATION_P for:

* arguments at callsites, and for

* typeid, alignof, sizeof, and offsetof.

This is a followup to that patch, adding many more location wrappers
to the C++ frontend.  It adds location wrappers for nodes with
!CAN_HAVE_LOCATION_P to:

* all literal nodes (in cp_parser_primary_expression)

* all id-expression nodes (in finish_id_expression), except within a
  decltype.

* all mem-initializer nodes within a mem-initializer-list
  (in cp_parser_mem_initializer)

However, the patch also adds some suppressions: regions in the parser
for which wrapper nodes will not be created:

* within a template-parameter-list or template-argument-list (in
  cp_parser_template_parameter_list and cp_parser_template_argument_list
  respectively), to avoid encoding the spelling location of the nodes
  in types.  For example, "array<10>" and "array<10>" are the same type,
  despite the fact that the two different "10" tokens are spelled in
  different locations in the source.

* within a gnu-style attribute (none of are handlers are set up to cope
  with location wrappers yet)

* within various OpenMP clauses

The patch enables various improvements to locations for bad
initializations, for -Wchar-subscripts, and enables various other
improvements in the followup patch.

For example, given the followup buggy mem-initializer:

class X {
  X() : bad(42),
        good(42)
  { }
  void* bad;
  int good;
};

previously, our diagnostic was on the final close parenthesis of the
mem-initializer-list, leaving it unclear where the problem is:

t.cc: In constructor 'X::X()':
t.cc:3:16: error: invalid conversion from 'int' to 'void*' [-fpermissive]
    3 |         good(42)
      |                ^
      |                |
      |                int

whereas with the patch we highlight which expression is bogus:

t.cc: In constructor 'X::X()':
t.cc:2:13: error: invalid conversion from 'int' to 'void*' [-fpermissive]
    2 |   X() : bad(42),
      |             ^~
      |             |
      |             int

Similarly, the diagnostic for this bogus initialization:

i.cc:1:44: error: initializer-string for array of chars is too long [-fpermissive]
    1 | char test[3][4] = { "ok", "too long", "ok" };
      |                                            ^

is improved by the patch so that it indicates which string is too long:

i.cc:1:27: error: initializer-string for array of chars is too long [-fpermissive]
    1 | char test[3][4] = { "ok", "too long", "ok" };
      |                           ^~~~~~~~~~


gcc/c-family/ChangeLog:
	PR c++/43064
	PR c++/43486
	* c-common.c (unsafe_conversion_p): Fold any location wrapper.
	(verify_tree): Handle location wrappers.
	(c_common_truthvalue_conversion): Strip any location wrapper.
	Handle CONST_DECL.
	(fold_offsetof): Strip any location wrapper.
	(complete_array_type): Likewise for initial_value.
	(convert_vector_to_array_for_subscript): Call fold_for_warn on the
	index before checking for INTEGER_CST.
	* c-pretty-print.c (c_pretty_printer::primary_expression): Don't
	print parentheses around location wrappers.
	* c-warn.c (warn_logical_operator): Call fold_for_warn on op_right
	before checking for INTEGER_CST.
	(warn_tautological_bitwise_comparison): Call
	tree_strip_any_location_wrapper on lhs, rhs, and bitop's operand
	before checking for INTEGER_CST.
	(readonly_error): Strip any location wrapper.
	(warn_array_subscript_with_type_char): Strip location wrappers
	before checking for INTEGER_CST.  Use the location of the index if
	available.

gcc/ChangeLog:
	PR c++/43064
	PR c++/43486
	* convert.c: Include "selftest.h".
	(preserve_any_location_wrapper): New function.
	(convert_to_pointer_maybe_fold): Update to handle location
	wrappers.
	(convert_to_real_maybe_fold): Likewise.
	(convert_to_integer_1): Strip expr when using TREE_OVERFLOW.
	Handle location wrappers when checking for INTEGER_CST.
	(convert_to_integer_maybe_fold): Update to handle location
	wrappers.
	(convert_to_complex_maybe_fold): Likewise.
	(selftest::test_convert_to_integer_maybe_fold): New functions.
	(selftest::convert_c_tests): New function.
	* convert.h (preserve_any_location_wrapper): New decl.
	* fold-const.c (size_binop_loc): Strip location wrappers when
	using TREE_OVERFLOW.
	(operand_equal_p): Strip any location wrappers.
	(integer_valued_real_p): Strip any location wrapper.
	* selftest-run-tests.c (selftest::run_tests): Call
	selftest::convert_c_tests.
	* selftest.h (selftest::convert_c_tests): New decl.
	* tree.c (build_complex): Assert that REAL and IMAG are constants.
	(integer_zerop): Look through location wrappers.
	(integer_onep): Likewise.
	(integer_each_onep): Likewise.
	(integer_all_onesp): Likewise.
	(integer_minus_onep): Likewise.
	(integer_pow2p): Likewise.
	(integer_nonzerop): Likewise.
	(integer_truep): Likewise.
	(fixed_zerop): Likewise.
	(real_zerop): Likewise.
	(real_onep): Likewise.
	(real_minus_onep): Likewise.
	(tree_int_cst_equal): Likewise.
	(simple_cst_equal): Treat location wrappers with non-equal source
	locations as being unequal.
	(uniform_integer_cst_p): Look through location wrappers.
	(maybe_wrap_with_location): Don't create wrappers if any
	auto_suppress_location_wrappers are active.
	(suppress_location_wrappers): New variable.
	(selftest::test_predicates): New test.
	(selftest::tree_c_tests): Call it.
	* tree.h (CONSTANT_CLASS_OR_WRAPPER_P): New macro.
	(suppress_location_wrappers): New decl.
	(class auto_suppress_location_wrappers): New class.

gcc/cp/ChangeLog:
	PR c++/43064
	PR c++/43486
	* call.c (build_conditional_expr_1): Strip location wrappers when
	checking for CONST_DECL.
	(conversion_null_warnings): Use location of "expr" if available.
	* class.c (fixed_type_or_null): Handle location wrappers.
	* constexpr.c (potential_constant_expression_1): Likewise.
	* cvt.c (ignore_overflows): Strip location wrappers when
	checking for INTEGER_CST, and re-wrap the result if present.
	(ocp_convert): Call fold_for_warn before checking for INTEGER_CST.
	* decl.c (reshape_init_r): Strip any location wrapper.
	(undeduced_auto_decl): Likewise.
	* expr.c (mark_discarded_use): Likewise for expr.
	* init.c (build_aggr_init): Likewise before checking init for
	DECL_P.
	(warn_placement_new_too_small): Call fold_for_warn on adj before
	checking for CONSTANT_CLASS_P, and on nelts.  Strip any location
	wrapper from op0 and on oper before checking for VAR_P.
	* parser.c (cp_parser_primary_expression): Call
	maybe_add_location_wrapper on numeric and string literals.
	(cp_parser_postfix_expression): Strip any location wrapper when
	checking for DECL_IS_BUILTIN_CONSTANT_P.
	(cp_parser_unary_expression): Ensure that folding of NEGATE_EXPR
	around a constant happens in the presence of location wrappers and
	returns a wrapped result.
	(cp_parser_has_attribute_expression): Strip any location wrapper
	from "oper".
	(cp_parser_binary_expression): Strip any location wrapper when
	checking for DECL_P on the lhs.
	(cp_parser_decltype): Strip any location wrapper from result of
	cp_parser_decltype_expr.
	(cp_parser_mem_initializer): Add location wrappers to the
	parenthesized expression list.
	(cp_parser_template_parameter_list): Don't create wrapper nodes
	within a template-parameter-list.
	(cp_parser_template_argument_list): Don't create wrapper nodes
	within a template-argument-list.
	(cp_parser_parameter_declaration): Strip location wrappers from
	default arguments.
	(cp_parser_gnu_attribute_list): Don't create wrapper nodes.
	(cp_parser_std_attribute_spec_seq): Likewise.
	(cp_parser_omp_all_clauses): Don't create wrapper nodes within
	OpenMP clauses.
	(cp_parser_omp_for_loop): Likewise.
	(cp_parser_omp_declare_reduction_exprs): Likewise.
	* pt.c (convert_nontype_argument_function): Strip location
	wrappers from fn_no_ptr before checking for FUNCTION_DECL.
	(tsubst_default_argument): Move note about which callsite led to
	instantiation to after the check_default_argument call.
	(do_auto_deduction): Likewise from init before checking for
	DECL_P.
	* semantics.c (force_paren_expr): Likewise from expr before
	checking for DECL_P.
	(finish_parenthesized_expr): Likewise from expr before
	checking for STRING_CST.
	(perform_koenig_lookup): Likewise from fn.
	(finish_call_expr): Likewise.
	(finish_id_expression): Rename to...
	(finish_id_expression_1): ...this, calling
	maybe_add_location_wrapper on the result.
	(capture_decltype): Use lookup_name_real rather than value_member
	when looking up decl within the capture-list.
	* tree.c (cp_stabilize_reference): Strip any location wrapper.
	(builtin_valid_in_constant_expr_p): Likewise.
	(strip_typedefs_expr): Strip any location wrapper before checking
	for decls or constants.
	(is_overloaded_fn): Likewise.
	(maybe_get_fns): Likewise.
	(selftest::test_lvalue_kind): Verify lvalue_p.
	* typeck.c (cxx_sizeof_expr): Strip any location wrapper.
	(cxx_alignof_expr): Likewise.
	(is_bitfield_expr_with_lowered_type): Handle location wrappers.
	(cp_build_array_ref): Call maybe_constant_value on "idx".
	(cp_build_binary_op): Strip location wrapper from first_arg before
	checking for PARM_DECL.  Likewise for op1 before checking for
	INTEGER_CST in two places.  Likewise for orig_op0 and orig_op1
	when checking for STRING_CST.
	(cp_build_addr_expr_1): Likewise for arg when checking for
	FUNCTION_DECL.
	(cp_build_modify_expr): Likewise for newrhs when checking for
	STRING_CST.
	(convert_for_assignment): Don't strip location wrappers when
	stripping NON_LVALUE_EXPR.
	(maybe_warn_about_returning_address_of_local): Strip location
	wrapper from whats_returned before checking for DECL_P.
	(can_do_nrvo_p): Strip location wrapper from retval.
	(treat_lvalue_as_rvalue_p): Likewise.
	(check_return_expr): Likewise.
	* typeck2.c (cxx_incomplete_type_diagnostic): Strip location
	wrapper from value before checking for VAR_P or PARM_DECL.
	(digest_init_r): Strip location wrapper from init.  When
	copying "init", also copy the wrapped node.

gcc/objc/ChangeLog:
	PR c++/43064
	PR c++/43486
	* objc-act.c (objc_maybe_build_component_ref): Strip any location
	wrapper before checking for UOBJC_SUPER_decl and self_decl.
	(objc_finish_message_expr): Strip any location wrapper.
	(gen_declaration): Strip location wrappers from "w".

gcc/testsuite/ChangeLog:
	PR c++/43064
	PR c++/43486
	* c-c++-common/pr51712.c (valid2): Mark xfail as passing on C++.
	* g++.dg/cpp0x/constexpr-47969.C: Update column of expected error.
	* g++.dg/cpp0x/constexpr-ex2.C: Likewise.
	* g++.dg/cpp0x/scoped_enum2.C: Likewise.
	* g++.dg/cpp1z/decomp48.C: Update expected location of warning
	for named local variables to use that of the local variable.
	* g++.dg/ext/vla1.C: Update column.
	* g++.dg/init/array43.C: Update expected column to be that of the
	initializer.
	* g++.dg/init/initializer-string-too-long.C: New test.
	* g++.dg/init/new44.C: Add "-ftrack-macro-expansion=0".
	* g++.dg/init/pr43064-1.C: New test.
	* g++.dg/init/pr43064-2.C: New test.
	* g++.dg/init/pr43064-3.C: New test.
	* g++.dg/other/fold1.C: Update column of expected error.
	* g++.dg/parse/crash36.C: Likewise.
	* g++.dg/plugin/diagnostic-test-expressions-1.C: Add negative
	integer and float expressions.
	* g++.dg/template/defarg6.C: Move expected error to the default
	argument; add expected message about where instantiated.
	* g++.dg/wrappers/Wparentheses.C: New test.
	* g++.old-deja/g++.bugs/900402_02.C: Update column of expected
	error.



git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@267272 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information...
dmalcolm
dmalcolm committed Dec 19, 2018
1 parent 43e4588 commit d582d14011fec247f203a49e79bdab05f56197b0
Showing with 1,309 additions and 214 deletions.
  1. +50 −0 gcc/ChangeLog
  2. +24 −0 gcc/c-family/ChangeLog
  3. +22 −0 gcc/c-family/c-common.c
  4. +8 −3 gcc/c-family/c-pretty-print.c
  5. +44 −27 gcc/c-family/c-warn.c
  6. +125 −10 gcc/convert.c
  7. +2 −0 gcc/convert.h
  8. +95 −0 gcc/cp/ChangeLog
  9. +6 −3 gcc/cp/call.c
  10. +8 −0 gcc/cp/class.c
  11. +11 −6 gcc/cp/constexpr.c
  12. +14 −8 gcc/cp/cvt.c
  13. +19 −14 gcc/cp/decl.c
  14. +2 −0 gcc/cp/expr.c
  15. +8 −1 gcc/cp/init.c
  16. +58 −17 gcc/cp/parser.c
  17. +6 −4 gcc/cp/pt.c
  18. +60 −25 gcc/cp/semantics.c
  19. +16 −0 gcc/cp/tree.c
  20. +69 −36 gcc/cp/typeck.c
  21. +36 −20 gcc/cp/typeck2.c
  22. +13 −4 gcc/fold-const.c
  23. +9 −0 gcc/objc/ChangeLog
  24. +11 −3 gcc/objc/objc-act.c
  25. +1 −0 gcc/selftest-run-tests.c
  26. +1 −0 gcc/selftest.h
  27. +28 −0 gcc/testsuite/ChangeLog
  28. +1 −1 gcc/testsuite/c-c++-common/pr51712.c
  29. +1 −1 gcc/testsuite/g++.dg/cpp0x/constexpr-47969.C
  30. +1 −1 gcc/testsuite/g++.dg/cpp0x/constexpr-ex2.C
  31. +1 −1 gcc/testsuite/g++.dg/cpp0x/scoped_enum2.C
  32. +4 −4 gcc/testsuite/g++.dg/cpp1z/decomp48.C
  33. +1 −1 gcc/testsuite/g++.dg/ext/vla1.C
  34. +1 −1 gcc/testsuite/g++.dg/init/array43.C
  35. +9 −0 gcc/testsuite/g++.dg/init/initializer-string-too-long.C
  36. +1 −0 gcc/testsuite/g++.dg/init/new44.C
  37. +37 −0 gcc/testsuite/g++.dg/init/pr43064-1.C
  38. +34 −0 gcc/testsuite/g++.dg/init/pr43064-2.C
  39. +32 −0 gcc/testsuite/g++.dg/init/pr43064-3.C
  40. +1 −1 gcc/testsuite/g++.dg/other/fold1.C
  41. +1 −1 gcc/testsuite/g++.dg/parse/crash36.C
  42. +14 −0 gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C
  43. +2 −4 gcc/testsuite/g++.dg/template/defarg6.C
  44. +10 −0 gcc/testsuite/g++.dg/wrappers/Wparentheses.C
  45. +4 −4 gcc/testsuite/g++.old-deja/g++.bugs/900402_02.C
  46. +389 −13 gcc/tree.c
  47. +19 −0 gcc/tree.h
@@ -1,3 +1,53 @@
2018-12-19 David Malcolm <dmalcolm@redhat.com>

PR c++/43064
PR c++/43486
* convert.c: Include "selftest.h".
(preserve_any_location_wrapper): New function.
(convert_to_pointer_maybe_fold): Update to handle location
wrappers.
(convert_to_real_maybe_fold): Likewise.
(convert_to_integer_1): Strip expr when using TREE_OVERFLOW.
Handle location wrappers when checking for INTEGER_CST.
(convert_to_integer_maybe_fold): Update to handle location
wrappers.
(convert_to_complex_maybe_fold): Likewise.
(selftest::test_convert_to_integer_maybe_fold): New functions.
(selftest::convert_c_tests): New function.
* convert.h (preserve_any_location_wrapper): New decl.
* fold-const.c (size_binop_loc): Strip location wrappers when
using TREE_OVERFLOW.
(operand_equal_p): Strip any location wrappers.
(integer_valued_real_p): Strip any location wrapper.
* selftest-run-tests.c (selftest::run_tests): Call
selftest::convert_c_tests.
* selftest.h (selftest::convert_c_tests): New decl.
* tree.c (build_complex): Assert that REAL and IMAG are constants.
(integer_zerop): Look through location wrappers.
(integer_onep): Likewise.
(integer_each_onep): Likewise.
(integer_all_onesp): Likewise.
(integer_minus_onep): Likewise.
(integer_pow2p): Likewise.
(integer_nonzerop): Likewise.
(integer_truep): Likewise.
(fixed_zerop): Likewise.
(real_zerop): Likewise.
(real_onep): Likewise.
(real_minus_onep): Likewise.
(tree_int_cst_equal): Likewise.
(simple_cst_equal): Treat location wrappers with non-equal source
locations as being unequal.
(uniform_integer_cst_p): Look through location wrappers.
(maybe_wrap_with_location): Don't create wrappers if any
auto_suppress_location_wrappers are active.
(suppress_location_wrappers): New variable.
(selftest::test_predicates): New test.
(selftest::tree_c_tests): Call it.
* tree.h (CONSTANT_CLASS_OR_WRAPPER_P): New macro.
(suppress_location_wrappers): New decl.
(class auto_suppress_location_wrappers): New class.

2018-12-19 Paul A. Clarke <pc@us.ibm.com>

* config/rs6000/tmmintrin.h (_mm_hadds_epi16): Vector lanes swapped.
@@ -1,3 +1,27 @@
2018-12-19 David Malcolm <dmalcolm@redhat.com>

PR c++/43064
PR c++/43486
* c-common.c (unsafe_conversion_p): Fold any location wrapper.
(verify_tree): Handle location wrappers.
(c_common_truthvalue_conversion): Strip any location wrapper.
Handle CONST_DECL.
(fold_offsetof): Strip any location wrapper.
(complete_array_type): Likewise for initial_value.
(convert_vector_to_array_for_subscript): Call fold_for_warn on the
index before checking for INTEGER_CST.
* c-pretty-print.c (c_pretty_printer::primary_expression): Don't
print parentheses around location wrappers.
* c-warn.c (warn_logical_operator): Call fold_for_warn on op_right
before checking for INTEGER_CST.
(warn_tautological_bitwise_comparison): Call
tree_strip_any_location_wrapper on lhs, rhs, and bitop's operand
before checking for INTEGER_CST.
(readonly_error): Strip any location wrapper.
(warn_array_subscript_with_type_char): Strip location wrappers
before checking for INTEGER_CST. Use the location of the index if
available.

2018-12-06 Jason Merrill <jason@redhat.com>

PR c++/88136 - -Wdeprecated-copy false positives
@@ -1250,6 +1250,8 @@ unsafe_conversion_p (location_t loc, tree type, tree expr, tree result,

loc = expansion_point_location_if_in_system_header (loc);

expr = fold_for_warn (expr);

if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST)
{
/* If type is complex, we are interested in compatibility with
@@ -1947,6 +1949,13 @@ verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp,
writer = 0;
goto restart;

case VIEW_CONVERT_EXPR:
if (location_wrapper_p (x))
{
x = TREE_OPERAND (x, 0);
goto restart;
}
gcc_fallthrough ();
default:
/* For other expressions, simply recurse on their operands.
Manual tail recursion for unary expressions.
@@ -3241,6 +3250,7 @@ decl_with_nonnull_addr_p (const_tree expr)
tree
c_common_truthvalue_conversion (location_t location, tree expr)
{
STRIP_ANY_LOCATION_WRAPPER (expr);
switch (TREE_CODE (expr))
{
case EQ_EXPR: case NE_EXPR: case UNEQ_EXPR: case LTGT_EXPR:
@@ -3460,6 +3470,14 @@ c_common_truthvalue_conversion (location_t location, tree expr)
}
break;

case CONST_DECL:
{
tree folded_expr = fold_for_warn (expr);
if (folded_expr != expr)
return c_common_truthvalue_conversion (location, folded_expr);
}
break;

default:
break;
}
@@ -6279,6 +6297,7 @@ fold_offsetof (tree expr, tree type, enum tree_code ctx)
return base;

t = TREE_OPERAND (expr, 1);
STRIP_ANY_LOCATION_WRAPPER (t);

/* Check if the offset goes beyond the upper bound of the array. */
if (TREE_CODE (t) == INTEGER_CST && tree_int_cst_sgn (t) >= 0)
@@ -6357,6 +6376,8 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
maxindex = size_zero_node;
if (initial_value)
{
STRIP_ANY_LOCATION_WRAPPER (initial_value);

if (TREE_CODE (initial_value) == STRING_CST)
{
int eltsize
@@ -7906,6 +7927,7 @@ convert_vector_to_array_for_subscript (location_t loc,

ret = !lvalue_p (*vecp);

index = fold_for_warn (index);
if (TREE_CODE (index) == INTEGER_CST)
if (!tree_fits_uhwi_p (index)
|| maybe_ge (tree_to_uhwi (index), TYPE_VECTOR_SUBPARTS (type)))
@@ -1260,9 +1260,14 @@ c_pretty_printer::primary_expression (tree e)

default:
/* FIXME: Make sure we won't get into an infinite loop. */
pp_c_left_paren (this);
expression (e);
pp_c_right_paren (this);
if (location_wrapper_p (e))
expression (e);
else
{
pp_c_left_paren (this);
expression (e);
pp_c_right_paren (this);
}
break;
}
}
@@ -208,19 +208,22 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
if (!truth_value_p (code_left)
&& INTEGRAL_TYPE_P (TREE_TYPE (op_left))
&& !CONSTANT_CLASS_P (op_left)
&& !TREE_NO_WARNING (op_left)
&& TREE_CODE (op_right) == INTEGER_CST
&& !integer_zerop (op_right)
&& !integer_onep (op_right))
&& !TREE_NO_WARNING (op_left))
{
if (or_op)
warning_at (location, OPT_Wlogical_op, "logical %<or%>"
" applied to non-boolean constant");
else
warning_at (location, OPT_Wlogical_op, "logical %<and%>"
" applied to non-boolean constant");
TREE_NO_WARNING (op_left) = true;
return;
tree folded_op_right = fold_for_warn (op_right);
if (TREE_CODE (folded_op_right) == INTEGER_CST
&& !integer_zerop (folded_op_right)
&& !integer_onep (folded_op_right))
{
if (or_op)
warning_at (location, OPT_Wlogical_op, "logical %<or%>"
" applied to non-boolean constant");
else
warning_at (location, OPT_Wlogical_op, "logical %<and%>"
" applied to non-boolean constant");
TREE_NO_WARNING (op_left) = true;
return;
}
}

/* We do not warn for constants because they are typical of macro
@@ -340,24 +343,30 @@ warn_tautological_bitwise_comparison (location_t loc, tree_code code,
/* Extract the operands from e.g. (x & 8) == 4. */
tree bitop;
tree cst;
tree stripped_lhs = tree_strip_any_location_wrapper (lhs);
tree stripped_rhs = tree_strip_any_location_wrapper (rhs);
if ((TREE_CODE (lhs) == BIT_AND_EXPR
|| TREE_CODE (lhs) == BIT_IOR_EXPR)
&& TREE_CODE (rhs) == INTEGER_CST)
bitop = lhs, cst = rhs;
&& TREE_CODE (stripped_rhs) == INTEGER_CST)
bitop = lhs, cst = stripped_rhs;
else if ((TREE_CODE (rhs) == BIT_AND_EXPR
|| TREE_CODE (rhs) == BIT_IOR_EXPR)
&& TREE_CODE (lhs) == INTEGER_CST)
bitop = rhs, cst = lhs;
&& TREE_CODE (stripped_lhs) == INTEGER_CST)
bitop = rhs, cst = stripped_lhs;
else
return;

tree bitopcst;
if (TREE_CODE (TREE_OPERAND (bitop, 0)) == INTEGER_CST)
bitopcst = TREE_OPERAND (bitop, 0);
else if (TREE_CODE (TREE_OPERAND (bitop, 1)) == INTEGER_CST)
bitopcst = TREE_OPERAND (bitop, 1);
else
return;
tree bitop_op0 = fold_for_warn (TREE_OPERAND (bitop, 0));
if (TREE_CODE (bitop_op0) == INTEGER_CST)
bitopcst = bitop_op0;
else {
tree bitop_op1 = fold_for_warn (TREE_OPERAND (bitop, 1));
if (TREE_CODE (bitop_op1) == INTEGER_CST)
bitopcst = bitop_op1;
else
return;
}

/* Note that the two operands are from before the usual integer
conversions, so their types might not be the same.
@@ -1529,6 +1538,7 @@ readonly_error (location_t loc, tree arg, enum lvalue_use use)
{
gcc_assert (use == lv_assign || use == lv_increment || use == lv_decrement
|| use == lv_asm);
STRIP_ANY_LOCATION_WRAPPER (arg);
/* Using this macro rather than (for example) arrays of messages
ensures that all the format strings are checked at compile
time. */
@@ -1669,15 +1679,22 @@ invalid_indirection_error (location_t loc, tree type, ref_operator errstring)
warn for unsigned char since that type is safe. Don't warn for
signed char because anyone who uses that must have done so
deliberately. Furthermore, we reduce the false positive load by
warning only for non-constant value of type char. */
warning only for non-constant value of type char.
LOC is the location of the subscripting expression. */

void
warn_array_subscript_with_type_char (location_t loc, tree index)
{
if (TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node
&& TREE_CODE (index) != INTEGER_CST)
warning_at (loc, OPT_Wchar_subscripts,
"array subscript has type %<char%>");
if (TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
{
/* If INDEX has a location, use it; otherwise use LOC (the location
of the subscripting expression as a whole). */
loc = EXPR_LOC_OR_LOC (index, loc);
STRIP_ANY_LOCATION_WRAPPER (index);
if (TREE_CODE (index) != INTEGER_CST)
warning_at (loc, OPT_Wchar_subscripts,
"array subscript has type %<char%>");
}
}

/* Implement -Wparentheses for the unexpected C precedence rules, to
Oops, something went wrong.

0 comments on commit d582d14

Please sign in to comment.
You can’t perform that action at this time.