diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-10-08 00:58:57 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-10-08 00:58:57 +0000 |
commit | 9a7f3e61a95ff42d1984b3c9aede2b1dd90c2adf (patch) | |
tree | a350b4e0099da49573bda4a82ef14ef859574286 /clang/test/CodeGenCXX/mangle-ms.cpp | |
parent | 094546836bed638d03e687d83b2682dfb3adf8f6 (diff) | |
download | bcm5719-llvm-9a7f3e61a95ff42d1984b3c9aede2b1dd90c2adf.tar.gz bcm5719-llvm-9a7f3e61a95ff42d1984b3c9aede2b1dd90c2adf.zip |
[ms-cxxabi] Fix the calling convention for operator new in records
Summary:
Operator new, new[], delete, and delete[] are all implicitly static when
declared inside a record. CXXMethodDecl already knows this, but we need
to account for that before we pick the calling convention for the
function type.
Fixes PR17371.
Reviewers: rsmith
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1761
llvm-svn: 192150
Diffstat (limited to 'clang/test/CodeGenCXX/mangle-ms.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/mangle-ms.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/mangle-ms.cpp b/clang/test/CodeGenCXX/mangle-ms.cpp index fd7c605c99f..42d574fa53e 100644 --- a/clang/test/CodeGenCXX/mangle-ms.cpp +++ b/clang/test/CodeGenCXX/mangle-ms.cpp @@ -304,3 +304,55 @@ inline int templated_inline_function_with_local_type() { int call_templated_inline_function_with_local_type() { return templated_inline_function_with_local_type<int>(); } + +// PR17371 +struct OverloadedNewDelete { + // __cdecl + void *operator new(__SIZE_TYPE__); + void *operator new[](__SIZE_TYPE__); + void operator delete(void *); + void operator delete[](void *); + // __thiscall + int operator+(int); +}; + +void *OverloadedNewDelete::operator new(__SIZE_TYPE__ s) { return 0; } +void *OverloadedNewDelete::operator new[](__SIZE_TYPE__ s) { return 0; } +void OverloadedNewDelete::operator delete(void *) { } +void OverloadedNewDelete::operator delete[](void *) { } +int OverloadedNewDelete::operator+(int x) { return x; }; + +// CHECK-DAG: ??2OverloadedNewDelete@@SAPAXI@Z +// CHECK-DAG: ??_UOverloadedNewDelete@@SAPAXI@Z +// CHECK-DAG: ??3OverloadedNewDelete@@SAXPAX@Z +// CHECK-DAG: ??_VOverloadedNewDelete@@SAXPAX@Z +// CHECK-DAG: ??HOverloadedNewDelete@@QAEHH@Z + +// X64-DAG: ??2OverloadedNewDelete@@SAPEAX_K@Z +// X64-DAG: ??_UOverloadedNewDelete@@SAPEAX_K@Z +// X64-DAG: ??3OverloadedNewDelete@@SAXPEAX@Z +// X64-DAG: ??_VOverloadedNewDelete@@SAXPEAX@Z +// X64-DAG: ??HOverloadedNewDelete@@QEAAHH@Z + +// Indirecting the function type through a typedef will require a calling +// convention adjustment before building the method decl. + +typedef void *__thiscall OperatorNewType(__SIZE_TYPE__); +typedef void __thiscall OperatorDeleteType(void *); + +struct TypedefNewDelete { + OperatorNewType operator new; + OperatorNewType operator new[]; + OperatorDeleteType operator delete; + OperatorDeleteType operator delete[]; +}; + +void *TypedefNewDelete::operator new(__SIZE_TYPE__ s) { return 0; } +void *TypedefNewDelete::operator new[](__SIZE_TYPE__ s) { return 0; } +void TypedefNewDelete::operator delete(void *) { } +void TypedefNewDelete::operator delete[](void *) { } + +// CHECK-DAG: ??2TypedefNewDelete@@SAPAXI@Z +// CHECK-DAG: ??_UTypedefNewDelete@@SAPAXI@Z +// CHECK-DAG: ??3TypedefNewDelete@@SAXPAX@Z +// CHECK-DAG: ??_VTypedefNewDelete@@SAXPAX@Z |