diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGExprCXX.cpp | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index feaf467636..35c65ab0e6 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -340,6 +340,24 @@ static CharUnits CalculateCookiePadding(ASTContext &Ctx, QualType ElementType) { Ctx.getTypeAlignInChars(ElementType)); } +/// 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()->getLookupContext()->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(ASTContext &Ctx, const CXXNewExpr *E) { if (!E->isArray()) return CharUnits::Zero(); @@ -347,16 +365,9 @@ static CharUnits CalculateCookiePadding(ASTContext &Ctx, const CXXNewExpr *E) { // No cookie is required if the new operator being used is // ::operator new[](size_t, void*). const FunctionDecl *OperatorNew = E->getOperatorNew(); - if (OperatorNew->getDeclContext()->getLookupContext()->isFileContext()) { - if (OperatorNew->getNumParams() == 2) { - CanQualType ParamType = - Ctx.getCanonicalType(OperatorNew->getParamDecl(1)->getType()); - - if (ParamType == Ctx.VoidPtrTy) - return CharUnits::Zero(); - } - } - + if (IsPlacementOperatorNewArray(Ctx, OperatorNew)) + return CharUnits::Zero(); + return CalculateCookiePadding(Ctx, E->getAllocatedType()); } |