]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c: Handle REALPART_EXPR and IMAGPART_EXPR in fold_offsetof [PR105555]
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Thu, 12 Feb 2026 17:07:10 +0000 (09:07 -0800)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Thu, 12 Feb 2026 23:23:37 +0000 (15:23 -0800)
In some cases the C front-end calls into fold_offsetof to fold
an address but that does not handle REALPART_EXPR nor IMAGPART_EXPR so
gcc produces an internal compiler error. For offsetof, REALPART_EXPR/IMAGPART_EXPR
won't show up which is why they were not there before.

Bootstrapped and tested on x86_64-linux-gnu.

PR c/105555

gcc/c-family/ChangeLog:

* c-common.cc (fold_offsetof): Handle REALPART_EXPR
and IMAGPART_EXPR.

gcc/testsuite/ChangeLog:

* gcc.dg/complex-10.c: New test.

Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
gcc/c-family/c-common.cc
gcc/testsuite/gcc.dg/complex-10.c [new file with mode: 0644]

index 22d51162d9bb506ed203486f334b09449a5b5333..5acb221d31f35f6b822ea1256949748270eaa67c 100644 (file)
@@ -7232,6 +7232,16 @@ fold_offsetof (tree expr, tree type, enum tree_code ctx)
     case ERROR_MARK:
       return expr;
 
+    case REALPART_EXPR:
+     return fold_offsetof (TREE_OPERAND (expr, 0), type, code);
+
+    case IMAGPART_EXPR:
+     base = fold_offsetof (TREE_OPERAND (expr, 0), type, code);
+     if (base == error_mark_node)
+       return base;
+     off = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (expr, 0))));
+     break;
+
     case VAR_DECL:
       error ("cannot apply %<offsetof%> to static data member %qD", expr);
       return error_mark_node;
diff --git a/gcc/testsuite/gcc.dg/complex-10.c b/gcc/testsuite/gcc.dg/complex-10.c
new file mode 100644 (file)
index 0000000..b27f91f
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+/* PR c/105555 */
+
+struct C {
+  __complex int i;
+};
+struct C p[10];
+int *foo1(void) {
+  return &__real(p->i);
+}
+
+int *foo2(void) {
+  return &__imag(p->i);
+}