// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++98 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,cxx98 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++14 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11,since-cxx14 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11,since-cxx14 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11,since-cxx14,since-cxx20 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11,since-cxx14,since-cxx20,since-cxx23 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++2c -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11,since-cxx14,since-cxx20,since-cxx23,since-cxx26 #if __cplusplus == 199711L #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) // cxx98-error@-1 {{variadic macros are a C99 feature}} #endif #if __cplusplus == 199711L #define __enable_constant_folding(x) (__builtin_constant_p(x) ? (x) : (x)) #else #define __enable_constant_folding #endif namespace std { #if __cplusplus >= 201103L using size_t = decltype(sizeof(0)); template struct initializer_list { const T *p; size_t n; #if __cplusplus >= 201402L constexpr #endif initializer_list(const T *p, size_t n); #if __cplusplus >= 201402L constexpr #endif const T* begin() const { return p; }; }; #endif #if __cplusplus >= 202002L struct strong_ordering { int n; constexpr operator int() const { return n; } static const strong_ordering less, equal, greater; }; constexpr strong_ordering strong_ordering::less{-1}, strong_ordering::equal{0}, strong_ordering::greater{1}; #endif } // namespace std namespace cwg2707 { // cwg2707: 20 #if __cplusplus >= 202002L template struct A { // #cwg2707-A T value[N]; }; template A(T...) -> A requires (sizeof...(T) == 2); // #cwg2707-guide-A // Brace elision is not allowed for synthesized CTAD guides if the array size // is value-dependent. // So this should pick up our explicit deduction guide. A a = {1, 2}; A b = {3, 4, 5}; // since-cxx20-error@-1 {{no viable constructor or deduction guide for deduction of template arguments of 'A'}} // since-cxx20-note@#cwg2707-A {{candidate function template not viable: requires 1 argument, but 3 were provided}} // since-cxx20-note@#cwg2707-A {{implicit deduction guide declared as 'template A(cwg2707::A) -> cwg2707::A'}} // since-cxx20-note@#cwg2707-guide-A {{candidate template ignored: constraints not satisfied [with T = ]}} // since-cxx20-note@#cwg2707-guide-A {{because 'sizeof...(T) == 2' (3 == 2) evaluated to false}} // since-cxx20-note@#cwg2707-A {{candidate function template not viable: requires 0 arguments, but 3 were provided}} // since-cxx20-note@#cwg2707-A {{implicit deduction guide declared as 'template A() -> cwg2707::A'}} #endif } // namespace cwg2707 namespace cwg2718 { // cwg2718: 2.7 struct B {}; struct D; void f(B b) { static_cast(b); // expected-error@-1 {{non-const lvalue reference to type 'D' cannot bind to a value of unrelated type 'B'}} } struct D : B {}; } // namespace cwg2718 namespace cwg2749 { // cwg2749: 20 extern int x[2]; struct Y { int i; int j; }; extern Y y[2]; static_assert(__enable_constant_folding(static_cast(&x[0]) < static_cast(&x[1])), ""); static_assert(__enable_constant_folding(static_cast(&y[0].i) < static_cast(&y[0].j)), ""); static_assert(__enable_constant_folding(static_cast(&y[0].j) < static_cast(&y[1].i)), ""); #if __cplusplus >= 202002L static_assert((static_cast(&x[0]) <=> static_cast(&x[1])) == std::strong_ordering::less); static_assert((static_cast(&y[0].i) <=> static_cast(&y[0].j)) == std::strong_ordering::less); static_assert((static_cast(&y[0].j) <=> static_cast(&y[1].i)) == std::strong_ordering::less); #endif } // namespace cwg2749 namespace cwg2759 { // cwg2759: 19 #if __cplusplus >= 201103L struct CStruct { int one; int two; }; struct CEmptyStruct {}; struct CEmptyStruct2 {}; struct CStructNoUniqueAddress { int one; [[no_unique_address]] int two; }; struct CStructNoUniqueAddress2 { int one; [[no_unique_address]] int two; }; union UnionLayout { int a; double b; CStruct c; [[no_unique_address]] CEmptyStruct d; [[no_unique_address]] CEmptyStruct2 e; }; union UnionLayout2 { CStruct c; int a; CEmptyStruct2 e; double b; [[no_unique_address]] CEmptyStruct d; }; union UnionLayout3 { CStruct c; int a; double b; [[no_unique_address]] CEmptyStruct d; }; struct StructWithAnonUnion { union { int a; double b; CStruct c; [[no_unique_address]] CEmptyStruct d; [[no_unique_address]] CEmptyStruct2 e; }; }; struct StructWithAnonUnion2 { union { CStruct c; int a; CEmptyStruct2 e; double b; [[no_unique_address]] CEmptyStruct d; }; }; struct StructWithAnonUnion3 { union { CStruct c; int a; CEmptyStruct2 e; double b; [[no_unique_address]] CEmptyStruct d; } u; }; static_assert(__is_layout_compatible(CStruct, CStructNoUniqueAddress) != bool(__has_cpp_attribute(no_unique_address)), ""); static_assert(__is_layout_compatible(CStructNoUniqueAddress, CStructNoUniqueAddress2) != bool(__has_cpp_attribute(no_unique_address)), ""); static_assert(!__is_layout_compatible(UnionLayout, UnionLayout2), ""); static_assert(!__is_layout_compatible(UnionLayout, UnionLayout3), ""); static_assert(!__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion2), ""); static_assert(!__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion3), ""); #endif } // namespace cwg2759 namespace cwg2765 { // cwg2765: partial static_assert(+"foo" == "foo", ""); // expected-error@-1 {{static assertion expression is not an integral constant expression}} // expected-note@-2 {{comparison of addresses of potentially overlapping literals has unspecified value}} static_assert("xfoo" + 1 == "foo\0y", ""); // expected-warning@-1 {{adding 'int' to a string does not append to the string}} // expected-note@-2 {{use array indexing to silence this warning}} // expected-error@-3 {{static assertion expression is not an integral constant expression}} // expected-note@-4 {{comparison of addresses of potentially overlapping literals has unspecified value}} static_assert("foo" + 0 != "bar", ""); // expected-warning@-1 {{adding 'int' to a string does not append to the string}} // expected-note@-2 {{use array indexing to silence this warning}} // cxx98-error@-3 {{static assertion expression is not an integral constant expression}} FIXME static_assert((const char*)"foo" != "oo", ""); // cxx98-error@-1 {{static assertion expression is not an integral constant expression}} FIXME #if __cplusplus >= 201103L constexpr const char *f() { return "foo"; } constexpr bool b2 = f() == f(); // since-cxx11-error@-1 {{constexpr variable 'b2' must be initialized by a constant expression}} // since-cxx11-note@-2 {{comparison of addresses of potentially overlapping literals has unspecified value}} constexpr const char *p = f(); constexpr bool b3 = p == p; #endif #if __cplusplus >= 201402L constexpr std::initializer_list il1 = { (int *)nullptr }; constexpr std::initializer_list il2 = { 0 }; constexpr bool b7 = il1.begin() == (void *)il2.begin(); // FIXME-error@-1 {{constexpr variable 'b7' must be initialized by a constant expression}} // FIXME-note@-2 {{address of a constexpr-unknown object cannot be used for comparison}} #endif } // namespace cwg2765 namespace cwg2770 { // cwg2770: 20 open 2023-07-14 #if __cplusplus >= 202002L template struct B { static_assert(sizeof(T) == 1); using type = int; }; template int f(T t, typename B::type u) requires (sizeof(t) == 1); template int f(T t, long); int i = f(1, 2); int j = f('a', 2); #endif } // namespace cwg2770 namespace cwg2780 { // cwg2780: 2.7 void f(); void g() { (void)reinterpret_cast(f); } } // namespace cwg2780 namespace cwg2785 { // cwg2785: 10 #if __cplusplus >= 202002L void g(void *); // #cwg2785-g template void f() { g(requires { T(); }); // since-cxx20-error@-1 {{no matching function for call to 'g'}} // since-cxx20-note@#cwg2785-g {{candidate function not viable: no known conversion from 'bool' to 'void *' for 1st argument}} } #endif } // namespace cwg2785 namespace cwg2789 { // cwg2789: 18 #if __cplusplus >= 202302L template struct Base { constexpr void g(); // #cwg2789-g1 }; template struct Base2 { constexpr void g() requires true; // #cwg2789-g2 }; template struct S : Base, Base2 { constexpr void f(); constexpr void f(this S&) requires true{}; using Base::g; using Base2::g; }; void test() { S<> s; s.f(); s.g(); // since-cxx23-error@-1 {{call to member function 'g' is ambiguous}} // since-cxx23-note@#cwg2789-g1 {{candidate function}} // since-cxx23-note@#cwg2789-g2 {{candidate function}} } #endif } // namespace cwg2789 namespace cwg2798 { // cwg2798: 17 #if __cplusplus > 202302L struct string { constexpr string() { data_ = new char[6](); __builtin_memcpy(data_, "Hello", 5); data_[5] = 0; } constexpr ~string() { delete[] data_; } constexpr unsigned long size() const { return 5; }; constexpr const char *data() const { return data_; } char *data_; }; struct X { string s; }; consteval X f() { return {}; } static_assert(false, f().s); // since-cxx26-error@-1 {{static assertion failed: Hello}} #endif } // namespace cwg2798