| Index: tools/clang/plugins/tests/base_passed.cpp
|
| diff --git a/tools/clang/plugins/tests/base_passed.cpp b/tools/clang/plugins/tests/base_passed.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7dc65d14b442ed439cb7703cb18d46f7e36ed13c
|
| --- /dev/null
|
| +++ b/tools/clang/plugins/tests/base_passed.cpp
|
| @@ -0,0 +1,58 @@
|
| +#define MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \
|
| + public: \
|
| + struct rvalue_type { \
|
| + explicit rvalue_type(type* object) : object(object) {} \
|
| + type* object; \
|
| + }; \
|
| + type(type&); \
|
| + void operator=(type&); \
|
| + operator rvalue_type() { return rvalue_type(this); } \
|
| + type Pass() { return type(rvalue_type(this)); } \
|
| + typedef void MoveOnlyTypeForCPP03; \
|
| + private:
|
| +
|
| +namespace base {
|
| +template <class T>
|
| +class scoped_ptr {
|
| + MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
|
| + public:
|
| + typedef T element_type;
|
| + scoped_ptr() { }
|
| + explicit scoped_ptr(element_type* p) { }
|
| + scoped_ptr(RValue rvalue) { }
|
| + template <typename U>
|
| + scoped_ptr& operator=(scoped_ptr<U> rhs) { return *this; }
|
| + element_type* get() const { return 0; }
|
| +};
|
| +
|
| +template <typename T>
|
| +static inline T Passed(T scoper) {
|
| + return scoper.Pass();
|
| +}
|
| +template <typename T>
|
| +static inline T Passed(T* scoper) {
|
| + return scoper->Pass();
|
| +}
|
| +
|
| +}
|
| +
|
| +void f_bad(base::scoped_ptr<int> i, int* p) {}
|
| +
|
| +void f_ok(base::scoped_ptr<int> i) {}
|
| +
|
| +int h_bad1(base::scoped_ptr<int> i) { return 0; }
|
| +int h_bad2(int* i) { return 0; }
|
| +int h(int a, int b) { return 0; }
|
| +
|
| +void g() {
|
| + base::scoped_ptr<int> s;
|
| +
|
| + f_bad(base::Passed(&s), s.get());
|
| + f_bad(base::Passed(s.Pass()), s.get());
|
| +
|
| + // Shouldn't warn.
|
| + f_ok(base::Passed(&s));
|
| +
|
| + h(h_bad1(base::Passed(&s)),
|
| + h_bad2(s.get()));
|
| +}
|
|
|