Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Bugzilla 24434 - Casting away const with cast() is not a @safe lv… #16315

Merged
merged 10 commits into from
Apr 28, 2024
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/expression.d
Original file line number Diff line number Diff line change
Expand Up @@ -3824,6 +3824,7 @@ extern (C++) final class CastExp : UnaExp
{
Type to; // type to cast to
ubyte mod = cast(ubyte)~0; // MODxxxxx
bool trusted; // assume cast is safe

extern (D) this(const ref Loc loc, Expression e, Type t) @safe
{
Expand Down
14 changes: 13 additions & 1 deletion compiler/src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -11864,7 +11864,11 @@
if (checkNewEscape(sc, exp.e2, false))
return setError();

exp = new CatElemAssignExp(exp.loc, exp.type, exp.e1, exp.e2.castTo(sc, tb1next));
auto ecast = exp.e2.castTo(sc, tb1next);
if (auto ce = ecast.isCastExp())
ce.trusted = true;

exp = new CatElemAssignExp(exp.loc, exp.type, exp.e1, ecast);
exp.e2 = doCopyOrMove(sc, exp.e2);
}
else if (tb1.ty == Tarray &&
Expand Down Expand Up @@ -15732,7 +15736,15 @@
return visit(_this);
}
if (_this.isLvalue())
{

Check warning on line 15739 in compiler/src/dmd/expressionsem.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expressionsem.d#L15739

Added line #L15739 was not covered by tests
with (_this)
if (!trusted && !e1.type.pointerTo().implicitConvTo(to.pointerTo()))
sc.setUnsafePreview(FeatureState.default_, false, loc,
"cast from `%s` to `%s` cannot be used as an lvalue in @safe code",
e1.type, to);

return _this;
}
return visit(_this);
}

Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -2425,6 +2425,7 @@ class CastExp final : public UnaExp
public:
Type* to;
uint8_t mod;
bool trusted;
CastExp* syntaxCopy() override;
bool isLvalue() override;
void accept(Visitor* v) override;
Expand Down
19 changes: 19 additions & 0 deletions compiler/test/fail_compilation/cast_qual.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
REQUIRED_ARGS: -preview=dip1000 -de
TEST_OUTPUT:
---
fail_compilation/cast_qual.d(15): Deprecation: cast from `const(int)` to `int` cannot be used as an lvalue in @safe code
fail_compilation/cast_qual.d(17): Deprecation: cast from `const(int)` to `int` cannot be used as an lvalue in @safe code
---
*/

@safe:

void main() {
const int i = 3;
int j = cast() i; // OK
int* p = &cast() i; // this should not compile in @safe code
*p = 4; // oops
cast() i = 5; // NG
auto q = &cast(const) j; // OK, int* to const int*
}
2 changes: 1 addition & 1 deletion druntime/src/core/sync/mutex.d
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ unittest
cargo = 42;
}

void useResource() shared @safe nothrow @nogc
void useResource() shared @trusted nothrow @nogc
{
mtx.lock_nothrow();
(cast() cargo) += 1;
Expand Down
Loading