Skip to content

Commit 16bdf6f

Browse files
committed
semantic3: Fix more assertions if TypeInfo_AssociativeArray is misdefined
1 parent d9cf342 commit 16bdf6f

4 files changed

Lines changed: 73 additions & 33 deletions

File tree

compiler/src/dmd/semantic3.d

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,6 +1631,11 @@ private extern(C++) final class Semantic3Visitor : Visitor
16311631
return new DotTemplateInstanceExp(loc, id, hook, tiargs);
16321632
}
16331633

1634+
void notTemplateFunction(Loc loc, Identifier id)
1635+
{
1636+
error(loc, "`%s` isn't a template function", id.toChars());
1637+
}
1638+
16341639
// generate ti.entry
16351640
auto tempinst = makeDotExp(Id.Entry);
16361641
auto e = expressionSemantic(tempinst, sc2);
@@ -1645,25 +1650,35 @@ private extern(C++) final class Semantic3Visitor : Visitor
16451650
semanticTypeInfo(sc2, ti.entry); // might get deferred
16461651

16471652
// generate ti.xtoHash
1648-
auto hashinst = makeDotExp(Identifier.idPool("aaGetHash"));
1653+
auto aaGetHash = Identifier.idPool("aaGetHash");
1654+
auto hashinst = makeDotExp(aaGetHash);
16491655
e = expressionSemantic(hashinst, sc2);
16501656
if (!e.isErrorExp())
16511657
{
1652-
assert(e.isVarExp() && e.type.isTypeFunction());
1653-
ti.xtoHash = e.isVarExp().var;
1654-
if (auto tmpl = ti.xtoHash.parent.isTemplateInstance())
1655-
tmpl.minst = sc2._module.importedFrom; // ensure it gets emitted
1658+
if (!e.isVarExp() || !e.type.isTypeFunction())
1659+
notTemplateFunction(e.loc, aaGetHash);
1660+
else
1661+
{
1662+
ti.xtoHash = e.isVarExp().var;
1663+
if (auto tmpl = ti.xtoHash.parent.isTemplateInstance())
1664+
tmpl.minst = sc2._module.importedFrom; // ensure it gets emitted
1665+
}
16561666
}
16571667

16581668
// generate ti.xopEqual
1659-
auto equalinst = makeDotExp(Identifier.idPool("aaOpEqual"));
1669+
auto aaOpEqual = Identifier.idPool("aaOpEqual");
1670+
auto equalinst = makeDotExp(aaOpEqual);
16601671
e = expressionSemantic(equalinst, sc2);
16611672
if (!e.isErrorExp())
16621673
{
1663-
assert(e.isVarExp() && e.type.isTypeFunction());
1664-
ti.xopEqual = e.isVarExp().var;
1665-
if (auto tmpl = ti.xopEqual.parent.isTemplateInstance())
1666-
tmpl.minst = sc2._module.importedFrom; // ensure it gets emitted
1674+
if (!e.isVarExp() || !e.type.isTypeFunction())
1675+
notTemplateFunction(e.loc, aaOpEqual);
1676+
else
1677+
{
1678+
ti.xopEqual = e.isVarExp().var;
1679+
if (auto tmpl = ti.xopEqual.parent.isTemplateInstance())
1680+
tmpl.minst = sc2._module.importedFrom; // ensure it gets emitted
1681+
}
16671682
}
16681683
visit(cast(ASTCodegen.TypeInfoDeclaration)ti);
16691684
}

compiler/test/fail_compilation/test20863.d

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// must not assert/crash with empty declarations
2+
/* TEST_OUTPUT:
3+
---
4+
fail_compilation/test20863a.d(21): Error: no property `Entry` for type `object.TypeInfo_AssociativeArray`
5+
fail_compilation/test20863a.d(17): class `TypeInfo_AssociativeArray` defined here
6+
fail_compilation/test20863a.d(21): Error: no property `aaGetHash` for type `object.TypeInfo_AssociativeArray`
7+
fail_compilation/test20863a.d(17): class `TypeInfo_AssociativeArray` defined here
8+
fail_compilation/test20863a.d(21): Error: no property `aaOpEqual` for type `object.TypeInfo_AssociativeArray`
9+
fail_compilation/test20863a.d(17): class `TypeInfo_AssociativeArray` defined here
10+
---
11+
*/
12+
13+
module object;
14+
15+
class Object { }
16+
class TypeInfo { }
17+
class TypeInfo_AssociativeArray { }
18+
19+
extern(C) int main()
20+
{
21+
int[int] aa;
22+
return 0;
23+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// must not assert/crash with mismatched declarations
2+
/* TEST_OUTPUT:
3+
---
4+
fail_compilation/test20863b.d(23): Error: `Entry` isn't a template
5+
fail_compilation/test20863b.d(23): Error: `aaGetHash` isn't a template function
6+
fail_compilation/test20863b.d(23): Error: `aaOpEqual` isn't a template function
7+
---
8+
*/
9+
10+
module object;
11+
12+
class Object { }
13+
class TypeInfo { }
14+
class TypeInfo_AssociativeArray
15+
{
16+
int Entry;
17+
struct aaOpEqual(K, V) { }
18+
struct aaGetHash(K, V) { }
19+
}
20+
21+
extern(C) int main()
22+
{
23+
int[int] aa;
24+
return 0;
25+
}

0 commit comments

Comments
 (0)