mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 00:55:49 +03:00
Don't finalize scope objects without dtors and monitor (#2516)
The dtors can be checked at compile-time; insert a runtime check for the monitor before finalizing the stack-allocated class object via druntime call. See issue #2515.
This commit is contained in:
parent
1da088330d
commit
6367d98d3a
8 changed files with 143 additions and 2 deletions
|
@ -21,6 +21,7 @@
|
|||
#include "gen/llvmhelpers.h"
|
||||
#include "gen/logger.h"
|
||||
#include "gen/nested.h"
|
||||
#include "gen/optimizer.h"
|
||||
#include "gen/rttibuilder.h"
|
||||
#include "gen/runtime.h"
|
||||
#include "gen/structs.h"
|
||||
|
@ -193,6 +194,50 @@ void DtoFinalizeClass(Loc &loc, LLValue *inst) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoFinalizeScopeClass(Loc &loc, LLValue *inst, ClassDeclaration *cd) {
|
||||
if (!isOptimizationEnabled()) {
|
||||
DtoFinalizeClass(loc, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(cd);
|
||||
// As of 2.077, the front-end doesn't emit the implicit delete() for C++
|
||||
// classes, so this code assumes D classes.
|
||||
assert(!cd->isCPPclass());
|
||||
|
||||
bool hasDtor = false;
|
||||
for (; cd; cd = cd->baseClass) {
|
||||
if (cd->dtor) {
|
||||
hasDtor = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDtor) {
|
||||
DtoFinalizeClass(loc, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
// no dtors => only finalize (via druntime call) if monitor is set,
|
||||
// see https://github.com/ldc-developers/ldc/issues/2515
|
||||
llvm::BasicBlock *ifbb = gIR->insertBB("if");
|
||||
llvm::BasicBlock *endbb = gIR->insertBBAfter(ifbb, "endif");
|
||||
|
||||
const auto monitor = DtoLoad(DtoGEPi(inst, 0, 1), ".monitor");
|
||||
const auto hasMonitor =
|
||||
gIR->ir->CreateICmp(llvm::CmpInst::ICMP_NE, monitor,
|
||||
getNullValue(monitor->getType()), ".hasMonitor");
|
||||
llvm::BranchInst::Create(ifbb, endbb, hasMonitor, gIR->scopebb());
|
||||
|
||||
gIR->scope() = IRScope(ifbb);
|
||||
DtoFinalizeClass(loc, inst);
|
||||
gIR->ir->CreateBr(endbb);
|
||||
|
||||
gIR->scope() = IRScope(endbb);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue *DtoCastClass(Loc &loc, DValue *val, Type *_to) {
|
||||
IF_LOG Logger::println("DtoCastClass(%s, %s)", val->type->toChars(),
|
||||
_to->toChars());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue