2016-10-11 02:54:32 +08:00
|
|
|
// Check that delete exprs call aligned (de)allocation functions if
|
|
|
|
// -faligned-allocation is passed in both C++11 and C++14.
|
|
|
|
// RUN: %clang_cc1 -std=c++11 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
|
|
|
|
// RUN: %clang_cc1 -std=c++14 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
|
|
|
|
// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
|
|
|
|
|
2017-11-21 09:25:56 +08:00
|
|
|
// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s --check-prefix=CHECK-MS
|
|
|
|
|
2016-10-11 02:54:32 +08:00
|
|
|
// Check that we don't used aligned (de)allocation without -faligned-allocation or C++1z.
|
|
|
|
// RUN: %clang_cc1 -std=c++14 -DUNALIGNED -fexceptions %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
|
|
|
|
// RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
|
|
|
|
|
|
|
|
// CHECK-UNALIGNED-NOT: _Znwm_St11align_val_t
|
|
|
|
// CHECK-UNALIGNED-NOT: _Znam_St11align_val_t
|
|
|
|
// CHECK-UNALIGNED-NOT: _ZdlPv_St11align_val_t
|
|
|
|
// CHECK-UNALIGNED-NOT: _ZdaPv_St11align_val_t
|
|
|
|
// CHECK-UNALIGNED-NOT: _ZdlPvm_St11align_val_t
|
|
|
|
// CHECK-UNALIGNED-NOT: _ZdaPvm_St11align_val_t
|
|
|
|
|
|
|
|
typedef decltype(sizeof(0)) size_t;
|
|
|
|
namespace std { enum class align_val_t : size_t {}; }
|
|
|
|
|
|
|
|
#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
|
|
|
|
|
|
|
|
// Global new and delete.
|
|
|
|
// ======================
|
|
|
|
struct OVERALIGNED A { A(); int n[128]; };
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2a0v()
|
[clang] Annotating C++'s `operator new` with more attributes
Summary:
Right now we annotate C++'s `operator new` with `noalias` attribute,
which very much is healthy for optimizations.
However as per [[ http://eel.is/c++draft/basic.stc.dynamic.allocation | `[basic.stc.dynamic.allocation]` ]],
there are more promises on global `operator new`, namely:
* non-`std::nothrow_t` `operator new` *never* returns `nullptr`
* If `std::align_val_t align` parameter is taken, the pointer will also be `align`-aligned
* ~~global `operator new`-returned pointer is `__STDCPP_DEFAULT_NEW_ALIGNMENT__`-aligned ~~ It's more caveated than that.
Supplying this information may not cause immediate landslide effects
on any specific benchmarks, but it for sure will be healthy for optimizer
in the sense that the IR will better reflect the guarantees provided in the source code.
The caveat is `-fno-assume-sane-operator-new`, which currently prevents emitting `noalias`
attribute, and is automatically passed by Sanitizers ([[ https://bugs.llvm.org/show_bug.cgi?id=16386 | PR16386 ]]) - should it also cover these attributes?
The problem is that the flag is back-end-specific, as seen in `test/Modules/explicit-build-flags.cpp`.
But while it is okay to add `noalias` metadata in backend, we really should be adding at least
the alignment metadata to the AST, since that allows us to perform sema checks on it.
Reviewers: erichkeane, rjmccall, jdoerfert, eugenis, rsmith
Reviewed By: rsmith
Subscribers: xbolva00, jrtc27, atanasyan, nlopes, cfe-commits
Tags: #llvm, #clang
Differential Revision: https://reviews.llvm.org/D73380
2020-02-26 06:37:17 +08:00
|
|
|
// CHECK: %[[ALLOC:.*]] = call noalias nonnull align 32 i8* @_ZnwmSt11align_val_t(i64 512, i64 32)
|
2016-10-11 02:54:32 +08:00
|
|
|
// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-MS-LABEL: define {{.*}} @"?a0@@YAPEAXXZ"()
|
[clang] Annotating C++'s `operator new` with more attributes
Summary:
Right now we annotate C++'s `operator new` with `noalias` attribute,
which very much is healthy for optimizations.
However as per [[ http://eel.is/c++draft/basic.stc.dynamic.allocation | `[basic.stc.dynamic.allocation]` ]],
there are more promises on global `operator new`, namely:
* non-`std::nothrow_t` `operator new` *never* returns `nullptr`
* If `std::align_val_t align` parameter is taken, the pointer will also be `align`-aligned
* ~~global `operator new`-returned pointer is `__STDCPP_DEFAULT_NEW_ALIGNMENT__`-aligned ~~ It's more caveated than that.
Supplying this information may not cause immediate landslide effects
on any specific benchmarks, but it for sure will be healthy for optimizer
in the sense that the IR will better reflect the guarantees provided in the source code.
The caveat is `-fno-assume-sane-operator-new`, which currently prevents emitting `noalias`
attribute, and is automatically passed by Sanitizers ([[ https://bugs.llvm.org/show_bug.cgi?id=16386 | PR16386 ]]) - should it also cover these attributes?
The problem is that the flag is back-end-specific, as seen in `test/Modules/explicit-build-flags.cpp`.
But while it is okay to add `noalias` metadata in backend, we really should be adding at least
the alignment metadata to the AST, since that allows us to perform sema checks on it.
Reviewers: erichkeane, rjmccall, jdoerfert, eugenis, rsmith
Reviewed By: rsmith
Subscribers: xbolva00, jrtc27, atanasyan, nlopes, cfe-commits
Tags: #llvm, #clang
Differential Revision: https://reviews.llvm.org/D73380
2020-02-26 06:37:17 +08:00
|
|
|
// CHECK-MS: %[[ALLOC:.*]] = call noalias nonnull align 32 i8* @"??2@YAPEAX_KW4align_val_t@std@@@Z"(i64 512, i64 32)
|
2017-11-21 09:25:56 +08:00
|
|
|
// CHECK-MS: cleanuppad
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-MS: call void @"??3@YAXPEAXW4align_val_t@std@@@Z"(i8* %[[ALLOC]], i64 32)
|
2016-10-11 02:54:32 +08:00
|
|
|
void *a0() { return new A; }
|
|
|
|
|
2017-11-21 09:25:56 +08:00
|
|
|
// FIXME: Why don't we call the sized array deallocation overload in this case?
|
|
|
|
// The size is known.
|
|
|
|
//
|
2016-10-11 02:54:32 +08:00
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2a1l(
|
[clang] Annotating C++'s `operator new` with more attributes
Summary:
Right now we annotate C++'s `operator new` with `noalias` attribute,
which very much is healthy for optimizations.
However as per [[ http://eel.is/c++draft/basic.stc.dynamic.allocation | `[basic.stc.dynamic.allocation]` ]],
there are more promises on global `operator new`, namely:
* non-`std::nothrow_t` `operator new` *never* returns `nullptr`
* If `std::align_val_t align` parameter is taken, the pointer will also be `align`-aligned
* ~~global `operator new`-returned pointer is `__STDCPP_DEFAULT_NEW_ALIGNMENT__`-aligned ~~ It's more caveated than that.
Supplying this information may not cause immediate landslide effects
on any specific benchmarks, but it for sure will be healthy for optimizer
in the sense that the IR will better reflect the guarantees provided in the source code.
The caveat is `-fno-assume-sane-operator-new`, which currently prevents emitting `noalias`
attribute, and is automatically passed by Sanitizers ([[ https://bugs.llvm.org/show_bug.cgi?id=16386 | PR16386 ]]) - should it also cover these attributes?
The problem is that the flag is back-end-specific, as seen in `test/Modules/explicit-build-flags.cpp`.
But while it is okay to add `noalias` metadata in backend, we really should be adding at least
the alignment metadata to the AST, since that allows us to perform sema checks on it.
Reviewers: erichkeane, rjmccall, jdoerfert, eugenis, rsmith
Reviewed By: rsmith
Subscribers: xbolva00, jrtc27, atanasyan, nlopes, cfe-commits
Tags: #llvm, #clang
Differential Revision: https://reviews.llvm.org/D73380
2020-02-26 06:37:17 +08:00
|
|
|
// CHECK: %[[ALLOC:.*]] = call noalias nonnull align 32 i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32)
|
2016-10-11 02:54:32 +08:00
|
|
|
// No array cookie.
|
|
|
|
// CHECK-NOT: store
|
|
|
|
// CHECK: invoke void @_ZN1AC1Ev(
|
|
|
|
// CHECK: call void @_ZdaPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-MS-LABEL: define {{.*}} @"?a1@@YAPEAXJ@Z"(
|
[clang] Annotating C++'s `operator new` with more attributes
Summary:
Right now we annotate C++'s `operator new` with `noalias` attribute,
which very much is healthy for optimizations.
However as per [[ http://eel.is/c++draft/basic.stc.dynamic.allocation | `[basic.stc.dynamic.allocation]` ]],
there are more promises on global `operator new`, namely:
* non-`std::nothrow_t` `operator new` *never* returns `nullptr`
* If `std::align_val_t align` parameter is taken, the pointer will also be `align`-aligned
* ~~global `operator new`-returned pointer is `__STDCPP_DEFAULT_NEW_ALIGNMENT__`-aligned ~~ It's more caveated than that.
Supplying this information may not cause immediate landslide effects
on any specific benchmarks, but it for sure will be healthy for optimizer
in the sense that the IR will better reflect the guarantees provided in the source code.
The caveat is `-fno-assume-sane-operator-new`, which currently prevents emitting `noalias`
attribute, and is automatically passed by Sanitizers ([[ https://bugs.llvm.org/show_bug.cgi?id=16386 | PR16386 ]]) - should it also cover these attributes?
The problem is that the flag is back-end-specific, as seen in `test/Modules/explicit-build-flags.cpp`.
But while it is okay to add `noalias` metadata in backend, we really should be adding at least
the alignment metadata to the AST, since that allows us to perform sema checks on it.
Reviewers: erichkeane, rjmccall, jdoerfert, eugenis, rsmith
Reviewed By: rsmith
Subscribers: xbolva00, jrtc27, atanasyan, nlopes, cfe-commits
Tags: #llvm, #clang
Differential Revision: https://reviews.llvm.org/D73380
2020-02-26 06:37:17 +08:00
|
|
|
// CHECK-MS: %[[ALLOC:.*]] = call noalias nonnull align 32 i8* @"??_U@YAPEAX_KW4align_val_t@std@@@Z"(i64 %{{.*}}, i64 32)
|
2017-11-21 09:25:56 +08:00
|
|
|
// No array cookie.
|
|
|
|
// CHECK-MS-NOT: store
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-MS: invoke %struct.A* @"??0A@@QEAA@XZ"(
|
2017-11-21 09:25:56 +08:00
|
|
|
// CHECK-MS: cleanuppad
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-MS: call void @"??_V@YAXPEAXW4align_val_t@std@@@Z"(i8* %[[ALLOC]], i64 32)
|
2016-10-11 02:54:32 +08:00
|
|
|
void *a1(long n) { return new A[n]; }
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2a2P1A(
|
|
|
|
// CHECK: call void @_ZdlPvmSt11align_val_t(i8* %{{.*}}, i64 512, i64 32) #9
|
|
|
|
void a2(A *p) { delete p; }
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2a3P1A(
|
|
|
|
// CHECK: call void @_ZdaPvSt11align_val_t(i8* %{{.*}}, i64 32) #9
|
|
|
|
void a3(A *p) { delete[] p; }
|
|
|
|
|
|
|
|
|
|
|
|
// Class-specific usual new and delete.
|
|
|
|
// ====================================
|
|
|
|
struct OVERALIGNED B {
|
|
|
|
B();
|
|
|
|
// These are just a distraction. We should ignore them.
|
|
|
|
void *operator new(size_t);
|
|
|
|
void operator delete(void*, size_t);
|
|
|
|
void operator delete[](void*, size_t);
|
|
|
|
|
|
|
|
void *operator new(size_t, std::align_val_t);
|
|
|
|
void operator delete(void*, std::align_val_t);
|
|
|
|
void operator delete[](void*, std::align_val_t);
|
|
|
|
|
|
|
|
int n[128];
|
|
|
|
};
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2b0v()
|
|
|
|
// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 32)
|
|
|
|
// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
|
|
|
|
void *b0() { return new B; }
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2b1l(
|
[clang] Annotating C++'s `operator new` with more attributes
Summary:
Right now we annotate C++'s `operator new` with `noalias` attribute,
which very much is healthy for optimizations.
However as per [[ http://eel.is/c++draft/basic.stc.dynamic.allocation | `[basic.stc.dynamic.allocation]` ]],
there are more promises on global `operator new`, namely:
* non-`std::nothrow_t` `operator new` *never* returns `nullptr`
* If `std::align_val_t align` parameter is taken, the pointer will also be `align`-aligned
* ~~global `operator new`-returned pointer is `__STDCPP_DEFAULT_NEW_ALIGNMENT__`-aligned ~~ It's more caveated than that.
Supplying this information may not cause immediate landslide effects
on any specific benchmarks, but it for sure will be healthy for optimizer
in the sense that the IR will better reflect the guarantees provided in the source code.
The caveat is `-fno-assume-sane-operator-new`, which currently prevents emitting `noalias`
attribute, and is automatically passed by Sanitizers ([[ https://bugs.llvm.org/show_bug.cgi?id=16386 | PR16386 ]]) - should it also cover these attributes?
The problem is that the flag is back-end-specific, as seen in `test/Modules/explicit-build-flags.cpp`.
But while it is okay to add `noalias` metadata in backend, we really should be adding at least
the alignment metadata to the AST, since that allows us to perform sema checks on it.
Reviewers: erichkeane, rjmccall, jdoerfert, eugenis, rsmith
Reviewed By: rsmith
Subscribers: xbolva00, jrtc27, atanasyan, nlopes, cfe-commits
Tags: #llvm, #clang
Differential Revision: https://reviews.llvm.org/D73380
2020-02-26 06:37:17 +08:00
|
|
|
// CHECK: %[[ALLOC:.*]] = call noalias nonnull align 32 i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32)
|
2016-10-11 02:54:32 +08:00
|
|
|
// No array cookie.
|
|
|
|
// CHECK-NOT: store
|
|
|
|
// CHECK: invoke void @_ZN1BC1Ev(
|
|
|
|
// CHECK: call void @_ZN1BdaEPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
|
|
|
|
void *b1(long n) { return new B[n]; }
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2b2P1B(
|
|
|
|
// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %{{.*}}, i64 32)
|
|
|
|
void b2(B *p) { delete p; }
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2b3P1B(
|
|
|
|
// CHECK: call void @_ZN1BdaEPvSt11align_val_t(i8* %{{.*}}, i64 32)
|
|
|
|
void b3(B *p) { delete[] p; }
|
|
|
|
|
|
|
|
struct OVERALIGNED C {
|
|
|
|
C();
|
|
|
|
void *operator new[](size_t, std::align_val_t);
|
|
|
|
void operator delete[](void*, size_t, std::align_val_t);
|
|
|
|
|
|
|
|
// It doesn't matter that we have an unaligned operator delete[] that doesn't
|
|
|
|
// want the size. What matters is that the aligned one does.
|
|
|
|
void operator delete[](void*);
|
|
|
|
};
|
|
|
|
|
|
|
|
// This one has an array cookie.
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2b4l(
|
|
|
|
// CHECK: call {{.*}} @llvm.umul.with.overflow{{.*}}i64 32
|
|
|
|
// CHECK: call {{.*}} @llvm.uadd.with.overflow{{.*}}i64 32
|
|
|
|
// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1CnaEmSt11align_val_t(i64 %{{.*}}, i64 32)
|
|
|
|
// CHECK: store
|
|
|
|
// CHECK: call void @_ZN1CC1Ev(
|
|
|
|
//
|
|
|
|
// Note, we're still calling a placement allocation function, and there is no
|
|
|
|
// matching placement operator delete. =(
|
|
|
|
// FIXME: This seems broken.
|
|
|
|
// CHECK-NOT: call void @_ZN1CdaEPvmSt11align_val_t(
|
|
|
|
#ifndef UNALIGNED
|
|
|
|
void *b4(long n) { return new C[n]; }
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2b5P1C(
|
|
|
|
// CHECK: mul i64{{.*}} 32
|
|
|
|
// CHECK: add i64{{.*}} 32
|
|
|
|
// CHECK: call void @_ZN1CdaEPvmSt11align_val_t(
|
|
|
|
void b5(C *p) { delete[] p; }
|
|
|
|
|
|
|
|
|
|
|
|
// Global placement new.
|
|
|
|
// =====================
|
|
|
|
|
|
|
|
struct Q { int n; } q;
|
|
|
|
void *operator new(size_t, Q);
|
|
|
|
void *operator new(size_t, std::align_val_t, Q);
|
|
|
|
void operator delete(void*, Q);
|
|
|
|
void operator delete(void*, std::align_val_t, Q);
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2c0v(
|
|
|
|
// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t1Q(i64 512, i64 32, i32 %
|
|
|
|
// CHECK: call void @_ZdlPvSt11align_val_t1Q(i8* %[[ALLOC]], i64 32, i32 %
|
|
|
|
void *c0() { return new (q) A; }
|
|
|
|
|
|
|
|
|
|
|
|
// Class-specific placement new.
|
|
|
|
// =============================
|
|
|
|
|
|
|
|
struct OVERALIGNED D {
|
|
|
|
D();
|
|
|
|
void *operator new(size_t, Q);
|
|
|
|
void *operator new(size_t, std::align_val_t, Q);
|
|
|
|
void operator delete(void*, Q);
|
|
|
|
void operator delete(void*, std::align_val_t, Q);
|
|
|
|
};
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2d0v(
|
|
|
|
// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1DnwEmSt11align_val_t1Q(i64 32, i64 32, i32 %
|
|
|
|
// CHECK: call void @_ZN1DdlEPvSt11align_val_t1Q(i8* %[[ALLOC]], i64 32, i32 %
|
|
|
|
void *d0() { return new (q) D; }
|
|
|
|
|
|
|
|
|
|
|
|
// Calling aligned new with placement syntax.
|
|
|
|
// ==========================================
|
|
|
|
|
|
|
|
#ifndef UNALIGNED
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2e0v(
|
[clang] Annotating C++'s `operator new` with more attributes
Summary:
Right now we annotate C++'s `operator new` with `noalias` attribute,
which very much is healthy for optimizations.
However as per [[ http://eel.is/c++draft/basic.stc.dynamic.allocation | `[basic.stc.dynamic.allocation]` ]],
there are more promises on global `operator new`, namely:
* non-`std::nothrow_t` `operator new` *never* returns `nullptr`
* If `std::align_val_t align` parameter is taken, the pointer will also be `align`-aligned
* ~~global `operator new`-returned pointer is `__STDCPP_DEFAULT_NEW_ALIGNMENT__`-aligned ~~ It's more caveated than that.
Supplying this information may not cause immediate landslide effects
on any specific benchmarks, but it for sure will be healthy for optimizer
in the sense that the IR will better reflect the guarantees provided in the source code.
The caveat is `-fno-assume-sane-operator-new`, which currently prevents emitting `noalias`
attribute, and is automatically passed by Sanitizers ([[ https://bugs.llvm.org/show_bug.cgi?id=16386 | PR16386 ]]) - should it also cover these attributes?
The problem is that the flag is back-end-specific, as seen in `test/Modules/explicit-build-flags.cpp`.
But while it is okay to add `noalias` metadata in backend, we really should be adding at least
the alignment metadata to the AST, since that allows us to perform sema checks on it.
Reviewers: erichkeane, rjmccall, jdoerfert, eugenis, rsmith
Reviewed By: rsmith
Subscribers: xbolva00, jrtc27, atanasyan, nlopes, cfe-commits
Tags: #llvm, #clang
Differential Revision: https://reviews.llvm.org/D73380
2020-02-26 06:37:17 +08:00
|
|
|
// CHECK: %[[ALLOC:.*]] = call noalias nonnull align 4 i8* @_ZnwmSt11align_val_t(i64 512, i64 4)
|
|
|
|
// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 4)
|
|
|
|
void *e0() { return new (std::align_val_t(4)) A; }
|
2016-10-11 02:54:32 +08:00
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2e1v(
|
[clang] Annotating C++'s `operator new` with more attributes
Summary:
Right now we annotate C++'s `operator new` with `noalias` attribute,
which very much is healthy for optimizations.
However as per [[ http://eel.is/c++draft/basic.stc.dynamic.allocation | `[basic.stc.dynamic.allocation]` ]],
there are more promises on global `operator new`, namely:
* non-`std::nothrow_t` `operator new` *never* returns `nullptr`
* If `std::align_val_t align` parameter is taken, the pointer will also be `align`-aligned
* ~~global `operator new`-returned pointer is `__STDCPP_DEFAULT_NEW_ALIGNMENT__`-aligned ~~ It's more caveated than that.
Supplying this information may not cause immediate landslide effects
on any specific benchmarks, but it for sure will be healthy for optimizer
in the sense that the IR will better reflect the guarantees provided in the source code.
The caveat is `-fno-assume-sane-operator-new`, which currently prevents emitting `noalias`
attribute, and is automatically passed by Sanitizers ([[ https://bugs.llvm.org/show_bug.cgi?id=16386 | PR16386 ]]) - should it also cover these attributes?
The problem is that the flag is back-end-specific, as seen in `test/Modules/explicit-build-flags.cpp`.
But while it is okay to add `noalias` metadata in backend, we really should be adding at least
the alignment metadata to the AST, since that allows us to perform sema checks on it.
Reviewers: erichkeane, rjmccall, jdoerfert, eugenis, rsmith
Reviewed By: rsmith
Subscribers: xbolva00, jrtc27, atanasyan, nlopes, cfe-commits
Tags: #llvm, #clang
Differential Revision: https://reviews.llvm.org/D73380
2020-02-26 06:37:17 +08:00
|
|
|
// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 4)
|
|
|
|
// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 4)
|
|
|
|
void *e1() { return new (std::align_val_t(4)) B; }
|
2016-10-11 02:54:32 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Variadic placement/non-placement allocation functions.
|
|
|
|
// ======================================================
|
|
|
|
|
|
|
|
struct OVERALIGNED F {
|
|
|
|
F();
|
|
|
|
void *operator new(size_t, ...);
|
|
|
|
void operator delete(void*, ...);
|
|
|
|
int n[128];
|
|
|
|
};
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2f0v(
|
|
|
|
// CHECK: %[[ALLOC:.*]] = call i8* (i64, ...) @_ZN1FnwEmz(i64 512, i64 32)
|
|
|
|
// Non-placement allocation function, uses normal deallocation lookup which
|
|
|
|
// cares about whether a parameter has type std::align_val_t.
|
|
|
|
// CHECK: call void (i8*, ...) @_ZN1FdlEPvz(i8* %[[ALLOC]])
|
|
|
|
void *f0() { return new F; }
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2f1v(
|
|
|
|
// CHECK: %[[ALLOC:.*]] = call i8* (i64, ...) @_ZN1FnwEmz(i64 512, i64 32, i32 %
|
|
|
|
// Placement allocation function, uses placement deallocation matching, which
|
|
|
|
// passes same arguments and therefore includes alignment.
|
|
|
|
// CHECK: call void (i8*, ...) @_ZN1FdlEPvz(i8* %[[ALLOC]], i64 32, i32 %
|
|
|
|
void *f1() { return new (q) F; }
|
|
|
|
|
|
|
|
struct OVERALIGNED G {
|
|
|
|
G();
|
|
|
|
void *operator new(size_t, std::align_val_t, ...);
|
|
|
|
void operator delete(void*, std::align_val_t, ...);
|
|
|
|
int n[128];
|
|
|
|
};
|
|
|
|
#ifndef UNALIGNED
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2g0v
|
|
|
|
// CHECK: %[[ALLOC:.*]] = call i8* (i64, i64, ...) @_ZN1GnwEmSt11align_val_tz(i64 512, i64 32)
|
|
|
|
// CHECK: call void (i8*, i64, ...) @_ZN1GdlEPvSt11align_val_tz(i8* %[[ALLOC]], i64 32)
|
|
|
|
void *g0() { return new G; }
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z2g1v
|
|
|
|
// CHECK: %[[ALLOC:.*]] = call i8* (i64, i64, ...) @_ZN1GnwEmSt11align_val_tz(i64 512, i64 32, i32 %
|
|
|
|
// CHECK: call void (i8*, i64, ...) @_ZN1GdlEPvSt11align_val_tz(i8* %[[ALLOC]], i64 32, i32 %
|
|
|
|
void *g1() { return new (q) G; }
|
|
|
|
#endif
|