diff mbox series

middle-end/115641 - invalid address construction

Message ID 20240718125340.0B8D1385F009@sourceware.org
State New
Headers show
Series middle-end/115641 - invalid address construction | expand

Commit Message

Richard Biener July 18, 2024, 12:53 p.m. UTC
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.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	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.
---
 gcc/fold-const.cc                       |  3 +++
 gcc/testsuite/gcc.dg/torture/pr115641.c | 29 +++++++++++++++++++++++++
 2 files changed, 32 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr115641.c
diff mbox series

Patch

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index fbc24a41427..400449c3617 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 00000000000..65fb09ca64f
--- /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;
+}