Skip to content

Commit ba9af8d

Browse files
committed
Tighten checks for IR aggregate sizes
1 parent 6bd5d9a commit ba9af8d

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed

ir/iraggr.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "dmd/aggregate.h"
1313
#include "dmd/declaration.h"
14+
#include "dmd/errors.h"
1415
#include "dmd/expression.h"
1516
#include "dmd/identifier.h"
1617
#include "dmd/init.h"
@@ -217,8 +218,12 @@ IrAggr::createInitializerConstant(const VarInitMap &explicitInitializers) {
217218

218219
// tail padding?
219220
const size_t structsize = aggrdecl->size(Loc());
220-
if (offset < structsize)
221+
if (offset < structsize) {
221222
add_zeros(constants, offset, structsize);
223+
} else if (offset > structsize) {
224+
error(Loc(), "ICE: IR aggregate constant size exceeds the frontend size");
225+
fatal();
226+
}
222227

223228
// get LL field types
224229
llvm::SmallVector<llvm::Type *, 16> types;

ir/irtypeclass.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "dmd/aggregate.h"
1313
#include "dmd/declaration.h"
1414
#include "dmd/dsymbol.h"
15+
#include "dmd/errors.h"
1516
#include "dmd/mtype.h"
1617
#include "dmd/target.h"
1718
#include "dmd/template.h"
@@ -98,6 +99,12 @@ IrTypeClass *IrTypeClass::get(ClassDeclaration *cd) {
9899
isaStruct(t->type)->setBody(builder.defaultTypes(), builder.isPacked());
99100
t->varGEPIndices = builder.varGEPIndices();
100101

102+
if (!cd->isInterfaceDeclaration() && instanceSize &&
103+
getTypeAllocSize(t->type) != instanceSize) {
104+
error(cd->loc, "ICE: class IR size does not match the frontend size");
105+
fatal();
106+
}
107+
101108
IF_LOG Logger::cout() << "class type: " << *t->type << std::endl;
102109

103110
return t;

ir/irtypestruct.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "dmd/aggregate.h"
1313
#include "dmd/declaration.h"
14+
#include "dmd/errors.h"
1415
#include "dmd/init.h"
1516
#include "dmd/mtype.h"
1617
#include "dmd/template.h"
@@ -91,6 +92,11 @@ IrTypeStruct *IrTypeStruct::get(StructDeclaration *sd) {
9192
builder.addTailPadding(sd->structsize);
9293
isaStruct(t->type)->setBody(builder.defaultTypes(), builder.isPacked());
9394
t->varGEPIndices = builder.varGEPIndices();
95+
96+
if (getTypeAllocSize(t->type) != sd->structsize) {
97+
error(sd->loc, "ICE: struct IR size does not match the frontend size");
98+
fatal();
99+
}
94100
}
95101

96102
IF_LOG Logger::cout() << "final struct type: " << *t->type << std::endl;

tests/compilable/gh4734.d

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %ldc -c %s
2+
3+
align(1) struct Item {
4+
KV v;
5+
uint i;
6+
}
7+
8+
struct KV {
9+
align(1) S* s;
10+
uint k;
11+
}
12+
13+
struct S {
14+
Table table;
15+
}
16+
17+
struct Table {
18+
char a;
19+
Item v;
20+
}

0 commit comments

Comments
 (0)