r260181 - Fix undefined behavior when compiling in C++14 due to sized operator delete

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 8 17:05:04 PST 2016


Author: rsmith
Date: Mon Feb  8 19:05:04 2016
New Revision: 260181

URL: http://llvm.org/viewvc/llvm-project?rev=260181&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h
    cfe/trunk/lib/CodeGen/CGCall.cpp

Modified: cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h?rev=260181&r1=260180&r2=260181&view=diff
==============================================================================
--- cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h (original)
+++ cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h Mon Feb  8 19:05:04 2016
@@ -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 <cassert>
 
 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<CGFunctionInfo, CGFunctionInfoArgInfo> {
+  typedef CGFunctionInfoArgInfo ArgInfo;
 
   /// The LLVM::CallingConv to use for this function (as specified by the
   /// user).
@@ -374,13 +381,17 @@ class CGFunctionInfo : public llvm::Fold
   unsigned ArgStructAlign;
 
   unsigned NumArgs;
+
   ArgInfo *getArgsBuffer() {
-    return reinterpret_cast<ArgInfo*>(this+1);
+    return getTrailingObjects<ArgInfo>();
   }
   const ArgInfo *getArgsBuffer() const {
-    return reinterpret_cast<const ArgInfo*>(this + 1);
+    return getTrailingObjects<ArgInfo>();
   }
 
+  size_t numTrailingObjects(OverloadToken<ArgInfo>) { return NumArgs + 1; }
+  friend class TrailingObjects;
+
   CGFunctionInfo() : Required(RequiredArgs::All) {}
 
 public:
@@ -391,6 +402,7 @@ public:
                                 CanQualType resultType,
                                 ArrayRef<CanQualType> argTypes,
                                 RequiredArgs required);
+  void operator delete(void *p) { TrailingObjects::operator delete(p); }
 
   typedef const ArgInfo *const_arg_iterator;
   typedef ArgInfo *arg_iterator;

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=260181&r1=260180&r2=260181&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Mon Feb  8 19:05:04 2016
@@ -569,8 +569,7 @@ CGFunctionInfo *CGFunctionInfo::create(u
                                        CanQualType resultType,
                                        ArrayRef<CanQualType> argTypes,
                                        RequiredArgs required) {
-  void *buffer = operator new(sizeof(CGFunctionInfo) +
-                              sizeof(ArgInfo) * (argTypes.size() + 1));
+  void *buffer = operator new(totalSizeToAlloc<ArgInfo>(argTypes.size() + 1));
   CGFunctionInfo *FI = new(buffer) CGFunctionInfo();
   FI->CallingConvention = llvmCC;
   FI->EffectiveCallingConvention = llvmCC;




More information about the cfe-commits mailing list