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
2 changes: 0 additions & 2 deletions src/dmd/astbase.d
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,6 @@ struct ASTBase
enum AdrOnStackNone = ~0u;
uint ctfeAdrOnStack;
uint sequenceNumber;
__gshared uint nextSequenceNumber;

final extern (D) this(const ref Loc loc, Type type, Identifier id, Initializer _init, StorageClass st = STC.undefined_)
{
Expand All @@ -490,7 +489,6 @@ struct ASTBase
this._init = _init;
this.loc = loc;
this.storage_class = st;
sequenceNumber = ++nextSequenceNumber;
ctfeAdrOnStack = AdrOnStackNone;
}

Expand Down
10 changes: 3 additions & 7 deletions src/dmd/declaration.d
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,6 @@ extern (C++) class VarDeclaration : Declaration
uint endlinnum; // line number of end of scope that this var lives in
uint offset;
uint sequenceNumber; // order the variables are declared
__gshared uint nextSequenceNumber; // the counter for sequenceNumber
structalign_t alignment;

// When interpreting, these point to the value (NULL if value not determinable)
Expand Down Expand Up @@ -1099,7 +1098,6 @@ extern (C++) class VarDeclaration : Declaration
this._init = _init;
ctfeAdrOnStack = AdrOnStackNone;
this.storage_class = storage_class;
sequenceNumber = ++nextSequenceNumber;
}

static VarDeclaration create(const ref Loc loc, Type type, Identifier ident, Initializer _init, StorageClass storage_class = STC.undefined_)
Expand Down Expand Up @@ -1657,12 +1655,10 @@ extern (C++) class VarDeclaration : Declaration
// Sequence numbers work when there are no special VarDeclaration's involved
if (!((this.storage_class | v.storage_class) & special))
{
// FIXME: VarDeclaration's for parameters are created in semantic3, so
// they will have a greater sequence number than local variables.
// Hence reverse the result for mixed comparisons.
const exp = this.isParameter() == v.isParameter();
assert(this.sequenceNumber != this.sequenceNumber.init);
assert(v.sequenceNumber != v.sequenceNumber.init);

return (this.sequenceNumber < v.sequenceNumber) == exp;
return (this.sequenceNumber < v.sequenceNumber);
}

// Assume that semantic produces temporaries according to their lifetime
Expand Down
2 changes: 2 additions & 0 deletions src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (sc && sc.inunion && sc.inunion.isAnonDeclaration())
dsym.overlapped = true;

dsym.sequenceNumber = global.varSequenceNumber++;

Scope* scx = null;
if (dsym._scope)
{
Expand Down
4 changes: 2 additions & 2 deletions src/dmd/escape.d
Original file line number Diff line number Diff line change
Expand Up @@ -691,8 +691,8 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag)
}

