// 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 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' (aka 'initializer_list')}} } // 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); \ if (0) \ return static_cast(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 ''}} } } // namespace non_deduced