mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-25 06:18:56 -04:00

Fixes <rdar://problem/15584219> and <rdar://problem/12241361>. This change looks large, but all it does is reuse and consolidate the delayed diagnostic logic for deprecation warnings with unavailability warnings. By doing so, it showed various inconsistencies between the diagnostics, which were close, but not consistent. It also revealed some missing "note:"'s in the deprecated diagnostics that were showing up in the unavailable diagnostics, etc. This change also changes the wording of the core deprecation diagnostics. Instead of saying "function has been explicitly marked deprecated" we now saw "'X' has been been explicitly marked deprecated". It turns out providing a bit more context is useful, and often we got the actual term wrong or it was not very precise (e.g., "function" instead of "destructor"). By just saying the name of the thing that is deprecated/deleted/unavailable we define this issue away. This diagnostic can likely be further wordsmithed to be shorter. llvm-svn: 197627
113 lines
3.6 KiB
C++
113 lines
3.6 KiB
C++
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
|
|
|
|
template<typename T>
|
|
class unique_ptr {
|
|
T *ptr;
|
|
|
|
unique_ptr(const unique_ptr&) = delete; // expected-note 3{{'unique_ptr' has been explicitly marked deleted here}}
|
|
unique_ptr &operator=(const unique_ptr&) = delete; // expected-note{{candidate function has been explicitly deleted}}
|
|
public:
|
|
unique_ptr() : ptr(0) { }
|
|
unique_ptr(unique_ptr &&other) : ptr(other.ptr) { other.ptr = 0; }
|
|
explicit unique_ptr(T *ptr) : ptr(ptr) { }
|
|
|
|
~unique_ptr() { delete ptr; }
|
|
|
|
unique_ptr &operator=(unique_ptr &&other) { // expected-note{{candidate function not viable: no known conversion from 'unique_ptr<int>' to 'unique_ptr<int> &&' for 1st argument}}
|
|
if (this == &other)
|
|
return *this;
|
|
|
|
delete ptr;
|
|
ptr = other.ptr;
|
|
other.ptr = 0;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
struct remove_reference {
|
|
typedef T type;
|
|
};
|
|
|
|
template<typename T>
|
|
struct remove_reference<T&> {
|
|
typedef T type;
|
|
};
|
|
|
|
template<typename T>
|
|
struct remove_reference<T&&> {
|
|
typedef T type;
|
|
};
|
|
|
|
|
|
template <class T> typename remove_reference<T>::type&& move(T&& t) {
|
|
return static_cast<typename remove_reference<T>::type&&>(t);
|
|
}
|
|
|
|
template <class T> T&& forward(typename remove_reference<T>::type& t) {
|
|
return static_cast<T&&>(t);
|
|
}
|
|
|
|
template <class T> T&& forward(typename remove_reference<T>::type&& t) {
|
|
return static_cast<T&&>(t);
|
|
}
|
|
|
|
template<typename T, typename ...Args>
|
|
unique_ptr<T> make_unique_ptr(Args &&...args) {
|
|
return unique_ptr<T>(new T(forward<Args>(args)...));
|
|
}
|
|
|
|
template<typename T> void accept_unique_ptr(unique_ptr<T>); // expected-note{{passing argument to parameter here}}
|
|
|
|
unique_ptr<int> test_unique_ptr() {
|
|
// Simple construction
|
|
unique_ptr<int> p;
|
|
unique_ptr<int> p1(new int);
|
|
|
|
// Move construction
|
|
unique_ptr<int> p2(make_unique_ptr<int>(17));
|
|
unique_ptr<int> p3 = make_unique_ptr<int>(17);
|
|
|
|
// Copy construction (failures)
|
|
unique_ptr<int> p4(p); // expected-error{{call to deleted constructor of 'unique_ptr<int>'}}
|
|
unique_ptr<int> p5 = p; // expected-error{{call to deleted constructor of 'unique_ptr<int>'}}
|
|
|
|
// Move assignment
|
|
p2 = move(p);
|
|
p2 = make_unique_ptr<int>(0);
|
|
|
|
// Copy assignment (failures);
|
|
p2 = p3; // expected-error{{overload resolution selected deleted operator '='}}
|
|
|
|
// Implicit copies
|
|
accept_unique_ptr(make_unique_ptr<double>(0.0));
|
|
accept_unique_ptr(move(p2));
|
|
|
|
// Implicit copies (failures);
|
|
accept_unique_ptr(p); // expected-error{{call to deleted constructor of 'unique_ptr<int>'}}
|
|
|
|
return p;
|
|
}
|
|
|
|
namespace perfect_forwarding {
|
|
struct A { };
|
|
|
|
struct F0 {
|
|
void operator()(A&, const A&, A&&, const A&&, A&&, const A&&); // expected-note{{candidate function not viable: 5th argument ('const perfect_forwarding::A') would lose const qualifier}}
|
|
};
|
|
|
|
template<typename F, typename ...Args>
|
|
void forward(F f, Args &&...args) {
|
|
f(static_cast<Args&&>(args)...); // expected-error{{no matching function for call to object of type 'perfect_forwarding::F0'}}
|
|
}
|
|
|
|
template<typename T> T get();
|
|
|
|
void test_forward() {
|
|
forward(F0(), get<A&>(), get<A const&>(), get<A>(), get<const A>(),
|
|
get<A&&>(), get<const A&&>());
|
|
forward(F0(), get<A&>(), get<A const&>(), get<A>(), get<const A>(), // expected-note{{in instantiation of function template specialization 'perfect_forwarding::forward<perfect_forwarding::F0, perfect_forwarding::A &, const perfect_forwarding::A &, perfect_forwarding::A, const perfect_forwarding::A, const perfect_forwarding::A, const perfect_forwarding::A>' requested here}}
|
|
get<const A&&>(), get<const A&&>());
|
|
}
|
|
};
|