|
@@ -1002,6 +1002,38 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
|
|
StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr);
|
|
StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/// Emit a call to an operator new or operator delete function, as implicitly
|
|
|
|
+/// created by new-expressions and delete-expressions.
|
|
|
|
+static RValue EmitNewDeleteCall(CodeGenFunction &CGF,
|
|
|
|
+ const FunctionDecl *Callee,
|
|
|
|
+ const FunctionProtoType *CalleeType,
|
|
|
|
+ const CallArgList &Args) {
|
|
|
|
+ llvm::Instruction *CallOrInvoke;
|
|
|
|
+ RValue RV =
|
|
|
|
+ CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(Args, CalleeType),
|
|
|
|
+ CGF.CGM.GetAddrOfFunction(Callee), ReturnValueSlot(), Args,
|
|
|
|
+ Callee, &CallOrInvoke);
|
|
|
|
+
|
|
|
|
+ /// C++1y [expr.new]p10:
|
|
|
|
+ /// [In a new-expression,] an implementation is allowed to omit a call
|
|
|
|
+ /// to a replaceable global allocation function.
|
|
|
|
+ ///
|
|
|
|
+ /// We model such elidable calls with the 'builtin' attribute.
|
|
|
|
+ if (Callee->isReplaceableGlobalAllocationFunction()) {
|
|
|
|
+ // FIXME: Add addAttribute to CallSite.
|
|
|
|
+ if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(CallOrInvoke))
|
|
|
|
+ CI->addAttribute(llvm::AttributeSet::FunctionIndex,
|
|
|
|
+ llvm::Attribute::Builtin);
|
|
|
|
+ else if (llvm::InvokeInst *II = dyn_cast<llvm::InvokeInst>(CallOrInvoke))
|
|
|
|
+ II->addAttribute(llvm::AttributeSet::FunctionIndex,
|
|
|
|
+ llvm::Attribute::Builtin);
|
|
|
|
+ else
|
|
|
|
+ llvm_unreachable("unexpected kind of call instruction");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return RV;
|
|
|
|
+}
|
|
|
|
+
|
|
namespace {
|
|
namespace {
|
|
/// A cleanup to call the given 'operator delete' function upon
|
|
/// A cleanup to call the given 'operator delete' function upon
|
|
/// abnormal exit from a new expression.
|
|
/// abnormal exit from a new expression.
|
|
@@ -1051,9 +1083,7 @@ namespace {
|
|
DeleteArgs.add(getPlacementArgs()[I], *AI++);
|
|
DeleteArgs.add(getPlacementArgs()[I], *AI++);
|
|
|
|
|
|
// Call 'operator delete'.
|
|
// Call 'operator delete'.
|
|
- CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, FPT),
|
|
|
|
- CGF.CGM.GetAddrOfFunction(OperatorDelete),
|
|
|
|
- ReturnValueSlot(), DeleteArgs, OperatorDelete);
|
|
|
|
|
|
+ EmitNewDeleteCall(CGF, OperatorDelete, FPT, DeleteArgs);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
@@ -1112,9 +1142,7 @@ namespace {
|
|
}
|
|
}
|
|
|
|
|
|
// Call 'operator delete'.
|
|
// Call 'operator delete'.
|
|
- CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, FPT),
|
|
|
|
- CGF.CGM.GetAddrOfFunction(OperatorDelete),
|
|
|
|
- ReturnValueSlot(), DeleteArgs, OperatorDelete);
|
|
|
|
|
|
+ EmitNewDeleteCall(CGF, OperatorDelete, FPT, DeleteArgs);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
}
|
|
}
|
|
@@ -1227,10 +1255,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
|
|
// TODO: kill any unnecessary computations done for the size
|
|
// TODO: kill any unnecessary computations done for the size
|
|
// argument.
|
|
// argument.
|
|
} else {
|
|
} else {
|
|
- RV = EmitCall(CGM.getTypes().arrangeFreeFunctionCall(allocatorArgs,
|
|
|
|
- allocatorType),
|
|
|
|
- CGM.GetAddrOfFunction(allocator), ReturnValueSlot(),
|
|
|
|
- allocatorArgs, allocator);
|
|
|
|
|
|
+ RV = EmitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs);
|
|
}
|
|
}
|
|
|
|
|
|
// Emit a null check on the allocation result if the allocation
|
|
// Emit a null check on the allocation result if the allocation
|
|
@@ -1350,9 +1375,7 @@ void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD,
|
|
DeleteArgs.add(RValue::get(Size), SizeTy);
|
|
DeleteArgs.add(RValue::get(Size), SizeTy);
|
|
|
|
|
|
// Emit the call to delete.
|
|
// Emit the call to delete.
|
|
- EmitCall(CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, DeleteFTy),
|
|
|
|
- CGM.GetAddrOfFunction(DeleteFD), ReturnValueSlot(),
|
|
|
|
- DeleteArgs, DeleteFD);
|
|
|
|
|
|
+ EmitNewDeleteCall(*this, DeleteFD, DeleteFTy, DeleteArgs);
|
|
}
|
|
}
|
|
|
|
|
|
namespace {
|
|
namespace {
|
|
@@ -1508,9 +1531,7 @@ namespace {
|
|
}
|
|
}
|
|
|
|
|
|
// Emit the call to delete.
|
|
// Emit the call to delete.
|
|
- CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(Args, DeleteFTy),
|
|
|
|
- CGF.CGM.GetAddrOfFunction(OperatorDelete),
|
|
|
|
- ReturnValueSlot(), Args, OperatorDelete);
|
|
|
|
|
|
+ EmitNewDeleteCall(CGF, OperatorDelete, DeleteFTy, Args);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
}
|
|
}
|