237 lines
7.8 KiB
C++
237 lines
7.8 KiB
C++
// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
|
|
// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
|
|
|
|
namespace std {
|
|
template<typename T> struct initializer_list {
|
|
const T *begin, *end;
|
|
initializer_list();
|
|
};
|
|
} // namespace std
|
|
|
|
enum class N {};
|
|
|
|
using Animal = int;
|
|
|
|
using AnimalPtr = Animal *;
|
|
|
|
using Man = Animal;
|
|
using Dog = Animal;
|
|
|
|
using ManPtr = Man *;
|
|
using DogPtr = Dog *;
|
|
|
|
using SocratesPtr = ManPtr;
|
|
|
|
using ConstMan = const Man;
|
|
using ConstDog = const Dog;
|
|
|
|
using Virus = void;
|
|
using SARS = Virus;
|
|
using Ebola = Virus;
|
|
|
|
using Bacteria = float;
|
|
using Bacilli = Bacteria;
|
|
using Vibrio = Bacteria;
|
|
|
|
struct Plant;
|
|
using Gymnosperm = Plant;
|
|
using Angiosperm = Plant;
|
|
|
|
namespace variable {
|
|
|
|
auto x1 = Animal();
|
|
N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
|
|
|
|
auto x2 = AnimalPtr();
|
|
N t2 = x2; // expected-error {{lvalue of type 'AnimalPtr' (aka 'int *')}}
|
|
|
|
auto *x3 = AnimalPtr();
|
|
N t3 = x3; // expected-error {{lvalue of type 'Animal *' (aka 'int *')}}
|
|
|
|
// Each variable deduces separately.
|
|
auto x4 = Man(), x5 = Dog();
|
|
N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
|
|
N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
|
|
|
|
auto x6 = { Man(), Dog() };
|
|
N t6 = x6; // expected-error {{from 'std::initializer_list<Animal>' (aka 'initializer_list<int>')}}
|
|
|
|
} // namespace variable
|
|
|
|
namespace function_basic {
|
|
|
|
auto f1() { return Animal(); }
|
|
auto x1 = f1();
|
|
N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
|
|
|
|
decltype(auto) f2() { return Animal(); }
|
|
auto x2 = f2();
|
|
N t2 = x2; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
|
|
|
|
auto x3 = [a = Animal()] { return a; }();
|
|
N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
|
|
|
|
} // namespace function_basic
|
|
|
|
namespace function_multiple_basic {
|
|
|
|
N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
|
|
if (true)
|
|
return Man();
|
|
return Dog();
|
|
}();
|
|
|
|
N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
|
|
if (true)
|
|
return Man();
|
|
return Dog();
|
|
}();
|
|
|
|
N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
|
|
if (true)
|
|
return Dog();
|
|
auto x = Man();
|
|
return x;
|
|
}();
|
|
|
|
N t4 = [] { // expected-error {{rvalue of type 'int'}}
|
|
if (true)
|
|
return Dog();
|
|
return 1;
|
|
}();
|
|
|
|
N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
|
|
if (true)
|
|
return Ebola();
|
|
return SARS();
|
|
}();
|
|
|
|
N t6 = [] { // expected-error {{rvalue of type 'void'}}
|
|
if (true)
|
|
return SARS();
|
|
return;
|
|
}();
|
|
|
|
} // namespace function_multiple_basic
|
|
|
|
#define TEST_AUTO(X, A, B) \
|
|
static_assert(__is_same(A, B), ""); \
|
|
auto X(A a, B b) { \
|
|
if (0) \
|
|
return a; \
|
|
if (0) \
|
|
return b; \
|
|
return N(); \
|
|
}
|
|
#define TEST_DAUTO(X, A, B) \
|
|
static_assert(__is_same(A, B), ""); \
|
|
decltype(auto) X(A a, B b) { \
|
|
if (0) \
|
|
return static_cast<A>(a); \
|
|
if (0) \
|
|
return static_cast<B>(b); \
|
|
return N(); \
|
|
}
|
|
|
|
namespace misc {
|
|
|
|
TEST_AUTO(t1, ManPtr, DogPtr) // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
|
|
TEST_AUTO(t2, ManPtr, int *) // expected-error {{but deduced as 'int *'}}
|
|
TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
|
|
|
|
TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
|
|
|
|
using block_man = void (^)(Man);
|
|
using block_dog = void (^)(Dog);
|
|
TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^__strong)(Animal)'}}
|
|
|
|
#if __cplusplus >= 201500
|
|
using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
|
|
using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
|
|
TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
|
|
|
|
using fp3 = SARS (*)() throw(Man);
|
|
using fp4 = Ebola (*)() throw(Vibrio);
|
|
auto t7(fp3 a, fp4 b) {
|
|
if (false)
|
|
return true ? a : b;
|
|
if (false)
|
|
return a;
|
|
return N(); // expected-error {{but deduced as 'Virus (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
|
|
}
|
|
#endif
|
|
|
|
using fp5 = void (*)(const Man);
|
|
using fp6 = void (*)(Dog);
|
|
TEST_AUTO(t8, fp5, fp6); // expected-error {{but deduced as 'void (*)(Animal)' (aka 'void (*)(int)')}}
|
|
|
|
using fp7 = void (*)(ConstMan);
|
|
using fp8 = void (*)(ConstDog);
|
|
TEST_AUTO(t9, fp7, fp8); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
|
|
|
|
using fp9 = void (*)(ConstMan);
|
|
using fp10 = void (*)(const Dog);
|
|
TEST_AUTO(t10, fp9, fp10); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
|
|
|
|
using fp11 = void (*)(__strong block_man);
|
|
using fp12 = void (*)(__weak block_dog);
|
|
TEST_AUTO(t11, fp11, fp12); // expected-error {{but deduced as 'void (*)(void (^)(Animal))'}}
|
|
|
|
TEST_AUTO(t12, Man Angiosperm::*, Dog Gymnosperm::*) // expected-error {{but deduced as 'Animal Plant::*'}}
|
|
|
|
TEST_DAUTO(t13, const Man &, const Dog &) // expected-error {{but deduced as 'const Animal &' (aka 'const int &')}}
|
|
|
|
TEST_DAUTO(t14, Man &&, Dog &&) // expected-error {{but deduced as 'Animal &&' (aka 'int &&')}}
|
|
|
|
using matrix_man = Man __attribute__((matrix_type(4, 4)));
|
|
using matrix_dog = Dog __attribute__((matrix_type(4, 4)));
|
|
TEST_AUTO(t15, matrix_man, matrix_dog) // expected-error {{but deduced as 'Animal __attribute__((matrix_type(4, 4)))'}}
|
|
|
|
using vector_man = Man __attribute__((vector_size(4)));
|
|
using vector_dog = Dog __attribute__((vector_size(4)));
|
|
TEST_AUTO(t16, vector_man, vector_dog) // expected-error {{but deduced as '__attribute__((__vector_size__(1 * sizeof(Animal)))) Animal' (vector of 1 'Animal' value)}}
|
|
|
|
using ext_vector_man = Man __attribute__((ext_vector_type(4)));
|
|
using ext_vector_dog = Dog __attribute__((ext_vector_type(4)));
|
|
TEST_AUTO(t17, ext_vector_man, ext_vector_dog) // expected-error {{but deduced as 'Animal __attribute__((ext_vector_type(4)))' (vector of 4 'Animal' values)}}
|
|
|
|
using TwoDogs = Dog[2];
|
|
using ConstTwoDogsPtr = const TwoDogs*;
|
|
using ConstTwoMenPtr = const Man(*)[2];
|
|
TEST_AUTO(t18, ConstTwoDogsPtr, ConstTwoMenPtr); // expected-error {{but deduced as 'const Animal (*)[2]' (aka 'const int (*)[2]')}}
|
|
|
|
} // namespace misc
|
|
|
|
namespace exception_spec {
|
|
|
|
void none();
|
|
void dyn_none() throw();
|
|
void dyn() throw(int);
|
|
void ms_any() throw(...);
|
|
void __declspec(nothrow) nothrow();
|
|
void noexcept_basic() noexcept;
|
|
void noexcept_true() noexcept(true);
|
|
void noexcept_false() noexcept(false);
|
|
|
|
#if __cplusplus < 201500
|
|
TEST_AUTO(t1, decltype(&noexcept_false), decltype(&noexcept_true)) // expected-error {{but deduced as 'void (*)() noexcept(false)'}}
|
|
TEST_AUTO(t2, decltype(&noexcept_basic), decltype(&noexcept_true)) // expected-error {{but deduced as 'void (*)() noexcept(true)'}}
|
|
TEST_AUTO(t3, decltype(&none), decltype(&ms_any)) // expected-error {{but deduced as 'void (*)()'}}
|
|
TEST_AUTO(t4, decltype(&noexcept_false), decltype(&ms_any)) // expected-error {{but deduced as 'void (*)() throw(...)'}}
|
|
TEST_AUTO(t5, decltype(¬hrow), decltype(&noexcept_false)) // expected-error {{but deduced as 'void (*)() noexcept(false)'}}
|
|
TEST_AUTO(t6, decltype(&dyn_none), decltype(¬hrow)) // expected-error {{but deduced as 'void (*)() throw()'}}
|
|
TEST_AUTO(t7, decltype(&noexcept_true), decltype(&dyn)) // expected-error {{but deduced as 'void (*)() throw(int)'}}
|
|
#endif
|
|
} // namespace exception_spec
|
|
|
|
namespace non_deduced {
|
|
void f();
|
|
void g();
|
|
void g(int);
|
|
auto h() {
|
|
if (false) return f;
|
|
return g;
|
|
// expected-error@-1 {{returned value of type '<overloaded function type>'}}
|
|
}
|
|
} // namespace non_deduced
|