diff options
author | Richard Biener <rguenther@suse.de> | 2024-07-18 13:35:33 +0200 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2024-07-18 14:53:31 +0200 |
commit | 3670c70c561656a19f6bff36dd229f18120af127 (patch) | |
tree | 993c6a499893fc9540627b724a58e514109ae31e /gcc/fold-const.cc | |
parent | ebac11afbcb7a52536da5f04fc524b870f5d76e0 (diff) | |
download | gcc-3670c70c561656a19f6bff36dd229f18120af127.zip gcc-3670c70c561656a19f6bff36dd229f18120af127.tar.gz gcc-3670c70c561656a19f6bff36dd229f18120af127.tar.bz2 |
middle-end/115641 - invalid address construction
fold_truth_andor_1 via make_bit_field_ref builds an address of
a CALL_EXPR which isn't valid GENERIC and later causes an ICE.
The following simply avoids the folding for f ().a != 1 || f ().b != 2
as it is a premature optimization anyway. The alternative would
have been to build a TARGET_EXPR around the call. To get this far
f () has to be const as otherwise the two calls are not semantically
equivalent for the optimization.
PR middle-end/115641
* fold-const.cc (decode_field_reference): If the inner
reference isn't something we can take the address of, fail.
* gcc.dg/torture/pr115641.c: New testcase.
Diffstat (limited to 'gcc/fold-const.cc')
-rw-r--r-- | gcc/fold-const.cc | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 710d697..6179a09 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -5003,6 +5003,9 @@ decode_field_reference (location_t loc, tree *exp_, HOST_WIDE_INT *pbitsize, || *pbitsize < 0 || offset != 0 || TREE_CODE (inner) == PLACEHOLDER_EXPR + /* We eventually want to build a larger reference and need to take + the address of this. */ + || (!REFERENCE_CLASS_P (inner) && !DECL_P (inner)) /* Reject out-of-bound accesses (PR79731). */ || (! AGGREGATE_TYPE_P (TREE_TYPE (inner)) && compare_tree_int (TYPE_SIZE (TREE_TYPE (inner)), |