// If va's lifetime encloses v's, then error
if (va &&
(va.enclosesLifetimeOf(v) && !(v.storage_class & (STC.parameter | STC.temp)) ||
if (va && !va.isDataseg() &&
(va.enclosesLifetimeOf(v) && !(v.storage_class & STC.temp) ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the check for STC.temp still necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not, let's see what the test suite says.

Copy link
Contributor Author

@dkorpel dkorpel Jan 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std/datetime/systime.d(9085): Error: scope variable `__tup794` assigned to `foundTZ` with longer lifetime

Looks like it's still needed for tuple lowering.

// va is class reference
ae.e1.isDotVarExp() && va.type.toBasetype().isTypeClass() && (va.enclosesLifetimeOf(v) ||
!va.isScope()) ||
Expand Down
10 changes: 6 additions & 4 deletions src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,7 @@ struct Global final
Array<Identifier* >* versionids;
Array<Identifier* >* debugids;
bool hasMainFunction;
uint32_t varSequenceNumber;
enum : int32_t { recursionLimit = 500 };

uint32_t startGagging();
Expand All @@ -881,10 +882,11 @@ struct Global final
console(),
versionids(),
debugids(),
hasMainFunction()
hasMainFunction(),
varSequenceNumber(1u)
{
}
Global(_d_dynamicArray< const char > inifilename, _d_dynamicArray< const char > copyright = { 73, "Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved" }, _d_dynamicArray< const char > written = { 24, "written by Walter Bright" }, Array<const char* >* path = nullptr, Array<const char* >* filePath = nullptr, _d_dynamicArray< const char > vendor = {}, Param params = Param(true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, 0u, false, false, (DiagnosticReporting)1u, false, false, false, (FeatureState)-1, (FeatureState)-1, false, false, false, (DiagnosticReporting)2u, (PIC)0u, false, false, 0u, false, false, false, true, true, true, false, false, false, false, false, false, true, false, false, false, (FeatureState)-1, false, false, (CppStdRevision)201103u, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKACTION)0u, 20u, {}, Array<const char* >(0LLU, {}, arrayliteral), nullptr, nullptr, {}, {}, {}, false, {}, {}, Array<const char* >(0LLU, {}, arrayliteral), false, {}, {}, true, (CxxHeaderMode)0u, {}, {}, false, {}, (JsonFieldFlags)0u, nullptr, nullptr, 0, 0u, nullptr, 0u, nullptr, {}, {}, {}, {}, nullptr, false, {}, Array<const char* >(0LLU, {}, arrayliteral), (MessageStyle)0u, false, Array<const char* >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), Array<bool >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), {}, {}, {}, {}), uint32_t errors = 0u, uint32_t warnings = 0u, uint32_t gag = 0u, uint32_t gaggedErrors = 0u, uint32_t gaggedWarnings = 0u, void* console = nullptr, Array<Identifier* >* versionids = nullptr, Array<Identifier* >* debugids = nullptr, bool hasMainFunction = false) :
Global(_d_dynamicArray< const char > inifilename, _d_dynamicArray< const char > copyright = { 73, "Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved" }, _d_dynamicArray< const char > written = { 24, "written by Walter Bright" }, Array<const char* >* path = nullptr, Array<const char* >* filePath = nullptr, _d_dynamicArray< const char > vendor = {}, Param params = Param(true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, 0u, false, false, (DiagnosticReporting)1u, false, false, false, (FeatureState)-1, (FeatureState)-1, false, false, false, (DiagnosticReporting)2u, (PIC)0u, false, false, 0u, false, false, false, true, true, true, false, false, false, false, false, false, true, false, false, false, (FeatureState)-1, false, false, (CppStdRevision)201103u, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKACTION)0u, 20u, {}, Array<const char* >(0LLU, {}, arrayliteral), nullptr, nullptr, {}, {}, {}, false, {}, {}, Array<const char* >(0LLU, {}, arrayliteral), false, {}, {}, true, (CxxHeaderMode)0u, {}, {}, false, {}, (JsonFieldFlags)0u, nullptr, nullptr, 0, 0u, nullptr, 0u, nullptr, {}, {}, {}, {}, nullptr, false, {}, Array<const char* >(0LLU, {}, arrayliteral), (MessageStyle)0u, false, Array<const char* >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), Array<bool >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), {}, {}, {}, {}), uint32_t errors = 0u, uint32_t warnings = 0u, uint32_t gag = 0u, uint32_t gaggedErrors = 0u, uint32_t gaggedWarnings = 0u, void* console = nullptr, Array<Identifier* >* versionids = nullptr, Array<Identifier* >* debugids = nullptr, bool hasMainFunction = false, uint32_t varSequenceNumber = 1u) :
inifilename(inifilename),
copyright(copyright),
written(written),
Expand All @@ -900,7 +902,8 @@ struct Global final
console(console),
versionids(versionids),
debugids(debugids),
hasMainFunction(hasMainFunction)
hasMainFunction(hasMainFunction),
varSequenceNumber(varSequenceNumber)
{}
};

Expand Down Expand Up @@ -5772,7 +5775,6 @@ class VarDeclaration : public Declaration
uint32_t endlinnum;
uint32_t offset;
uint32_t sequenceNumber;
static uint32_t nextSequenceNumber;
structalign_t alignment;
enum : uint32_t { AdrOnStackNone = 4294967295u };

Expand Down
1 change: 1 addition & 0 deletions src/dmd/globals.d
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ extern (C++) struct Global
Array!Identifier* debugids; /// command line debug versions and predefined versions

bool hasMainFunction; /// Whether a main function has already been compiled in (for -main switch)
uint varSequenceNumber = 1; /// Relative lifetime of `VarDeclaration` within a function, used for `scope` checks

enum recursionLimit = 500; /// number of recursive template expansions before abort

Expand Down
1 change: 1 addition & 0 deletions src/dmd/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ struct Global
Array<class Identifier*>* debugids; // command line debug versions and predefined versions

bool hasMainFunction;
unsigned varSequenceNumber;

/* Start gagging. Return the current number of gagged errors
*/
Expand Down
30 changes: 30 additions & 0 deletions test/fail_compilation/test22298.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
REQUIRED_ARGS: -preview=dip1000
TEST_OUTPUT:
---
fail_compilation/test22298.d(18): Error: scope variable `i` assigned to `p` with longer lifetime
fail_compilation/test22298.d(29): Error: scope variable `y` assigned to `x` with longer lifetime
---
*/

void g(scope void delegate(scope int*) @safe cb) @safe {
int x = 42;
cb(&x);
}

void main() @safe {
int* p;
void f(scope int* i) @safe {
p = i;
}

g(&f);
// address of x has escaped g
assert(*p == 42);
}

void f() @safe {
mixin("scope int* x;");
scope int* y;
x = y;
}