From 6ca3d730aef797b5612528272e82ab64af1aff7c Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Mon, 1 Feb 2016 21:52:15 +0100 Subject: [PATCH] Do not construct Ir-Types twice for the same type. This is the same as in PR #1269. The Ir-Types may be initialized twice (due to pointers, forward references etc.). This commit fixes hopefully all instances of this problem, using the same approach in each factory function. This fixes issue #1112. --- ir/irtype.cpp | 12 ++++++++---- ir/irtype.h | 2 +- ir/irtypefunction.cpp | 18 ++++++++++++------ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/ir/irtype.cpp b/ir/irtype.cpp index 91dcfd6c22..5788ceb396 100644 --- a/ir/irtype.cpp +++ b/ir/irtype.cpp @@ -186,12 +186,16 @@ IrTypeArray *IrTypeArray::get(Type *dt) { ////////////////////////////////////////////////////////////////////////////// -IrTypeVector::IrTypeVector(Type *dt) : IrType(dt, vector2llvm(dt)) {} +IrTypeVector::IrTypeVector(Type *dt, llvm::Type *lt) : IrType(dt, lt) {} IrTypeVector *IrTypeVector::get(Type *dt) { - auto t = new IrTypeVector(dt); - dt->ctype = t; - return t; + LLType *lt = vector2llvm(dt); + // Could have already built the type as part of a struct forward reference, + // just as for pointers and arrays. + if (!dt->ctype) { + dt->ctype = new IrTypeVector(dt, lt); + } + return dt->ctype->isVector(); } llvm::Type *IrTypeVector::vector2llvm(Type *dt) { diff --git a/ir/irtype.h b/ir/irtype.h index 111d103430..40cc4662cd 100644 --- a/ir/irtype.h +++ b/ir/irtype.h @@ -182,7 +182,7 @@ public: protected: /// - explicit IrTypeVector(Type *dt); + explicit IrTypeVector(Type *dt, llvm::Type *lt); static llvm::Type *vector2llvm(Type *dt); }; diff --git a/ir/irtypefunction.cpp b/ir/irtypefunction.cpp index 1183de0529..f5fcf618ad 100644 --- a/ir/irtypefunction.cpp +++ b/ir/irtypefunction.cpp @@ -26,9 +26,12 @@ IrTypeFunction *IrTypeFunction::get(Type *dt) { IrFuncTy irFty; llvm::Type *lt = DtoFunctionType(dt, irFty, nullptr, nullptr); - auto result = new IrTypeFunction(dt, lt, irFty); - dt->ctype = result; - return result; + // Could have already built the type as part of a struct forward reference, + // just as for pointers and arrays. + if (!dt->ctype) { + dt->ctype = new IrTypeFunction(dt, lt, irFty); + } + return dt->ctype->isFunction(); } ////////////////////////////////////////////////////////////////////////////// @@ -47,7 +50,10 @@ IrTypeDelegate *IrTypeDelegate::get(Type *t) { llvm::Type *types[] = {getVoidPtrType(), getPtrToType(ltf)}; LLStructType *lt = LLStructType::get(gIR->context(), types, false); - auto result = new IrTypeDelegate(t, lt, irFty); - t->ctype = result; - return result; + // Could have already built the type as part of a struct forward reference, + // just as for pointers and arrays. + if (!t->ctype) { + t->ctype = new IrTypeDelegate(t, lt, irFty); + } + return t->ctype->isDelegate(); }