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 21985 - Ensure that LabelDsymbols have an explicit location #12605

Merged
merged 1 commit into from
May 29, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/dmd/declaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ class FuncDeclaration : public Declaration
bool overloadInsert(Dsymbol *s);
bool inUnittest();
MATCH leastAsSpecialized(FuncDeclaration *g);
LabelDsymbol *searchLabel(Identifier *ident);
LabelDsymbol *searchLabel(Identifier *ident, const Loc &loc);
int getLevel(FuncDeclaration *fd, int intypeof); // lexical nesting level difference
int getLevelAndCheck(const Loc &loc, Scope *sc, FuncDeclaration *fd);
const char *toPrettyChars(bool QualifyTypes = false);
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -4692,7 +4692,7 @@ class FuncDeclaration : public Declaration
bool overloadInsert(Dsymbol* s);
bool inUnittest();
MATCH leastAsSpecialized(FuncDeclaration* g);
LabelDsymbol* searchLabel(Identifier* ident);
LabelDsymbol* searchLabel(Identifier* ident, const Loc& loc = Loc::initial);
int32_t getLevel(FuncDeclaration* fd, int32_t intypeof);
int32_t getLevelAndCheck(const Loc& loc, Scope* sc, FuncDeclaration* fd, Declaration* decl);
enum : int32_t { LevelError = -2 };
Expand Down
13 changes: 10 additions & 3 deletions src/dmd/func.d
Original file line number Diff line number Diff line change
Expand Up @@ -1063,9 +1063,16 @@ extern (C++) class FuncDeclaration : Declaration
}

/********************************
* Labels are in a separate scope, one per function.
* Searches for a label with the given identifier. This function will insert a new
* `LabelDsymbol` into `labtab` if it does not contain a mapping for `ident`.
*
* Params:
* ident = identifier of the requested label
* loc = location used when creating a new `LabelDsymbol`
*
* Returns: the `LabelDsymbol` for `ident`
*/
final LabelDsymbol searchLabel(Identifier ident)
final LabelDsymbol searchLabel(Identifier ident, const ref Loc loc = Loc.initial)
{
Dsymbol s;
if (!labtab)
Expand All @@ -1074,7 +1081,7 @@ extern (C++) class FuncDeclaration : Declaration
s = labtab.lookup(ident);
if (!s)
{
s = new LabelDsymbol(ident);
s = new LabelDsymbol(ident, loc);
labtab.insert(s);
}
return cast(LabelDsymbol)s;
Expand Down
4 changes: 2 additions & 2 deletions src/dmd/iasmdmd.d
Original file line number Diff line number Diff line change
Expand Up @@ -3508,7 +3508,7 @@ code *asm_da_parse(OP *pop)
{
if (asmstate.tokValue == TOK.identifier)
{
LabelDsymbol label = asmstate.sc.func.searchLabel(asmstate.tok.ident);
LabelDsymbol label = asmstate.sc.func.searchLabel(asmstate.tok.ident, asmstate.loc);
if (!label)
{
asmerr("label `%s` not found", asmstate.tok.ident.toChars());
Expand Down Expand Up @@ -4421,7 +4421,7 @@ void asm_primary_exp(out OPND o1)
if (!s)
{
// Assume it is a label, and define that label
s = asmstate.sc.func.searchLabel(asmstate.tok.ident);
s = asmstate.sc.func.searchLabel(asmstate.tok.ident, asmstate.loc);
}
if (auto label = s.isLabel())
{
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/semantic3.d
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
LabelDsymbol label = cast(LabelDsymbol)keyValue.value;
if (!label.statement && (!label.deleted || label.iasm))
{
funcdecl.error("label `%s` is undefined", label.toChars());
funcdecl.error(label.loc, "label `%s` is undefined", label.toChars());
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/dmd/statement.d
Original file line number Diff line number Diff line change
Expand Up @@ -2441,9 +2441,9 @@ extern (C++) final class LabelDsymbol : Dsymbol
bool deleted; // set if rewritten to return in foreach delegate
bool iasm; // set if used by inline assembler

extern (D) this(Identifier ident)
extern (D) this(Identifier ident, const ref Loc loc = Loc.initial)
{
super(ident);
super(loc, ident);
}

static LabelDsymbol create(Identifier ident)
Expand Down
6 changes: 3 additions & 3 deletions src/dmd/statementsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -4160,7 +4160,7 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
FuncDeclaration fd = sc.func;

gs.ident = fixupLabelName(sc, gs.ident);
gs.label = fd.searchLabel(gs.ident);
gs.label = fd.searchLabel(gs.ident, gs.loc);
gs.tryBody = sc.tryBody;
gs.tf = sc.tf;
gs.os = sc.os;
Expand Down Expand Up @@ -4205,7 +4205,7 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
ls.os = sc.os;
ls.lastVar = sc.lastVar;

LabelDsymbol ls2 = fd.searchLabel(ls.ident);
LabelDsymbol ls2 = fd.searchLabel(ls.ident, ls.loc);
if (ls2.statement)
{
ls.error("label `%s` already defined", ls2.toChars());
Expand Down Expand Up @@ -4253,7 +4253,7 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
{
if (auto ls = s.isLabelStatement())
{
sc.func.searchLabel(ls.ident);
sc.func.searchLabel(ls.ident, ls.loc);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/fail_compilation/fail11552.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
REQUIRED_ARGS: -o-
TEST_OUTPUT:
---
fail_compilation/fail11552.d(9): Error: function `D main` label `label` is undefined
fail_compilation/fail11552.d(11): Error: function `D main` label `label` is undefined
---
*/

Expand Down
4 changes: 2 additions & 2 deletions test/fail_compilation/iasm1.d
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ void test4()

/* TEST_OUTPUT:
---
fail_compilation/iasm1.d(501): Error: function `iasm1.test5` label `L1` is undefined
fail_compilation/iasm1.d(505): Error: function `iasm1.test5` label `L1` is undefined
---
*/

Expand All @@ -117,7 +117,7 @@ void test5()

/* TEST_OUTPUT:
---
fail_compilation/iasm1.d(611): Error: delegate `iasm1.test6.__foreachbody1` label `L1` is undefined
fail_compilation/iasm1.d(615): Error: delegate `iasm1.test6.__foreachbody1` label `L1` is undefined
---
*/

Expand Down
2 changes: 1 addition & 1 deletion test/fail_compilation/ice11552.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
REQUIRED_ARGS: -o-
TEST_OUTPUT:
---
fail_compilation/ice11552.d(11): Error: function `ice11552.test11552` label `label` is undefined
fail_compilation/ice11552.d(13): Error: function `ice11552.test11552` label `label` is undefined
fail_compilation/ice11552.d(16): called from here: `test11552()`
fail_compilation/ice11552.d(16): while evaluating: `static assert(test11552())`
---
Expand Down