Skip to content

Commit c3aaf96

Browse files
committed
[Clang] Add tests for placeholder exprs in placement-args of new-expression
1 parent 2a14421 commit c3aaf96

8 files changed

+244
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -std=c++11 -emit-llvm -o - %s | FileCheck %s
2+
3+
struct S {
4+
void* operator new(__SIZE_TYPE__, int);
5+
};
6+
7+
int main() {
8+
// CHECK: call {{.*}} ptr @"??2S@@SAPEAX_KH@Z"(i64 {{.*}} 1, i32 {{.*}} 0)
9+
// CHECK: call {{.*}} ptr @"??2S@@SAPEAX_KH@Z"(i64 {{.*}} 1, i32 {{.*}} 0)
10+
new (__noop) S;
11+
new ((__noop)) S;
12+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// RUN: %clang_cc1 -x objective-c++ -std=c++11 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
2+
3+
// CHECK: [[NAME:@.*]] = private unnamed_addr constant [9 x i8] c"position\00"
4+
// CHECK: [[SEL:@.*]] = internal externally_initialized global ptr [[NAME]]
5+
6+
@interface I {
7+
int position;
8+
}
9+
@property(nonatomic) int position;
10+
@end
11+
12+
struct S {
13+
void *operator new(__SIZE_TYPE__, int);
14+
};
15+
16+
template <typename T>
17+
struct TS {
18+
void *operator new(__SIZE_TYPE__, T);
19+
};
20+
21+
I *GetI();
22+
23+
int main() {
24+
@autoreleasepool {
25+
// CHECK: [[I:%.+]] = alloca ptr
26+
auto* i = GetI();
27+
i.position = 42;
28+
29+
// This is so we can find the next line more easily.
30+
// CHECK: store double
31+
double d = 42.0;
32+
33+
// CHECK: [[I1:%.+]] = load ptr, ptr [[I]]
34+
// CHECK-NEXT: [[SEL1:%.+]] = load ptr, ptr [[SEL]]
35+
// CHECK-NEXT: [[POS1:%.+]] = call {{.*}} i32 @objc_msgSend(ptr {{.*}} [[I1]], ptr {{.*}} [[SEL1]])
36+
// CHECK-NEXT: call {{.*}} ptr @_ZN1SnwEmi(i64 {{.*}} 1, i32 {{.*}} [[POS1]])
37+
new (i.position) S;
38+
39+
// CHECK: [[I2:%.+]] = load ptr, ptr [[I]]
40+
// CHECK-NEXT: [[SEL2:%.+]] = load ptr, ptr [[SEL]]
41+
// CHECK-NEXT: [[POS2:%.+]] = call {{.*}} i32 @objc_msgSend(ptr {{.*}} [[I2]], ptr {{.*}} [[SEL2]])
42+
// CHECK-NEXT: [[DBL:%.+]] = sitofp i32 [[POS2]] to double
43+
// CHECK-NEXT: call {{.*}} ptr @_ZN2TSIdEnwEmd(i64 {{.*}} 1, double {{.*}} [[DBL]])
44+
new (i.position) TS<double>;
45+
}
46+
}

clang/test/SemaCXX/builtin-std-move.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace std {
1212
template<typename T> CONSTEXPR T &&move(T &x) {
1313
static_assert(T::moveable, "instantiated move"); // expected-error {{no member named 'moveable' in 'B'}}
1414
// expected-error@-1 {{no member named 'moveable' in 'C'}}
15+
// expected-error@-2 {{no member named 'moveable' in 'D'}}
1516
return static_cast<T&&>(x);
1617
}
1718

@@ -23,6 +24,7 @@ namespace std {
2324

2425
template<typename T> CONSTEXPR auto move_if_noexcept(T &x) -> typename ref<T, noexcept(T(static_cast<T&&>(x)))>::type {
2526
static_assert(T::moveable, "instantiated move_if_noexcept"); // expected-error {{no member named 'moveable' in 'B'}}
27+
// expected-error@-1 {{no member named 'moveable' in 'D'}}
2628
return static_cast<typename ref<T, noexcept(T(static_cast<T&&>(x)))>::type>(x);
2729
}
2830

@@ -36,6 +38,7 @@ namespace std {
3638
template<typename T> CONSTEXPR T &&forward(typename remove_reference<T>::type &x) {
3739
static_assert(T::moveable, "instantiated forward"); // expected-error {{no member named 'moveable' in 'B'}}
3840
// expected-error@-1 {{no member named 'moveable' in 'C'}}
41+
// expected-error@-2 {{no member named 'moveable' in 'D'}}
3942
return static_cast<T&&>(x);
4043
}
4144
template<typename T> CONSTEXPR T &&forward(typename remove_reference<T>::type &&x) {
@@ -67,21 +70,25 @@ namespace std {
6770
CONSTEXPR auto forward_like(T &&t) -> ForwardLikeRetType<U, T> {
6871
using TT = typename remove_reference<T>::type;
6972
static_assert(TT::moveable, "instantiated as_const"); // expected-error {{no member named 'moveable' in 'B'}}
73+
// expected-error@-1 {{no member named 'moveable' in 'D'}}
7074
return static_cast<ForwardLikeRetType<U, T>>(t);
7175
}
7276

7377
template<typename T> CONSTEXPR const T &as_const(T &x) {
7478
static_assert(T::moveable, "instantiated as_const"); // expected-error {{no member named 'moveable' in 'B'}}
79+
// expected-error@-1 {{no member named 'moveable' in 'D'}}
7580
return x;
7681
}
7782

7883
template<typename T> CONSTEXPR T *addressof(T &x) {
7984
static_assert(T::moveable, "instantiated addressof"); // expected-error {{no member named 'moveable' in 'B'}}
85+
// expected-error@-1 {{no member named 'moveable' in 'D'}}
8086
return __builtin_addressof(x);
8187
}
8288

8389
template<typename T> CONSTEXPR T *__addressof(T &x) {
8490
static_assert(T::moveable, "instantiated __addressof"); // expected-error {{no member named 'moveable' in 'B'}}
91+
// expected-error@-1 {{no member named 'moveable' in 'D'}}
8592
return __builtin_addressof(x);
8693
}
8794
}
@@ -163,6 +170,40 @@ void attribute_const() {
163170
std::as_const(n); // expected-warning {{ignoring return value}}
164171
}
165172

173+
struct D {
174+
void* operator new(__SIZE_TYPE__, D&&(*)(D&));
175+
void* operator new(__SIZE_TYPE__, D*(*)(D&));
176+
void* operator new(__SIZE_TYPE__, const D&(*)(D&));
177+
};
178+
179+
#if __cplusplus <= 201703L
180+
// expected-warning@#10 {{non-addressable}}
181+
// expected-warning@#11 {{non-addressable}}
182+
// expected-warning@#12 {{non-addressable}}
183+
// expected-warning@#13 {{non-addressable}}
184+
// expected-warning@#14 {{non-addressable}}
185+
// expected-warning@#15 {{non-addressable}}
186+
// expected-warning@#16 {{non-addressable}}
187+
#else
188+
// expected-error@#10 {{non-addressable}}
189+
// expected-error@#11 {{non-addressable}}
190+
// expected-error@#12 {{non-addressable}}
191+
// expected-error@#13 {{non-addressable}}
192+
// expected-error@#14 {{non-addressable}}
193+
// expected-error@#15 {{non-addressable}}
194+
// expected-error@#16 {{non-addressable}}
195+
#endif
196+
197+
void placement_new() {
198+
new (std::move<D>) D; // #10 expected-note {{instantiation of}}
199+
new (std::move_if_noexcept<D>) D; // #11 expected-note {{instantiation of}}
200+
new (std::forward<D>) D; // #12 expected-note {{instantiation of}}
201+
new (std::forward_like<D>) D; // #13 expected-note {{instantiation of}}
202+
new (std::addressof<D>) D; // #14 expected-note {{instantiation of}}
203+
new (std::__addressof<D>) D; // #15 expected-note {{instantiation of}}
204+
new (std::as_const<D>) D; // #16 expected-note {{instantiation of}}
205+
}
206+
166207
namespace std {
167208
template<typename T> int &move(T);
168209
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
2+
3+
struct S {
4+
int NoArgs();
5+
int OneArg(int);
6+
7+
template <typename T>
8+
T TemplNoArgs(); // expected-note {{possible target for call}} // expected-note {{possible target for call}}
9+
10+
template <typename T>
11+
T TemplOneArg(T); // expected-note {{possible target for call}} // expected-note {{possible target for call}}
12+
13+
void* operator new(__SIZE_TYPE__, int);
14+
};
15+
16+
S* GetS();
17+
18+
int test() {
19+
S s, *ps = GetS();
20+
int (S::*pNoArgs)() = &S::NoArgs;
21+
int (S::*pOneArg)(int) = &S::OneArg;
22+
int (S::*pTemplNoArgs)() = &S::TemplNoArgs<int>;
23+
int (S::*pTemplOneArg)(int) = &S::TemplOneArg<int>;
24+
25+
new (s.NoArgs()) S;
26+
new (s.OneArg(1)) S;
27+
new (ps->NoArgs()) S;
28+
new (ps->OneArg(1)) S;
29+
new ((s.*pNoArgs)()) S;
30+
new ((s.*pOneArg)(1)) S;
31+
new ((ps->*pNoArgs)()) S;
32+
new ((ps->*pOneArg)(1)) S;
33+
34+
new (s.TemplNoArgs<int>()) S;
35+
new (s.TemplOneArg<int>(1)) S;
36+
new (ps->TemplNoArgs<int>()) S;
37+
new (ps->TemplOneArg<int>(1)) S;
38+
new ((s.*pTemplNoArgs)()) S;
39+
new ((s.*pTemplOneArg)(1)) S;
40+
new ((ps->*pTemplNoArgs)()) S;
41+
new ((ps->*pTemplOneArg)(1)) S;
42+
43+
new (s.NoArgs) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
44+
new (s.OneArg) S; // expected-error {{reference to non-static member function must be called}}
45+
new (ps->NoArgs) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
46+
new (ps->OneArg) S; // expected-error {{reference to non-static member function must be called}}
47+
new (s.*pNoArgs) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
48+
new (s.*pOneArg) S; // expected-error {{reference to non-static member function must be called}}
49+
new (ps->*pNoArgs) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
50+
new (ps->*pOneArg) S; // expected-error {{reference to non-static member function must be called}}
51+
new ((s.*pNoArgs)) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
52+
new ((s.*pOneArg)) S; // expected-error {{reference to non-static member function must be called}}
53+
new ((ps->*pNoArgs)) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
54+
new ((ps->*pOneArg)) S; // expected-error {{reference to non-static member function must be called}}
55+
56+
new (s.TemplNoArgs<int>) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
57+
new (s.TemplOneArg<int>) S; // expected-error {{reference to non-static member function must be called}}
58+
new (ps->TemplNoArgs<int>) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
59+
new (ps->TemplOneArg<int>) S; // expected-error {{reference to non-static member function must be called}}
60+
new (s.*pTemplNoArgs) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
61+
new (s.*pTemplOneArg) S; // expected-error {{reference to non-static member function must be called}}
62+
new (ps->*pTemplNoArgs) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
63+
new (ps->*pTemplOneArg) S; // expected-error {{reference to non-static member function must be called}}
64+
new ((s.*pTemplNoArgs)) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
65+
new ((s.*pTemplOneArg)) S; // expected-error {{reference to non-static member function must be called}}
66+
new ((ps->*pTemplNoArgs)) S; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
67+
new ((ps->*pTemplOneArg)) S; // expected-error {{reference to non-static member function must be called}}
68+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
2+
3+
struct S {
4+
void* operator new(__SIZE_TYPE__, char*);
5+
void* operator new(__SIZE_TYPE__, __SIZE_TYPE__);
6+
};
7+
8+
int main() {
9+
new (__builtin_strchr) S; // expected-error {{builtin functions must be directly called}}
10+
new ((__builtin_strlen)) S; // expected-error {{builtin functions must be directly called}}
11+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_cc1 -fenable-matrix -fsyntax-only -verify %s -std=c++11
2+
3+
using Matrix = int __attribute__((matrix_type(4, 3)));
4+
5+
template <__SIZE_TYPE__ a, __SIZE_TYPE__ b>
6+
using TMatrix = int __attribute__((matrix_type(a, b)));
7+
8+
struct S {
9+
void* operator new(__SIZE_TYPE__, int);
10+
void* operator new(__SIZE_TYPE__, Matrix);
11+
void* operator new(__SIZE_TYPE__, TMatrix<2, 2>);
12+
};
13+
14+
int main() {
15+
Matrix m;
16+
TMatrix<2, 2> tm;
17+
18+
new (m) S {};
19+
new (tm) S {};
20+
21+
new (m[1][1]) S {};
22+
new (tm[1][1]) S {};
23+
24+
new (m[1]) S {}; // expected-error {{single subscript expressions are not allowed for matrix values}}
25+
new (tm[1]) S {}; // expected-error {{single subscript expressions are not allowed for matrix values}}
26+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -fsyntax-only -fms-extensions -verify %s -std=c++11
2+
// expected-no-diagnostics
3+
4+
struct S {
5+
void* operator new(__SIZE_TYPE__, int);
6+
};
7+
8+
int main() {
9+
// MSVC supports __noop with no arguments or (), so we do as well.
10+
new (__noop) S;
11+
new ((__noop)) S;
12+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wno-objc-root-class %s
2+
// expected-no-diagnostics
3+
4+
@interface I {
5+
int position;
6+
}
7+
@property(nonatomic) int position;
8+
@end
9+
10+
struct S {
11+
void *operator new(__SIZE_TYPE__, int);
12+
};
13+
14+
template <typename T>
15+
struct TS {
16+
void *operator new(__SIZE_TYPE__, T);
17+
};
18+
19+
I *GetI();
20+
21+
int main() {
22+
@autoreleasepool {
23+
auto* i = GetI();
24+
i.position = 42;
25+
new (i.position) S;
26+
new (i.position) TS<double>;
27+
}
28+
}

0 commit comments

Comments
 (0)