From: Richard Smith Date: Tue, 9 Feb 2016 01:05:04 +0000 (+0000) Subject: Fix undefined behavior when compiling in C++14 due to sized operator delete X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0f7f466fd0081ad90040e4b5df0a1611b7911269;p=clang Fix undefined behavior when compiling in C++14 due to sized operator delete being called with the wrong size: convert CGFunctionInfo to use TrailingObjects and ask TrailingObjects to provide a working 'operator delete' for us. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@260181 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h index bb6ceb4351..4c9e0134ff 100644 --- a/include/clang/CodeGen/CGFunctionInfo.h +++ b/include/clang/CodeGen/CGFunctionInfo.h @@ -20,6 +20,7 @@ #include "clang/AST/CharUnits.h" #include "clang/AST/Type.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/TrailingObjects.h" #include namespace llvm { @@ -331,13 +332,19 @@ public: } }; +// Implementation detail of CGFunctionInfo, factored out so it can be named +// in the TrailingObjects base class of CGFunctionInfo. +struct CGFunctionInfoArgInfo { + CanQualType type; + ABIArgInfo info; +}; + /// CGFunctionInfo - Class to encapsulate the information about a /// function definition. -class CGFunctionInfo : public llvm::FoldingSetNode { - struct ArgInfo { - CanQualType type; - ABIArgInfo info; - }; +class CGFunctionInfo final + : public llvm::FoldingSetNode, + private llvm::TrailingObjects { + typedef CGFunctionInfoArgInfo ArgInfo; /// The LLVM::CallingConv to use for this function (as specified by the /// user). @@ -374,13 +381,17 @@ class CGFunctionInfo : public llvm::FoldingSetNode { unsigned ArgStructAlign; unsigned NumArgs; + ArgInfo *getArgsBuffer() { - return reinterpret_cast(this+1); + return getTrailingObjects(); } const ArgInfo *getArgsBuffer() const { - return reinterpret_cast(this + 1); + return getTrailingObjects(); } + size_t numTrailingObjects(OverloadToken) { return NumArgs + 1; } + friend class TrailingObjects; + CGFunctionInfo() : Required(RequiredArgs::All) {} public: @@ -391,6 +402,7 @@ public: CanQualType resultType, ArrayRef argTypes, RequiredArgs required); + void operator delete(void *p) { TrailingObjects::operator delete(p); } typedef const ArgInfo *const_arg_iterator; typedef ArgInfo *arg_iterator; diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 5bd452e1c9..0ba0642517 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -569,8 +569,7 @@ CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC, CanQualType resultType, ArrayRef argTypes, RequiredArgs required) { - void *buffer = operator new(sizeof(CGFunctionInfo) + - sizeof(ArgInfo) * (argTypes.size() + 1)); + void *buffer = operator new(totalSizeToAlloc(argTypes.size() + 1)); CGFunctionInfo *FI = new(buffer) CGFunctionInfo(); FI->CallingConvention = llvmCC; FI->EffectiveCallingConvention = llvmCC;