Skip to content

Commit

Permalink
d: Fix accesses of immutable arrays using constant index still bounds…
Browse files Browse the repository at this point in the history
… checked

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.
  • Loading branch information
ibuclaw committed Jul 1, 2023
1 parent fca6d9c commit 61b1c56
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 0 deletions.
14 changes: 14 additions & 0 deletions gcc/d/decl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,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. */
Expand Down
4 changes: 4 additions & 0 deletions gcc/d/expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2701,6 +2701,10 @@ class ExprVisitor : public Visitor
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);
}
Expand Down
9 changes: 9 additions & 0 deletions gcc/testsuite/gdc.dg/pr110514a.d
Original file line number Diff line number Diff line change
@@ -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 } }
8 changes: 8 additions & 0 deletions gcc/testsuite/gdc.dg/pr110514b.d
Original file line number Diff line number Diff line change
@@ -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" } }
8 changes: 8 additions & 0 deletions gcc/testsuite/gdc.dg/pr110514c.d
Original file line number Diff line number Diff line change
@@ -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" } }
8 changes: 8 additions & 0 deletions gcc/testsuite/gdc.dg/pr110514d.d
Original file line number Diff line number Diff line change
@@ -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" } }

0 comments on commit 61b1c56

Please sign in to comment.