diff options
author | John McCall <rjmccall@apple.com> | 2011-05-16 01:05:12 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-05-16 01:05:12 +0000 |
commit | b1c98a35fbd49d6404a72db4aca2ceda352380c7 (patch) | |
tree | 7a939e0932b90135416af1a4b707f6a84bc174b8 /lib/CodeGen | |
parent | 5587803dfdb862d573289782f0c695872d9297a1 (diff) |
Don't actually emit calls to the reserved global placement new and delete
operators; their semantics are guaranteed by the language.
If someone wants to argue that freestanding compiles shouldn't recognize
this, I might be convinceable.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131395 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGExprCXX.cpp | 46 |
1 files changed, 18 insertions, 28 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 734449005f..1d668477c1 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -444,33 +444,14 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtor(llvm::Value *Dest, E->arg_begin(), E->arg_end()); } -/// Check whether the given operator new[] is the global placement -/// operator new[]. -static bool IsPlacementOperatorNewArray(ASTContext &Ctx, - const FunctionDecl *Fn) { - // Must be in global scope. Note that allocation functions can't be - // declared in namespaces. - if (!Fn->getDeclContext()->getRedeclContext()->isFileContext()) - return false; - - // Signature must be void *operator new[](size_t, void*). - // The size_t is common to all operator new[]s. - if (Fn->getNumParams() != 2) - return false; - - CanQualType ParamType = Ctx.getCanonicalType(Fn->getParamDecl(1)->getType()); - return (ParamType == Ctx.VoidPtrTy); -} - static CharUnits CalculateCookiePadding(CodeGenFunction &CGF, const CXXNewExpr *E) { if (!E->isArray()) return CharUnits::Zero(); - // No cookie is required if the new operator being used is - // ::operator new[](size_t, void*). - const FunctionDecl *OperatorNew = E->getOperatorNew(); - if (IsPlacementOperatorNewArray(CGF.getContext(), OperatorNew)) + // No cookie is required if the operator new[] being used is the + // reserved placement operator new[]. + if (E->getOperatorNew()->isReservedGlobalPlacementOperator()) return CharUnits::Zero(); return CGF.CGM.getCXXABI().GetArrayCookieSize(E); @@ -1073,11 +1054,19 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { EmitCallArg(allocatorArgs, *placementArg, placementArg->getType()); } - // Emit the allocation call. - RValue RV = - EmitCall(CGM.getTypes().getFunctionInfo(allocatorArgs, allocatorType), - CGM.GetAddrOfFunction(allocator), ReturnValueSlot(), - allocatorArgs, allocator); + // Emit the allocation call. If the allocator is a global placement + // operator, just "inline" it directly. + RValue RV; + if (allocator->isReservedGlobalPlacementOperator()) { + assert(allocatorArgs.size() == 2); + RV = allocatorArgs[1].RV; + // TODO: kill any unnecessary computations done for the size + // argument. + } else { + RV = EmitCall(CGM.getTypes().getFunctionInfo(allocatorArgs, allocatorType), + CGM.GetAddrOfFunction(allocator), ReturnValueSlot(), + allocatorArgs, allocator); + } // Emit a null check on the allocation result if the allocation // function is allowed to return null (because it has a non-throwing @@ -1122,7 +1111,8 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { // If there's an operator delete, enter a cleanup to call it if an // exception is thrown. EHScopeStack::stable_iterator operatorDeleteCleanup; - if (E->getOperatorDelete()) { + if (E->getOperatorDelete() && + !E->getOperatorDelete()->isReservedGlobalPlacementOperator()) { EnterNewDeleteCleanup(*this, E, allocation, allocSize, allocatorArgs); operatorDeleteCleanup = EHStack.stable_begin(); } |