Skip to content

Commit 8e92050

Browse files
committed
[SemaCXX] Unconfuse Clang when std::align_val_t is unscoped in C++03
When -faligned-allocation is specified in C++03 libc++ defines std::align_val_t as an unscoped enumeration type (because Clang didn't provide scoped enumerations as an extension until 8.0). Unfortunately Clang confuses the `align_val_t` overloads of delete with the sized deallocation overloads which aren't enabled. This caused Clang to call the aligned deallocation function as if it were the sized deallocation overload. For example: https://godbolt.org/z/xXJELh This patch fixes the confusion. llvm-svn: 351294
1 parent d88cbd5 commit 8e92050

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,11 +1511,19 @@ namespace {
15111511
Destroying = true;
15121512
++NumBaseParams;
15131513
}
1514-
if (FD->getNumParams() == NumBaseParams + 2)
1515-
HasAlignValT = HasSizeT = true;
1516-
else if (FD->getNumParams() == NumBaseParams + 1) {
1517-
HasSizeT = FD->getParamDecl(NumBaseParams)->getType()->isIntegerType();
1518-
HasAlignValT = !HasSizeT;
1514+
1515+
if (NumBaseParams < FD->getNumParams() &&
1516+
S.Context.hasSameUnqualifiedType(
1517+
FD->getParamDecl(NumBaseParams)->getType(),
1518+
S.Context.getSizeType())) {
1519+
++NumBaseParams;
1520+
HasSizeT = true;
1521+
}
1522+
1523+
if (NumBaseParams < FD->getNumParams() &&
1524+
FD->getParamDecl(NumBaseParams)->getType()->isAlignValT()) {
1525+
++NumBaseParams;
1526+
HasAlignValT = true;
15191527
}
15201528

15211529
// In CUDA, determine how much we'd like / dislike to call this.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %clang_cc1 -std=c++03 -triple x86_64-pc-linux-gnu %s \
2+
// RUN: -faligned-allocation -emit-llvm -o - -Wno-c++11-extensions | FileCheck %s
3+
4+
// Ensure Clang doesn't confuse std::align_val_t with the sized deallocation
5+
// parameter when the enum type is unscoped. Libc++ does this in C++03 in order
6+
// to support aligned allocation in that dialect.
7+
8+
using size_t = __decltype(sizeof(0));
9+
10+
namespace std {
11+
enum align_val_t : size_t {};
12+
}
13+
_Static_assert(__is_same(__underlying_type(std::align_val_t), size_t), "");
14+
15+
// CHECK-LABEL: define void @_Z1fPi(
16+
void f(int *p) {
17+
// CHECK-NOT: call void @_ZdlPvSt11align_val_t(
18+
// CHECK: call void @_ZdlPv(
19+
// CHECK: ret void
20+
delete p;
21+
}

0 commit comments

Comments
 (0)