middle-end/103038 - avoid ICE with -ftrivial-auto-var-init=pattern
authorRichard Biener <rguenther@suse.de>
Tue, 2 Nov 2021 08:58:00 +0000 (09:58 +0100)
committerRichard Biener <rguenther@suse.de>
Tue, 2 Nov 2021 13:17:08 +0000 (14:17 +0100)
This avoids ICEing with expanding a VIEW_CONVERT_EXRP of a SSA name
on the LHS by making sure we can native-interpret OFFSET_TYPE and
by never building such a LHS but instead view-converting the RHS
for SSA LHS.

2021-11-02  Richard Biener  <rguenther@suse.de>

PR middle-end/103038
* fold-const.c (native_interpret_expr): Handle OFFSET_TYPE.
(can_native_interpret_type_p): Likewise.
* internal-fn.c (expand_DEFERRED_INIT): View-convert the
RHS if the LHS is an SSA name.

* g++.dg/pr103038.C: New testcase.

gcc/fold-const.c
gcc/internal-fn.c
gcc/testsuite/g++.dg/pr103038.C [new file with mode: 0644]

index 54f91f0..2d3ba07 100644 (file)
@@ -8791,6 +8791,7 @@ native_interpret_expr (tree type, const unsigned char *ptr, int len)
     case BOOLEAN_TYPE:
     case POINTER_TYPE:
     case REFERENCE_TYPE:
+    case OFFSET_TYPE:
       return native_interpret_int (type, ptr, len);
 
     case REAL_TYPE:
@@ -8827,6 +8828,7 @@ can_native_interpret_type_p (tree type)
     case REAL_TYPE:
     case COMPLEX_TYPE:
     case VECTOR_TYPE:
+    case OFFSET_TYPE:
       return true;
     default:
       return false;
index 9e10da0..fd6cb09 100644 (file)
@@ -3090,8 +3090,12 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt)
                             (total_bytes * BITS_PER_UNIT, 1);
              wide_int w = wi::from_buffer (buf, total_bytes);
              init = wide_int_to_tree (itype, w);
-             /* Pun the LHS to make sure its type has constant size.  */
-             lhs = build1 (VIEW_CONVERT_EXPR, itype, lhs);
+             /* Pun the LHS to make sure its type has constant size
+                unless it is an SSA name where that's already known.  */
+             if (TREE_CODE (lhs) != SSA_NAME)
+               lhs = build1 (VIEW_CONVERT_EXPR, itype, lhs);
+             else
+               init = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), init);
            }
        }
       else
diff --git a/gcc/testsuite/g++.dg/pr103038.C b/gcc/testsuite/g++.dg/pr103038.C
new file mode 100644 (file)
index 0000000..bb7183a
--- /dev/null
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern" } */
+
+struct S;
+void test() { int(S::*PtrMem); }