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 } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits