diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index bd04d429f257..675ef10f43d5 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -13185,7 +13185,9 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false) // Error by default bool visit(Expression e) { - if (e.type.isShared()) + // https://issues.dlang.org/show_bug.cgi?id=23639 + // Should be able to cast(shared) + if (!e.isCastExp() && e.type.isShared()) return sharedError(e); return false; } diff --git a/compiler/test/compilable/test23639.d b/compiler/test/compilable/test23639.d new file mode 100644 index 000000000000..e2ec002c8480 --- /dev/null +++ b/compiler/test/compilable/test23639.d @@ -0,0 +1,12 @@ +// https://issues.dlang.org/show_bug.cgi?id=23639 + +// REQUIRED_ARGS: -preview=nosharedaccess + +class T {} + +shared(T) allocClassMem() +{ + void *p; + // assume p is allocated here + return cast(shared(T))p; +} diff --git a/compiler/test/fail_compilation/shared.d b/compiler/test/fail_compilation/shared.d index 7d15b16bdc1f..413905ceb6e6 100644 --- a/compiler/test/fail_compilation/shared.d +++ b/compiler/test/fail_compilation/shared.d @@ -236,3 +236,26 @@ struct BitRange this.bits++; } } + +/* +TEST_OUTPUT: +--- +fail_compilation/shared.d(3004): Error: cast from `void*` to `shared(int*)` not allowed in safe code +fail_compilation/shared.d(3005): Error: cast from `void*` to `shared(const(int*))` not allowed in safe code +fail_compilation/shared.d(3008): Error: cast from `shared(void*)` to `int*` not allowed in safe code +fail_compilation/shared.d(3009): Error: cast from `shared(void*)` to `shared(const(int*))` not allowed in safe code +--- +*/ + +#line 3000 + +void test_casting_safe() @safe +{ + void *p; + auto t1 = cast(shared(int*))p; + auto t2 = cast(const(shared(int*)))p; + + shared void* s; + auto x1 = cast(int*)s; + auto x2 = cast(const(shared(int*)))s; +}