summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-06-30 03:30:26 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-06-30 03:30:26 +0000
commit149e6031323d6507860909a5cbb449fb2d0e0210 (patch)
treeba1e4e8ac969b4a5a753964475e43e227a1b7d31
parent6238c6f09a8795b888ebf90d24adc169ebfa5242 (diff)
downloadbcm5719-llvm-149e6031323d6507860909a5cbb449fb2d0e0210.tar.gz
bcm5719-llvm-149e6031323d6507860909a5cbb449fb2d0e0210.zip
[MS ABI] Workaround corner-case bug in the ABI for operator delete
MSVC only genreates array cookies if the class has a destructor. This is problematic when having to call T::operator delete[](void *, size_t) because the second argument's argument is impossible to synthesize correctly if the class has no destructor (because there will be no array cookie). Instead, MSVC passes the size of the class. Do the same, for compatibility, instead of crashing. This fixes PR23990. llvm-svn: 241038
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp3
-rw-r--r--clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp10
2 files changed, 12 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index f0f706d7b95..c7adccaeeae 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -1548,7 +1548,8 @@ namespace {
// The size of an element, multiplied by the number of elements.
llvm::Value *Size
= llvm::ConstantInt::get(SizeTy, ElementTypeSize.getQuantity());
- Size = CGF.Builder.CreateMul(Size, NumElements);
+ if (NumElements)
+ Size = CGF.Builder.CreateMul(Size, NumElements);
// Plus the size of the cookie if applicable.
if (!CookieSize.isZero()) {
diff --git a/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp b/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
index 619b1b8a948..62ead4fb69d 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
@@ -58,4 +58,14 @@ void check_array_cookies_aligned() {
// CHECK: getelementptr inbounds i8, i8* [[ARRAY_AS_CHAR]], i64 -8
}
+namespace PR23990 {
+struct S {
+ char x[42];
+ void operator delete[](void *p, __SIZE_TYPE__);
+ // CHECK-LABEL: define void @"\01?delete_s@PR23990@@YAXPAUS@1@@Z"(
+ // CHECK: call void @"\01??_VS@PR23990@@SAXPAXI@Z"(i8* {{.*}}, i32 42)
+};
+void delete_s(S *s) { delete[] s; }
+}
+
// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
OpenPOWER on IntegriCloud