]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
d: Fix accesses of immutable arrays using constant index still bounds checked
authorIain Buclaw <ibuclaw@gdcproject.org>
Sat, 1 Jul 2023 21:32:53 +0000 (23:32 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Sat, 1 Jul 2023 23:20:08 +0000 (01:20 +0200)
Starts setting TREE_READONLY against specific kinds of VAR_DECLs, so
that the middle-end/optimization passes can more aggressively constant
fold D code that makes use of `immutable' or `const'.

PR d/110514

gcc/d/ChangeLog:

* decl.cc (get_symbol_decl): Set TREE_READONLY on certain kinds of
const and immutable variables.
* expr.cc (ExprVisitor::visit (ArrayLiteralExp *)): Set TREE_READONLY
on immutable dynamic array literals.

gcc/testsuite/ChangeLog:

* gdc.dg/pr110514a.d: New test.
* gdc.dg/pr110514b.d: New test.
* gdc.dg/pr110514c.d: New test.
* gdc.dg/pr110514d.d: New test.

(cherry picked from commit 61b1c562f8c703bff045e91257120e42b7fae523)

gcc/d/decl.cc
gcc/d/expr.cc
gcc/testsuite/gdc.dg/pr110514a.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/pr110514b.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/pr110514c.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/pr110514d.d [new file with mode: 0644]

index 1cdfc24666eeaaeb1393815e67bc9052caeb4ef2..de1dfd14189b3ffd026d845a510cfe248bdefcad 100644 (file)
@@ -1264,6 +1264,20 @@ get_symbol_decl (Declaration *decl)
                DECL_INITIAL (decl->csym) = build_expr (ie, true);
            }
        }
+
+      /* [type-qualifiers/const-and-immutable]
+
+        `immutable` applies to data that cannot change. Immutable data values,
+        once constructed, remain the same for the duration of the program's
+        execution.  */
+      if (vd->isImmutable () && !vd->setInCtorOnly ())
+       TREE_READONLY (decl->csym) = 1;
+
+      /* `const` applies to data that cannot be changed by the const reference
+        to that data. It may, however, be changed by another reference to that
+        same data.  */
+      if (vd->isConst () && !vd->isDataseg ())
+       TREE_READONLY (decl->csym) = 1;
     }
 
   /* Set the declaration mangled identifier if static.  */
index 6654244292efd3d357e47bfc38d4cb36a707c0d9..46d94f81fa20fb40942f7a5ac02064b6ff374968 100644 (file)
@@ -2708,6 +2708,10 @@ public:
            if (tb->ty == TY::Tarray)
              ctor = d_array_value (type, size_int (e->elements->length), ctor);
 
+           /* Immutable literals can be placed in rodata.  */
+           if (tb->isImmutable ())
+             TREE_READONLY (decl) = 1;
+
            d_pushdecl (decl);
            rest_of_decl_compilation (decl, 1, 0);
          }
diff --git a/gcc/testsuite/gdc.dg/pr110514a.d b/gcc/testsuite/gdc.dg/pr110514a.d
new file mode 100644 (file)
index 0000000..46e3705
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-do "compile" }
+// { dg-options "-O -fdump-tree-optimized" }
+immutable uint[] imm_arr = [1,2,3];
+int test_imm(immutable uint[] ptr)
+{
+    return imm_arr[2] == 3 ? 123 : 456;
+}
+// { dg-final { scan-assembler-not "_d_arraybounds_indexp" } }
+// { dg-final { scan-tree-dump "return 123;" optimized } }
diff --git a/gcc/testsuite/gdc.dg/pr110514b.d b/gcc/testsuite/gdc.dg/pr110514b.d
new file mode 100644 (file)
index 0000000..86aeb48
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-do "compile" }
+// { dg-options "-O" }
+immutable uint[] imm_ctor_arr;
+int test_imm_ctor(immutable uint[] ptr)
+{
+    return imm_ctor_arr[2] == 3;
+}
+// { dg-final { scan-assembler "_d_arraybounds_indexp" } }
diff --git a/gcc/testsuite/gdc.dg/pr110514c.d b/gcc/testsuite/gdc.dg/pr110514c.d
new file mode 100644 (file)
index 0000000..94779e1
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-do "compile" }
+// { dg-options "-O" }
+const uint[] cst_arr = [1,2,3];
+int test_cst(const uint[] ptr)
+{
+    return cst_arr[2] == 3;
+}
+// { dg-final { scan-assembler "_d_arraybounds_indexp" } }
diff --git a/gcc/testsuite/gdc.dg/pr110514d.d b/gcc/testsuite/gdc.dg/pr110514d.d
new file mode 100644 (file)
index 0000000..56e9a31
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-do "compile" }
+// { dg-options "-O" }
+const uint[] cst_ctor_arr;
+int test_cst_ctor(const uint[] ptr)
+{
+    return cst_ctor_arr[2] == 3;
+}
+// { dg-final { scan-assembler "_d_arraybounds_indexp" } }