Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/src/dmd/backend/cc.d
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,7 @@ enum
Fnothrow = 0x10000, // function does not throw (even if not marked 'nothrow')
Feh_none = 0x20000, // ehmethod==EH_NONE for this function only
F3hiddenPtr = 0x40000, // function has hidden pointer to return value
F3safe = 0x80000, // function is @safe
}

struct func_t
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dmd/backend/gdag.d
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ private void aewalk(elem **pn,vec_t ae)
{
assert(t.Eoper == OPvar);
Symbol* s = t.EV.Vsym;
if (!(s.Sflags & SFLunambig))
if (Symbol_isAffected(*s))
vec_subass(ae,go.starkill);
for (uint i = 0; (i = cast(uint) vec_index(i, ae)) < go.exptop; ++i) // for each ae elem
{
Expand Down Expand Up @@ -821,7 +821,7 @@ private void abewalk(elem *n,vec_t ae,vec_t aeval)

assert(t.Eoper == OPvar);
s = t.EV.Vsym;
if (!(s.Sflags & SFLunambig))
if (Symbol_isAffected(*s))
vec_subass(ae,go.starkill);
for (uint i = 0; (i = cast(uint) vec_index(i, ae)) < go.exptop; ++i) // for each ae elem
{
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/dmd/backend/gother.d
Original file line number Diff line number Diff line change
Expand Up @@ -1255,18 +1255,19 @@ private bool copyPropWalk(elem *n,vec_t IN)
v = go.expnod[i].EV.E1.EV.Vsym;
if (ambig)
{
if (!(v.Sflags & SFLunambig))
if (Symbol_isAffected(*v))
goto clr;
}
else
{
if (v == t.EV.Vsym)
goto clr;
}

v = go.expnod[i].EV.E2.EV.Vsym;
if (ambig)
{
if (!(v.Sflags & SFLunambig))
if (Symbol_isAffected(*v))
goto clr;
}
else
Expand Down
13 changes: 10 additions & 3 deletions compiler/src/dmd/backend/symbol.d
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,17 @@ bool Symbol_isAffected(const ref Symbol s)
* 4. Const can be mutated by a separate view.
* Address this in a separate PR.
*/
if (0 &&
s.ty() & (mTYconst | mTYimmutable))
static if (0)
if (s.ty() & (mTYconst | mTYimmutable))
{
return false;
/* Disabled for the moment because even @safe functions
* may have inlined unsafe code from other functions
*/
if (funcsym_p.Sfunc.Fflags3 & F3safe &&
s.ty() & mTYimmutable)
{
return false;
}
}
return true;
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/src/dmd/tocsym.d
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,9 @@ Symbol *toSymbol(Dsymbol s)
else if (fd.isMember2() && fd.isStatic())
f.Fflags |= Fstatic;

if (fd.isSafe())
f.Fflags3 |= F3safe;

if (fd.inlining == PINLINE.default_ && global.params.useInline ||
fd.inlining == PINLINE.always)
{
Expand Down
32 changes: 32 additions & 0 deletions test/runnable/test21821.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// REQUIRED_ARGS: -preview=fieldwise -O
// https://issues.dlang.org/show_bug.cgi?id=21821

// test case comes from unittests in core.lifetime

void test()
{
alias T = immutable(S);
T source;
T target;
copyEmplacex(source, target);
T expectedCopy = source;
assert(target == expectedCopy);
}

struct S
{
int x = 42;
this(this) { x += 10; }
}

void copyEmplacex(ref immutable(S) source, ref immutable(S) target) @system
{
import core.stdc.string : memcpy;
memcpy(cast(S*) &target, cast(S*) &source, S.sizeof);
(cast() target).__xpostblit(); // casting away immutable
}

void main()
{
test();
}