diff --git a/src/dmd/dstruct.d b/src/dmd/dstruct.d index e61e866f07b3..227074f44ff2 100644 --- a/src/dmd/dstruct.d +++ b/src/dmd/dstruct.d @@ -479,6 +479,19 @@ extern (C++) class StructDeclaration : AggregateDeclaration Type origType = t; Type tb = t.toBasetype(); + const hasPointers = tb.hasPointers(); + if (hasPointers) + { + if ((stype.alignment() < Target.ptrsize || + (v.offset & (Target.ptrsize - 1))) && + sc.func.setUnsafe()) + { + .error(loc, "field `%s.%s` cannot assign to misaligned pointers in `@safe` code", + toChars(), v.toChars()); + return false; + } + } + /* Look for case of initializing a static array with a too-short * string literal, such as: * char[5] foo = "abc"; diff --git a/src/dmd/initsem.d b/src/dmd/initsem.d index 29bced0aae5a..48c99cc76748 100644 --- a/src/dmd/initsem.d +++ b/src/dmd/initsem.d @@ -33,6 +33,7 @@ import dmd.identifier; import dmd.init; import dmd.mtype; import dmd.statement; +import dmd.target; import dmd.tokens; import dmd.visitor; @@ -187,6 +188,17 @@ private extern(C++) final class InitializerSemanticVisitor : Visitor errors = true; continue; } + if (vd.type.hasPointers) + { + if ((t.alignment() < Target.ptrsize || + (vd.offset & (Target.ptrsize - 1))) && + sc.func.setUnsafe()) + { + error(i.loc, "field `%s.%s` cannot assign to misaligned pointers in `@safe` code", + sd.toChars(), vd.toChars()); + errors = true; + } + } for (size_t k = 0; k < nfields; k++) { VarDeclaration v2 = sd.fields[k]; diff --git a/test/fail_compilation/test18597.d b/test/fail_compilation/test18597.d new file mode 100644 index 000000000000..66cde58e047b --- /dev/null +++ b/test/fail_compilation/test18597.d @@ -0,0 +1,27 @@ +/* TEST_OUTPUT: +--- +fail_compilation/test18597.d(24): Error: field `Unaligned.p` cannot modify misaligned pointers in `@safe` code +fail_compilation/test18597.d(25): Error: field `Unaligned.p` cannot assign to misaligned pointers in `@safe` code +fail_compilation/test18597.d(26): Error: field `Unaligned.p` cannot assign to misaligned pointers in `@safe` code +--- +*/ + +// https://issues.dlang.org/show_bug.cgi?id=18597 + +@safe: + +align(1) +struct Unaligned +{ +align(1): + ubyte filler; + int* p; +} + +void test() +{ + Unaligned u; + u.p = new int; + Unaligned v = Unaligned(0, new int); + Unaligned w = { p : new int }; +}