From c99f11b37343ccd955935cc87a4262311077a4b7 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 9 Feb 2016 01:05:04 +0000 Subject: [PATCH] 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. llvm-svn: 260181 --- clang/include/clang/CodeGen/CGFunctionInfo.h | 26 +++++++++++++++++++------- clang/lib/CodeGen/CGCall.cpp | 3 +-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/CodeGen/CGFunctionInfo.h b/clang/include/clang/CodeGen/CGFunctionInfo.h index bb6ceb4..4c9e013 100644 --- a/clang/include/clang/CodeGen/CGFunctionInfo.h +++ b/clang/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/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 5bd452e1..0ba0642 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/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; -- 2.7.4