aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-07-18 13:35:33 +0200
committerRichard Biener <rguenth@gcc.gnu.org>2024-07-18 14:53:31 +0200
commit3670c70c561656a19f6bff36dd229f18120af127 (patch)
tree993c6a499893fc9540627b724a58e514109ae31e /gcc
parentebac11afbcb7a52536da5f04fc524b870f5d76e0 (diff)
downloadgcc-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')
-rw-r--r--gcc/fold-const.cc3
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr115641.c29
2 files changed, 32 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)),
diff --git a/gcc/testsuite/gcc.dg/torture/pr115641.c b/gcc/testsuite/gcc.dg/torture/pr115641.c
new file mode 100644
index 0000000..65fb09c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr115641.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+typedef struct {
+ char hours, day, month;
+ short year;
+} T;
+
+T g (void)
+{
+ T now;
+ now.hours = 1;
+ now.day = 2;
+ now.month = 3;
+ now.year = 4;
+ return now;
+}
+
+__attribute__((const)) T f (void)
+{
+ T virk = g ();
+ return virk;
+}
+
+int main ()
+{
+ if (f ().hours != 1 || f ().day != 2 || f ().month != 3 || f ().year != 4)
+ __builtin_abort ();
+ return 0;
+}