r248862 - Don't crash when a reserved global placement operator new is paired

John McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 29 16:55:18 PDT 2015


Author: rjmccall
Date: Tue Sep 29 18:55:17 2015
New Revision: 248862

URL: http://llvm.org/viewvc/llvm-project?rev=248862&view=rev
Log:
Don't crash when a reserved global placement operator new is paired
with a non-reserved operator delete in a new-expression.

Modified:
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/test/CodeGenCXX/exceptions.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=248862&r1=248861&r2=248862&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Tue Sep 29 18:55:17 2015
@@ -1289,9 +1289,11 @@ llvm::Value *CodeGenFunction::EmitCXXNew
   Address allocation = Address::invalid();
   CallArgList allocatorArgs;
   if (allocator->isReservedGlobalPlacementOperator()) {
+    assert(E->getNumPlacementArgs() == 1);
+    const Expr *arg = *E->placement_arguments().begin();
+
     AlignmentSource alignSource;
-    allocation = EmitPointerWithAlignment(*E->placement_arguments().begin(),
-                                          &alignSource);
+    allocation = EmitPointerWithAlignment(arg, &alignSource);
 
     // The pointer expression will, in many cases, be an opaque void*.
     // In these cases, discard the computed alignment and use the
@@ -1301,6 +1303,14 @@ llvm::Value *CodeGenFunction::EmitCXXNew
                            getContext().getTypeAlignInChars(allocType));
     }
 
+    // Set up allocatorArgs for the call to operator delete if it's not
+    // the reserved global operator.
+    if (E->getOperatorDelete() &&
+        !E->getOperatorDelete()->isReservedGlobalPlacementOperator()) {
+      allocatorArgs.add(RValue::get(allocSize), getContext().getSizeType());
+      allocatorArgs.add(RValue::get(allocation.getPointer()), arg->getType());
+    }
+
   } else {
     const FunctionProtoType *allocatorType =
       allocator->getType()->castAs<FunctionProtoType>();

Modified: cfe/trunk/test/CodeGenCXX/exceptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/exceptions.cpp?rev=248862&r1=248861&r2=248862&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/exceptions.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/exceptions.cpp Tue Sep 29 18:55:17 2015
@@ -2,6 +2,9 @@
 
 typedef __typeof(sizeof(0)) size_t;
 
+// Declare the reserved global placement new.
+void *operator new(size_t, void*);
+
 // This just shouldn't crash.
 namespace test0 {
   struct allocator {
@@ -526,4 +529,21 @@ namespace test11 {
   //   (After this is a terminate landingpad.)
 }
 
+namespace test12 {
+  struct A {
+    void operator delete(void *, void *);
+    A();
+  };
+
+  A *test(void *ptr) {
+    return new (ptr) A();
+  }
+  // CHECK-LABEL: define {{.*}} @_ZN6test124testEPv(
+  // CHECK:       [[PTR:%.*]] = load i8*, i8*
+  // CHECK-NEXT:  [[CAST:%.*]] = bitcast i8* [[PTR]] to [[A:%.*]]*
+  // CHECK-NEXT:  invoke void @_ZN6test121AC1Ev([[A]]* [[CAST]])
+  // CHECK:       ret [[A]]* [[CAST]]
+  // CHECK:       invoke void @_ZN6test121AdlEPvS1_(i8* [[PTR]], i8* [[PTR]])
+}
+
 // CHECK: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind }




More information about the cfe-commits mailing list