From 6551a7dcb014b972909d340fab34f8b282722de2 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Sun, 18 Aug 2024 15:20:16 +0200 Subject: [PATCH] Tighten checks for IR aggregate sizes --- ir/iraggr.cpp | 7 ++++++- ir/irtypeclass.cpp | 6 ++++++ ir/irtypestruct.cpp | 6 ++++++ tests/compilable/gh4734.d | 20 ++++++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/compilable/gh4734.d diff --git a/ir/iraggr.cpp b/ir/iraggr.cpp index faca04f25c4..a19867af544 100644 --- a/ir/iraggr.cpp +++ b/ir/iraggr.cpp @@ -11,6 +11,7 @@ #include "dmd/aggregate.h" #include "dmd/declaration.h" +#include "dmd/errors.h" #include "dmd/expression.h" #include "dmd/identifier.h" #include "dmd/init.h" @@ -217,8 +218,12 @@ IrAggr::createInitializerConstant(const VarInitMap &explicitInitializers) { // tail padding? const size_t structsize = aggrdecl->size(Loc()); - if (offset < structsize) + if (offset < structsize) { add_zeros(constants, offset, structsize); + } else if (offset > structsize) { + error(Loc(), "ICE: IR aggregate constant size exceeds the frontend size"); + fatal(); + } // get LL field types llvm::SmallVector types; diff --git a/ir/irtypeclass.cpp b/ir/irtypeclass.cpp index e29b7460706..087c3b55919 100644 --- a/ir/irtypeclass.cpp +++ b/ir/irtypeclass.cpp @@ -12,6 +12,7 @@ #include "dmd/aggregate.h" #include "dmd/declaration.h" #include "dmd/dsymbol.h" +#include "dmd/errors.h" #include "dmd/mtype.h" #include "dmd/target.h" #include "dmd/template.h" @@ -98,6 +99,11 @@ IrTypeClass *IrTypeClass::get(ClassDeclaration *cd) { isaStruct(t->type)->setBody(builder.defaultTypes(), builder.isPacked()); t->varGEPIndices = builder.varGEPIndices(); + if (instanceSize && getTypeAllocSize(t->type) != instanceSize) { + error(cd->loc, "ICE: class IR size does not match the frontend size"); + fatal(); + } + IF_LOG Logger::cout() << "class type: " << *t->type << std::endl; return t; diff --git a/ir/irtypestruct.cpp b/ir/irtypestruct.cpp index ccbb5b9514c..fba984498a1 100644 --- a/ir/irtypestruct.cpp +++ b/ir/irtypestruct.cpp @@ -11,6 +11,7 @@ #include "dmd/aggregate.h" #include "dmd/declaration.h" +#include "dmd/errors.h" #include "dmd/init.h" #include "dmd/mtype.h" #include "dmd/template.h" @@ -91,6 +92,11 @@ IrTypeStruct *IrTypeStruct::get(StructDeclaration *sd) { builder.addTailPadding(sd->structsize); isaStruct(t->type)->setBody(builder.defaultTypes(), builder.isPacked()); t->varGEPIndices = builder.varGEPIndices(); + + if (getTypeAllocSize(t->type) != sd->structsize) { + error(sd->loc, "ICE: struct IR size does not match the frontend size"); + fatal(); + } } IF_LOG Logger::cout() << "final struct type: " << *t->type << std::endl; diff --git a/tests/compilable/gh4734.d b/tests/compilable/gh4734.d new file mode 100644 index 00000000000..49656e86077 --- /dev/null +++ b/tests/compilable/gh4734.d @@ -0,0 +1,20 @@ +// RUN: %ldc -c %s + +align(1) struct Item { + KV v; + uint i; +} + +struct KV { + align(1) S* s; + uint k; +} + +struct S { + Table table; +} + +struct Table { + char a; + Item v; +}