diff options
Diffstat (limited to 'test/SemaCXX')
45 files changed, 1531 insertions, 526 deletions
diff --git a/test/SemaCXX/MicrosoftCompatibility.cpp b/test/SemaCXX/MicrosoftCompatibility.cpp index 203a810111..727e67528f 100644 --- a/test/SemaCXX/MicrosoftCompatibility.cpp +++ b/test/SemaCXX/MicrosoftCompatibility.cpp @@ -302,3 +302,23 @@ void function_to_voidptr_conv() { void *a2 = &function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} void *a3 = function_ptr; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} } + +namespace member_lookup { + +template<typename T> +struct ConfuseLookup { + T* m_val; + struct m_val { + static size_t ms_test; + }; +}; + +// Microsoft mode allows explicit constructor calls +// This could confuse name lookup in cases such as this +template<typename T> +size_t ConfuseLookup<T>::m_val::ms_test + = size_t(&(char&)(reinterpret_cast<ConfuseLookup<T>*>(0)->m_val)); + +void instantiate() { ConfuseLookup<int>::m_val::ms_test = 1; } +} + diff --git a/test/SemaCXX/alias-template.cpp b/test/SemaCXX/alias-template.cpp index b6256103ef..f2ba04df78 100644 --- a/test/SemaCXX/alias-template.cpp +++ b/test/SemaCXX/alias-template.cpp @@ -179,3 +179,13 @@ struct S { }; static_assert(__is_same(S<3>::U, X[2]), ""); // expected-error {{static_assert failed}} } + +namespace PR39623 { +template <class T> +using void_t = void; + +template <class T, class = void_t<typename T::wait_what>> +int sfinae_me() { return 0; } // expected-note{{candidate template ignored: substitution failure}} + +int g = sfinae_me<int>(); // expected-error{{no matching function for call to 'sfinae_me'}} +} diff --git a/test/SemaCXX/align-x86-abi7.cpp b/test/SemaCXX/align-x86-abi7.cpp new file mode 100644 index 0000000000..3088a13f78 --- /dev/null +++ b/test/SemaCXX/align-x86-abi7.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++11 -triple i386-apple-darwin9 -fsyntax-only -verify -fclang-abi-compat=7 %s +// expected-no-diagnostics + +using size_t = decltype(sizeof(0)); + +template <typename T, size_t Preferred> +struct check_alignment { + using type = T; + static type value; + + static_assert(__alignof__(value) == Preferred, "__alignof__(value) != Preferred"); + static_assert(__alignof__(type) == Preferred, "__alignof__(type) != Preferred"); + static_assert(alignof(type) == Preferred, "alignof(type) != Preferred"); +}; + +// PR3433 +template struct check_alignment<double, 8>; +template struct check_alignment<long long, 8>; +template struct check_alignment<unsigned long long, 8>; + +// PR6362 +template struct check_alignment<double[3], 8>; + +enum big_enum { x = 18446744073709551615ULL }; +template struct check_alignment<big_enum, 8>; diff --git a/test/SemaCXX/align-x86.cpp b/test/SemaCXX/align-x86.cpp new file mode 100644 index 0000000000..0c97fc28fe --- /dev/null +++ b/test/SemaCXX/align-x86.cpp @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -std=c++11 -triple i386-apple-darwin9 -fsyntax-only -verify %s +// expected-no-diagnostics + +using size_t = decltype(sizeof(0)); + +struct complex_double { + double real; + double imag; +}; + +template <typename T, size_t ABI, size_t Preferred> +struct check_alignment { + using type = T; + static type value; + + static_assert(__alignof__(value) == Preferred, "__alignof__(value) != Preferred"); + static_assert(__alignof__(type) == Preferred, "__alignof__(type) != Preferred"); + static_assert(alignof(type) == ABI, "alignof(type) != ABI"); +}; + +// PR3433 +template struct check_alignment<double, 4, 8>; +template struct check_alignment<long long, 4, 8>; +template struct check_alignment<unsigned long long, 4, 8>; +template struct check_alignment<complex_double, 4, 4>; + +// PR6362 +struct __attribute__((packed)) +packed_struct { + unsigned int a; +} g_packedstruct; +template struct check_alignment<packed_struct, 1, 1>; +static_assert(__alignof__(g_packedstruct.a) == 1, "__alignof__(packed_struct.member) != 1"); + +template struct check_alignment<double[3], 4, 8>; + +enum big_enum { x = 18446744073709551615ULL }; +template struct check_alignment<big_enum, 4, 8>; + +// PR5637 + +#define ALIGNED(x) __attribute__((aligned(x))) + +typedef ALIGNED(2) struct { + char a[3]; +} aligned_before_struct; + +static_assert(sizeof(aligned_before_struct) == 3, ""); +static_assert(sizeof(aligned_before_struct[1]) == 4, ""); +static_assert(sizeof(aligned_before_struct[2]) == 6, ""); +static_assert(sizeof(aligned_before_struct[2][1]) == 8, ""); +static_assert(sizeof(aligned_before_struct[1][2]) == 6, ""); + +typedef struct ALIGNED(2) { + char a[3]; +} aligned_after_struct; + +static_assert(sizeof(aligned_after_struct) == 4, ""); +static_assert(sizeof(aligned_after_struct[1]) == 4, ""); +static_assert(sizeof(aligned_after_struct[2]) == 8, ""); +static_assert(sizeof(aligned_after_struct[2][1]) == 8, ""); +static_assert(sizeof(aligned_after_struct[1][2]) == 8, ""); diff --git a/test/SemaCXX/alignof.cpp b/test/SemaCXX/alignof.cpp index e3690ea926..f2854024da 100644 --- a/test/SemaCXX/alignof.cpp +++ b/test/SemaCXX/alignof.cpp @@ -11,7 +11,7 @@ struct S0 { struct S1; // expected-note 6 {{forward declaration}} extern S1 s1; -const int test3 = __alignof__(s1); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} +const int test3 = __alignof__(s1); // expected-error {{invalid application of '__alignof' to an incomplete type 'S1'}} struct S2 { S2(); @@ -19,11 +19,11 @@ struct S2 { int x; int test4 = __alignof__(x); // ok - int test5 = __alignof__(s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} + int test5 = __alignof__(s); // expected-error {{invalid application of '__alignof' to an incomplete type 'S1'}} }; const int test6 = __alignof__(S2::x); -const int test7 = __alignof__(S2::s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} +const int test7 = __alignof__(S2::s); // expected-error {{invalid application of '__alignof' to an incomplete type 'S1'}} // Arguably, these should fail like the S1 cases do: the alignment of // 's2.x' should depend on the alignment of both x-within-S2 and @@ -34,10 +34,10 @@ struct S3 { S2 s2; static const int test8 = __alignof__(s2.x); - static const int test9 = __alignof__(s2.s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} + static const int test9 = __alignof__(s2.s); // expected-error {{invalid application of '__alignof' to an incomplete type 'S1'}} auto test10() -> char(&)[__alignof__(s2.x)]; static const int test11 = __alignof__(S3::s2.x); - static const int test12 = __alignof__(S3::s2.s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} + static const int test12 = __alignof__(S3::s2.s); // expected-error {{invalid application of '__alignof' to an incomplete type 'S1'}} auto test13() -> char(&)[__alignof__(s2.x)]; }; @@ -59,9 +59,9 @@ struct S5 { }; const int test8 = __alignof__(S5::x); -long long int test14[2]; +int test14[2]; -static_assert(alignof(test14) == 8, "foo"); // expected-warning {{'alignof' applied to an expression is a GNU extension}} +static_assert(alignof(test14) == 4, "foo"); // expected-warning {{'alignof' applied to an expression is a GNU extension}} // PR19992 static_assert(alignof(int[]) == alignof(int), ""); // ok @@ -97,3 +97,8 @@ struct S { typedef __attribute__((aligned(N))) int Field[sizeof(N)]; // expected-error {{requested alignment is dependent but declaration is not dependent}} }; } + +typedef int __attribute__((aligned(16))) aligned_int; +template <typename> +using template_alias = aligned_int; +static_assert(alignof(template_alias<void>) == 16, "Expected alignment of 16" ); diff --git a/test/SemaCXX/ast-print-crash.cpp b/test/SemaCXX/ast-print-crash.cpp index c108f666d7..33edc34823 100644 --- a/test/SemaCXX/ast-print-crash.cpp +++ b/test/SemaCXX/ast-print-crash.cpp @@ -7,6 +7,6 @@ // CHECK: struct { // CHECK-NEXT: } dont_crash_on_syntax_error; -// CHECK-NEXT: decltype(nullptr) p; +// CHECK-NEXT: decltype(nullptr) p(/*implicit*/(decltype(nullptr))0); struct { } dont_crash_on_syntax_error /* missing ; */ decltype(nullptr) p; diff --git a/test/SemaCXX/attr-exclude_from_explicit_instantiation.diagnose_on_undefined_entity.cpp b/test/SemaCXX/attr-exclude_from_explicit_instantiation.diagnose_on_undefined_entity.cpp new file mode 100644 index 0000000000..24e2422193 --- /dev/null +++ b/test/SemaCXX/attr-exclude_from_explicit_instantiation.diagnose_on_undefined_entity.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -Wundefined-func-template -Wundefined-var-template -verify %s + +// Test that a diagnostic is emitted when an entity marked with the +// exclude_from_explicit_instantiation attribute is not defined in +// the current TU but it is used (and it is hence implicitly +// instantiated). + +#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation)) + +template <class T> +struct Foo { + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void non_static_member_function(); // expected-note{{forward declaration of template entity is here}} + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function(); // expected-note{{forward declaration of template entity is here}} + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member; // expected-note{{forward declaration of template entity is here}} + struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION nested { + static int static_member_function(); // expected-note{{forward declaration of template entity is here}} + }; +}; + +extern template struct Foo<int>; + +void use() { + Foo<int> foo; + + foo.non_static_member_function(); // expected-warning{{instantiation of function 'Foo<int>::non_static_member_function' required here, but no definition is available}} + // expected-note@-1 {{add an explicit instantiation}} + + Foo<int>::static_member_function(); // expected-warning{{instantiation of function 'Foo<int>::static_member_function' required here, but no definition is available}} + // expected-note@-1 {{add an explicit instantiation}} + + (void)Foo<int>::static_data_member; // expected-warning{{instantiation of variable 'Foo<int>::static_data_member' required here, but no definition is available}} + // expected-note@-1 {{add an explicit instantiation}} + + Foo<int>::nested::static_member_function(); // expected-warning{{instantiation of function 'Foo<int>::nested::static_member_function' required here, but no definition is available}} + // expected-note@-1 {{add an explicit instantiation}} +} diff --git a/test/SemaCXX/attr-exclude_from_explicit_instantiation.explicit_instantiation.cpp b/test/SemaCXX/attr-exclude_from_explicit_instantiation.explicit_instantiation.cpp new file mode 100644 index 0000000000..379ab0a3eb --- /dev/null +++ b/test/SemaCXX/attr-exclude_from_explicit_instantiation.explicit_instantiation.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// Test that explicit instantiations do not instantiate entities +// marked with the exclude_from_explicit_instantiation attribute. + +#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation)) + +template <class T> +struct Foo { + EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void non_static_member_function1(); + + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void non_static_member_function2(); + + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static inline void static_member_function1(); + + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function2(); + + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member; + + struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION member_class1 { + static void non_static_member_function() { using Fail = typename T::fail; } + }; + + struct member_class2 { + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void non_static_member_function() { using Fail = typename T::fail; } + }; +}; + +template <class T> +inline void Foo<T>::non_static_member_function1() { using Fail = typename T::fail; } + +template <class T> +void Foo<T>::non_static_member_function2() { using Fail = typename T::fail; } + +template <class T> +inline void Foo<T>::static_member_function1() { using Fail = typename T::fail; } + +template <class T> +void Foo<T>::static_member_function2() { using Fail = typename T::fail; } + +template <class T> +int Foo<T>::static_data_member = T::fail; + +// expected-no-diagnostics +template struct Foo<int>; diff --git a/test/SemaCXX/attr-exclude_from_explicit_instantiation.extern_declaration.cpp b/test/SemaCXX/attr-exclude_from_explicit_instantiation.extern_declaration.cpp new file mode 100644 index 0000000000..4cb02252ba --- /dev/null +++ b/test/SemaCXX/attr-exclude_from_explicit_instantiation.extern_declaration.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -Wno-unused-local-typedef -fsyntax-only -verify %s + +// Test that extern instantiation declarations cause members marked with +// the exclude_from_explicit_instantiation attribute to be instantiated in +// the current TU. + +#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation)) + +template <class T> +struct Foo { + EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void non_static_member_function1(); + + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void non_static_member_function2(); + + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static inline void static_member_function1(); + + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function2(); + + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member; + + struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION member_class1 { + static void static_member_function() { + using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} + } + }; + + struct member_class2 { + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function() { + using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} + } + }; +}; + +template <class T> +inline void Foo<T>::non_static_member_function1() { + using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} +} + +template <class T> +void Foo<T>::non_static_member_function2() { + using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} +} + +template <class T> +inline void Foo<T>::static_member_function1() { + using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} +} + +template <class T> +void Foo<T>::static_member_function2() { + using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} +} + +template <class T> +int Foo<T>::static_data_member = T::invalid; // expected-error{{no member named 'invalid' in 'Empty'}} + +struct Empty { }; +extern template struct Foo<Empty>; + +int main() { + Foo<Empty> foo; + foo.non_static_member_function1(); // expected-note{{in instantiation of}} + foo.non_static_member_function2(); // expected-note{{in instantiation of}} + Foo<Empty>::static_member_function1(); // expected-note{{in instantiation of}} + Foo<Empty>::static_member_function2(); // expected-note{{in instantiation of}} + (void)foo.static_data_member; // expected-note{{in instantiation of}} + Foo<Empty>::member_class1::static_member_function(); // expected-note{{in instantiation of}} + Foo<Empty>::member_class2::static_member_function(); // expected-note{{in instantiation of}} +} diff --git a/test/SemaCXX/attr-exclude_from_explicit_instantiation.merge_redeclarations.cpp b/test/SemaCXX/attr-exclude_from_explicit_instantiation.merge_redeclarations.cpp new file mode 100644 index 0000000000..da861ab972 --- /dev/null +++ b/test/SemaCXX/attr-exclude_from_explicit_instantiation.merge_redeclarations.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// Test that we properly merge the exclude_from_explicit_instantiation +// attribute on redeclarations. + +#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation)) + +template <class T> +struct Foo { + // Declaration without the attribute, definition with the attribute. + void func1(); + + // Declaration with the attribute, definition without the attribute. + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void func2(); + + // Declaration with the attribute, definition with the attribute. + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void func3(); +}; + +template <class T> +EXCLUDE_FROM_EXPLICIT_INSTANTIATION void Foo<T>::func1() { + using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} +} + +template <class T> +void Foo<T>::func2() { + using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} +} + +template <class T> +EXCLUDE_FROM_EXPLICIT_INSTANTIATION void Foo<T>::func3() { + using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} +} + +struct Empty { }; +extern template struct Foo<Empty>; + +int main() { + Foo<Empty> foo; + foo.func1(); // expected-note{{in instantiation of}} + foo.func2(); // expected-note{{in instantiation of}} + foo.func3(); // expected-note{{in instantiation of}} +} diff --git a/test/SemaCXX/attr-gnu.cpp b/test/SemaCXX/attr-gnu.cpp index a553f0d210..9eb42342df 100644 --- a/test/SemaCXX/attr-gnu.cpp +++ b/test/SemaCXX/attr-gnu.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -fms-compatibility -verify %s - -void f() { - // GNU-style attributes are prohibited in this position. +// RUN: %clang_cc1 -std=gnu++17 -fsyntax-only -fms-compatibility -verify %s
+
+void f() {
+ // GNU-style attributes are prohibited in this position.
auto P = new int * __attribute__((vector_size(8))); // expected-error {{an attribute list cannot appear here}} \ // expected-error {{invalid vector element type 'int *'}} @@ -40,6 +40,13 @@ void tuTest1(Tu<int> u); // expected-note {{candidate function not viable: no kn void tuTest2(Tu3 u); // expected-note {{candidate function not viable: no known conversion from 'int' to 'Tu3' for 1st argument}} void tu() { int x = 2; - tuTest1(x); // expected-error {{no matching function for call to 'tuTest1'}} - tuTest2(x); // expected-error {{no matching function for call to 'tuTest2'}} -} + tuTest1(x); // expected-error {{no matching function for call to 'tuTest1'}}
+ tuTest2(x); // expected-error {{no matching function for call to 'tuTest2'}}
+}
+
+[[gnu::__const__]] int f2() { return 12; }
+[[__gnu__::__const__]] int f3() { return 12; }
+[[using __gnu__ : __const__]] int f4() { return 12; }
+
+static_assert(__has_cpp_attribute(gnu::__const__));
+static_assert(__has_cpp_attribute(__gnu__::__const__));
diff --git a/test/SemaCXX/attr-on-explicit-template-instantiation.cpp b/test/SemaCXX/attr-on-explicit-template-instantiation.cpp new file mode 100644 index 0000000000..ddb9c8e2e4 --- /dev/null +++ b/test/SemaCXX/attr-on-explicit-template-instantiation.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s + +// PR39118 +// Make sure that attributes are properly applied to explicit template +// instantiations. + +#define HIDDEN __attribute__((__visibility__("hidden"))) +#define VISIBLE __attribute__((__visibility__("default"))) + +namespace ns HIDDEN { + struct A { }; + template <typename T> struct B { static A a; }; + template <typename T> A B<T>::a; + + // CHECK: @_ZN2ns1BIiE1aE = weak_odr global + // CHECK-NOT: hidden + template VISIBLE A B<int>::a; +} + +struct C { }; +template <typename T> struct D { static C c; }; +template <typename T> C D<T>::c; + +// CHECK-DAG: @_ZN1DIiE1cB3TAGE +template __attribute__((abi_tag("TAG"))) C D<int>::c; diff --git a/test/SemaCXX/attr-optnone.cpp b/test/SemaCXX/attr-optnone.cpp index 58776caf7a..c8e85eec37 100644 --- a/test/SemaCXX/attr-optnone.cpp +++ b/test/SemaCXX/attr-optnone.cpp @@ -71,3 +71,11 @@ struct B2 { static void bar(); }; +// Verify that we can handle the [[_Clang::optnone]] and +// [[__clang__::optnone]] spellings, as well as [[clang::__optnone__]]. +[[_Clang::optnone]] int foo3(); +[[__clang__::optnone]] int foo4(); // expected-warning {{'__clang__' is a predefined macro name, not an attribute scope specifier; did you mean '_Clang' instead?}} +[[clang::__optnone__]] int foo5(); +[[_Clang::__optnone__]] int foo6(); + +[[_Clang::optnone]] int foo7; // expected-warning {{'optnone' attribute only applies to functions}} diff --git a/test/SemaCXX/attr-speculative-load-hardening.cpp b/test/SemaCXX/attr-speculative-load-hardening.cpp new file mode 100644 index 0000000000..bba3b6921e --- /dev/null +++ b/test/SemaCXX/attr-speculative-load-hardening.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +int i __attribute__((speculative_load_hardening)); // expected-error {{'speculative_load_hardening' attribute only applies to functions}} + +void f1() __attribute__((speculative_load_hardening)); +void f2() __attribute__((speculative_load_hardening(1))); // expected-error {{'speculative_load_hardening' attribute takes no arguments}} + +template <typename T> +void tf1() __attribute__((speculative_load_hardening)); + +int f3(int __attribute__((speculative_load_hardening)), int); // expected-error {{'speculative_load_hardening' attribute only applies to functions}} + +struct A { + int f __attribute__((speculative_load_hardening)); // expected-error {{'speculative_load_hardening' attribute only applies to functions}} + void mf1() __attribute__((speculative_load_hardening)); + static void mf2() __attribute__((speculative_load_hardening)); +}; + +int ci [[clang::speculative_load_hardening]]; // expected-error {{'speculative_load_hardening' attribute only applies to functions}} + +[[clang::speculative_load_hardening]] void cf1(); +[[clang::speculative_load_hardening(1)]] void cf2(); // expected-error {{'speculative_load_hardening' attribute takes no arguments}} + +template <typename T> +[[clang::speculative_load_hardening]] +void ctf1(); + +int cf3(int c[[clang::speculative_load_hardening]], int); // expected-error {{'speculative_load_hardening' attribute only applies to functions}} + +struct CA { + int f [[clang::speculative_load_hardening]]; // expected-error {{'speculative_load_hardening' attribute only applies to functions}} + [[clang::speculative_load_hardening]] void mf1(); + [[clang::speculative_load_hardening]] static void mf2(); +}; diff --git a/test/SemaCXX/auto-pragma.cpp b/test/SemaCXX/auto-pragma.cpp deleted file mode 100644 index 1cd0781fe9..0000000000 --- a/test/SemaCXX/auto-pragma.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -ast-dump -ast-dump-filter AutoVar | FileCheck %s - -namespace { - class foo { - }; -} - -#pragma GCC visibility push(hidden) -auto AutoVar = foo(); - -// CHECK: VarDecl {{.*}} AutoVar -// CHECK-NOT: VisibilityAttr diff --git a/test/SemaCXX/builtins.cpp b/test/SemaCXX/builtins.cpp index f26931b55b..fbe2c457da 100644 --- a/test/SemaCXX/builtins.cpp +++ b/test/SemaCXX/builtins.cpp @@ -53,3 +53,95 @@ extern "C" int vfprintf(FILE *__restrict, const char *__restrict, void synchronize_args() { __sync_synchronize(0); // expected-error {{too many arguments}} } + +namespace test_launder { +#define TEST_TYPE(Ptr, Type) \ + static_assert(__is_same(decltype(__builtin_launder(Ptr)), Type), "expected same type") + +struct Dummy {}; + +using FnType = int(char); +using MemFnType = int (Dummy::*)(char); +using ConstMemFnType = int (Dummy::*)() const; + +void foo() {} + +void test_builtin_launder_diags(void *vp, const void *cvp, FnType *fnp, + MemFnType mfp, ConstMemFnType cmfp, int (&Arr)[5]) { + __builtin_launder(vp); // expected-error {{void pointer argument to '__builtin_launder' is not allowed}} + __builtin_launder(cvp); // expected-error {{void pointer argument to '__builtin_launder' is not allowed}} + __builtin_launder(fnp); // expected-error {{function pointer argument to '__builtin_launder' is not allowed}} + __builtin_launder(mfp); // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}} + __builtin_launder(cmfp); // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}} + (void)__builtin_launder(&fnp); + __builtin_launder(42); // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}} + __builtin_launder(nullptr); // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}} + __builtin_launder(foo); // expected-error {{function pointer argument to '__builtin_launder' is not allowed}} + (void)__builtin_launder(Arr); +} + +void test_builtin_launder(char *p, const volatile int *ip, const float *&fp, + double *__restrict dp) { + int x; + __builtin_launder(x); // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}} + + TEST_TYPE(p, char*); + TEST_TYPE(ip, const volatile int*); + TEST_TYPE(fp, const float*); + TEST_TYPE(dp, double *__restrict); + + char *d = __builtin_launder(p); + const volatile int *id = __builtin_launder(ip); + int *id2 = __builtin_launder(ip); // expected-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const volatile int *'}} + const float* fd = __builtin_launder(fp); +} + +void test_launder_return_type(const int (&ArrayRef)[101], int (&MArrRef)[42][13], + void (**&FuncPtrRef)()) { + TEST_TYPE(ArrayRef, const int *); + TEST_TYPE(MArrRef, int(*)[13]); + TEST_TYPE(FuncPtrRef, void (**)()); +} + +template <class Tp> +constexpr Tp *test_constexpr_launder(Tp *tp) { + return __builtin_launder(tp); +} +constexpr int const_int = 42; +constexpr int const_int2 = 101; +constexpr const int *const_ptr = test_constexpr_launder(&const_int); +static_assert(&const_int == const_ptr, ""); +static_assert(const_ptr != test_constexpr_launder(&const_int2), ""); + +void test_non_constexpr() { + constexpr int i = 42; // expected-note {{declared here}} + constexpr const int *ip = __builtin_launder(&i); // expected-error {{constexpr variable 'ip' must be initialized by a constant expression}} + // expected-note@-1 {{pointer to 'i' is not a constant expression}} +} + +constexpr bool test_in_constexpr(const int &i) { + return (__builtin_launder(&i) == &i); +} + +static_assert(test_in_constexpr(const_int), ""); +void f() { + constexpr int i = 42; + static_assert(test_in_constexpr(i), ""); +} + +struct Incomplete; // expected-note {{forward declaration}} +struct IncompleteMember { + Incomplete &i; +}; +void test_incomplete(Incomplete *i, IncompleteMember *im) { + // expected-error@+1 {{incomplete type 'test_launder::Incomplete' where a complete type is required}} + __builtin_launder(i); + __builtin_launder(&i); // OK + __builtin_launder(im); // OK +} + +void test_noexcept(int *i) { + static_assert(noexcept(__builtin_launder(i)), ""); +} +#undef TEST_TYPE +} // end namespace test_launder diff --git a/test/SemaCXX/char8_t.cpp b/test/SemaCXX/char8_t.cpp index 5eb3d7062d..f60a66dbe8 100644 --- a/test/SemaCXX/char8_t.cpp +++ b/test/SemaCXX/char8_t.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fchar8_t -std=c++2a -verify %s +// RUN: %clang_cc1 -fchar8_t -std=c++17 -verify %s +// RUN: %clang_cc1 -std=c++2a -verify %s char8_t a = u8'a'; char8_t b[] = u8"foo"; @@ -6,7 +7,12 @@ char8_t c = 'a'; char8_t d[] = "foo"; // expected-error {{initializing 'char8_t' array with plain string literal}} expected-note {{add 'u8' prefix}} char e = u8'a'; -char f[] = u8"foo"; // expected-error {{initialization of char array with UTF-8 string literal is not permitted by '-fchar8_t'}} +char f[] = u8"foo"; +#if __cplusplus <= 201703L +// expected-error@-2 {{initialization of char array with UTF-8 string literal is not permitted by '-fchar8_t'}} +#else +// expected-error@-4 {{ISO C++20 does not permit initialization of char array with UTF-8 string literal}} +#endif char g = 'a'; char h[] = "foo"; diff --git a/test/SemaCXX/compound-literal.cpp b/test/SemaCXX/compound-literal.cpp index be9ebee00c..353be2cf48 100644 --- a/test/SemaCXX/compound-literal.cpp +++ b/test/SemaCXX/compound-literal.cpp @@ -34,9 +34,19 @@ namespace brace_initializers { ~HasCtorDtor();
};
+ POD p = (POD){1, 2};
+ // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD'
+ // CHECK: CompoundLiteralExpr {{.*}} 'brace_initializers::POD'
+ // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD'
+ // CHECK-NEXT: ConstantExpr {{.*}}
+ // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
+ // CHECK-NEXT: ConstantExpr {{.*}}
+ // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
+
void test() {
(void)(POD){1, 2};
// CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD'
+ // CHECK-NOT: ConstantExpr {{.*}} 'brace_initializers::POD'
// CHECK: CompoundLiteralExpr {{.*}} 'brace_initializers::POD'
// CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD'
// CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
@@ -52,6 +62,7 @@ namespace brace_initializers { #if __cplusplus >= 201103L
(void)(HasCtor){1, 2};
// CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtor'
+ // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'brace_initializers::HasCtor'
// CHECK-CXX11: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtor'
// CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtor'
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
@@ -59,7 +70,8 @@ namespace brace_initializers { (void)(HasCtorDtor){1, 2};
// CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtorDtor'
- // CHECK-CXX11-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtorDtor'
+ // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'brace_initializers::HasCtorDtor'
+ // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtorDtor'
// CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtorDtor'
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}
diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp index 00df2e5c77..a71dbc0eb5 100644 --- a/test/SemaCXX/constant-expression-cxx1y.cpp +++ b/test/SemaCXX/constant-expression-cxx1y.cpp @@ -374,6 +374,30 @@ namespace compound_assign { } static_assert(test_float(), ""); + constexpr bool test_bool() { + bool b = false; + b |= 2; + if (b != true) return false; + b <<= 1; + if (b != true) return false; + b *= 2; + if (b != true) return false; + b -= 1; + if (b != false) return false; + b -= 1; + if (b != true) return false; + b += -1; + if (b != false) return false; + b += 1; + if (b != true) return false; + b += 1; + if (b != true) return false; + b ^= b; + if (b != false) return false; + return true; + } + static_assert(test_bool(), ""); + constexpr bool test_ptr() { int arr[123] = {}; int *p = arr; @@ -420,7 +444,7 @@ namespace compound_assign { static_assert(test_bounds("foo", 0)[0] == 'f', ""); static_assert(test_bounds("foo", 3)[0] == 0, ""); static_assert(test_bounds("foo", 4)[-3] == 'o', ""); - static_assert(test_bounds("foo" + 4, -4)[0] == 'f', ""); + static_assert(test_bounds(&"foo"[4], -4)[0] == 'f', ""); static_assert(test_bounds("foo", 5) != 0, ""); // expected-error {{constant}} expected-note {{call}} static_assert(test_bounds("foo", -1) != 0, ""); // expected-error {{constant}} expected-note {{call}} static_assert(test_bounds("foo", 1000) != 0, ""); // expected-error {{constant}} expected-note {{call}} @@ -879,7 +903,7 @@ namespace Bitfields { --a.n; --a.u; a.n = -a.n * 3; - return a.b == false && a.n == 3 && a.u == 31; + return a.b == true && a.n == 3 && a.u == 31; } static_assert(test(), ""); } @@ -1098,3 +1122,8 @@ constexpr E e2 = E{0}; static_assert(e2.x != e2.y, ""); } // namespace IndirectFields + +constexpr bool indirect_builtin_constant_p(const char *__s) { + return __builtin_constant_p(*__s); +} +constexpr bool n = indirect_builtin_constant_p("a"); diff --git a/test/SemaCXX/constexpr-string.cpp b/test/SemaCXX/constexpr-string.cpp index 5002038f18..c348c0ff74 100644 --- a/test/SemaCXX/constexpr-string.cpp +++ b/test/SemaCXX/constexpr-string.cpp @@ -1,8 +1,11 @@ -// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++1z -fsyntax-only -verify -pedantic -// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++1z -fsyntax-only -verify -pedantic -fno-signed-char -// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++1z -fsyntax-only -verify -pedantic -fno-wchar -Dwchar_t=__WCHAR_TYPE__ - -# 6 "/usr/include/string.h" 1 3 4 +// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension +// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -fno-signed-char +// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -fno-wchar -DNO_PREDEFINED_WCHAR_T +// RUN: %clang_cc1 %s -triple armebv7-unknown-linux -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension +// RUN: %clang_cc1 %s -triple armebv7-unknown-linux -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -fno-signed-char +// RUN: %clang_cc1 %s -triple armebv7-unknown-linux -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -fno-wchar -DNO_PREDEFINED_WCHAR_T + +# 9 "/usr/include/string.h" 1 3 4 extern "C" { typedef decltype(sizeof(int)) size_t; @@ -18,10 +21,13 @@ extern "C" { extern void *memcpy(void *d, const void *s, size_t n); extern void *memmove(void *d, const void *s, size_t n); } -# 22 "SemaCXX/constexpr-string.cpp" 2 +# 25 "SemaCXX/constexpr-string.cpp" 2 -# 24 "/usr/include/wchar.h" 1 3 4 +# 27 "/usr/include/wchar.h" 1 3 4 extern "C" { +#if NO_PREDEFINED_WCHAR_T + typedef decltype(L'0') wchar_t; +#endif extern size_t wcslen(const wchar_t *p); extern int wcscmp(const wchar_t *s1, const wchar_t *s2); @@ -35,7 +41,7 @@ extern "C" { extern wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n); } -# 39 "SemaCXX/constexpr-string.cpp" 2 +# 45 "SemaCXX/constexpr-string.cpp" 2 namespace Strlen { constexpr int n = __builtin_strlen("hello"); // ok static_assert(n == 5); @@ -95,11 +101,142 @@ namespace StrcmpEtc { static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 6) == -1); static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 5) == 0); + extern struct Incomplete incomplete; + static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0); + static_assert(__builtin_memcmp("", &incomplete, 0u) == 0); + static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}} + static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}} + + constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00}; + constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff}; + constexpr signed char ks00fe00[] = {0, -2, 0}; + constexpr signed char ks00feff[] = {0, -2, -1}; + static_assert(__builtin_memcmp(ku00feff, ks00fe00, 2) == 0); + static_assert(__builtin_memcmp(ku00feff, ks00fe00, 99) == 1); + static_assert(__builtin_memcmp(ku00fe00, ks00feff, 99) == -1); + static_assert(__builtin_memcmp(ks00feff, ku00fe00, 2) == 0); + static_assert(__builtin_memcmp(ks00feff, ku00fe00, 99) == 1); + static_assert(__builtin_memcmp(ks00fe00, ku00feff, 99) == -1); + static_assert(__builtin_memcmp(ks00fe00, ks00feff, 2) == 0); + static_assert(__builtin_memcmp(ks00feff, ks00fe00, 99) == 1); + static_assert(__builtin_memcmp(ks00fe00, ks00feff, 99) == -1); + + struct Bool3Tuple { bool bb[3]; }; + constexpr Bool3Tuple kb000100 = {{false, true, false}}; + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, kb000100.bb, 1) == 0); + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, kb000100.bb, 2) == 1); + + constexpr long ksl[] = {0, -1}; + constexpr unsigned int kui[] = {0, 0u - 1}; + constexpr unsigned long long kull[] = {0, 0ull - 1}; + constexpr const auto *kuSizeofLong(void) { + if constexpr(sizeof(long) == sizeof(int)) { + return kui; + } else if constexpr(sizeof(long) == sizeof(long long)) { + return kull; + } else { + return nullptr; + } + } + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - 1) == 0); + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + 0) == 0); + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + 1) == 0); + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) - 1) == 0); + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 0) == 0); + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 1) == 42); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) - 1) == 0); + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 0) == 0); + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 1) == 42); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} + constexpr int a = strcmp("hello", "world"); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strcmp' cannot be used in a constant expression}} constexpr int b = strncmp("hello", "world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strncmp' cannot be used in a constant expression}} constexpr int c = memcmp("hello", "world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'memcmp' cannot be used in a constant expression}} } +namespace MultibyteElementTests { +inline namespace Util { +#define STR2(X) #X +#define STR(X) STR2(X) +constexpr const char ByteOrderString[] = STR(__BYTE_ORDER__); +#undef STR +#undef STR2 +constexpr bool LittleEndian{*ByteOrderString == '1'}; + +constexpr size_t GoodFoldArraySize = 42, BadFoldArraySize = 43; +struct NotBadFoldResult {}; +template <size_t> struct FoldResult; +template <> struct FoldResult<GoodFoldArraySize> : NotBadFoldResult {}; +template <typename T, size_t N> +FoldResult<N> *foldResultImpl(T (*ptrToConstantSizeArray)[N]); +struct NotFolded : NotBadFoldResult {}; +NotFolded *foldResultImpl(bool anyPtr); +template <auto Value> struct MetaValue; +template <typename Callable, size_t N, auto ExpectedFoldResult> +auto foldResult(const Callable &, MetaValue<N> *, + MetaValue<ExpectedFoldResult> *) { + int (*maybeVLAPtr)[Callable{}(N) == ExpectedFoldResult + ? GoodFoldArraySize + : BadFoldArraySize] = 0; + return foldResultImpl(maybeVLAPtr); +} +template <typename FoldResultKind, typename Callable, typename NWrap, + typename ExpectedWrap> +constexpr bool checkFoldResult(const Callable &c, NWrap *n, ExpectedWrap *e) { + decltype(static_cast<FoldResultKind *>(foldResult(c, n, e))) *chk{}; + return true; +} +template <size_t N> constexpr MetaValue<N> *withN() { return nullptr; } +template <auto Expected> constexpr MetaValue<Expected> *withExpected() { + return nullptr; +} +} // namespace Util +} // namespace MultibyteElementTests + +namespace MultibyteElementTests::Memcmp { +#ifdef __SIZEOF_INT128__ +constexpr __int128 i128_ff_8_00_8 = -(__int128)1 - -1ull; +constexpr __int128 i128_00_16 = 0; +static_assert(checkFoldResult<NotBadFoldResult>( + [](size_t n) constexpr { + return __builtin_memcmp(&i128_ff_8_00_8, &i128_00_16, n); + }, + withN<1u>(), withExpected<LittleEndian ? 0 : 1>())); +#endif + +constexpr const signed char ByteOrderStringReduced[] = { + ByteOrderString[0] - '0', ByteOrderString[1] - '0', + ByteOrderString[2] - '0', ByteOrderString[3] - '0', +}; +constexpr signed int i04030201 = 0x04030201; +constexpr unsigned int u04030201 = 0x04030201u; +static_assert(checkFoldResult<NotBadFoldResult>( + [](size_t n) constexpr { + return __builtin_memcmp(ByteOrderStringReduced, &i04030201, n); + }, + withN<sizeof(int)>(), withExpected<0>())); +static_assert(checkFoldResult<NotBadFoldResult>( + [](size_t n) constexpr { + return __builtin_memcmp(&u04030201, ByteOrderStringReduced, n); + }, + withN<sizeof(int)>(), withExpected<0>())); + +constexpr unsigned int ui0000FEFF = 0x0000feffU; +constexpr unsigned short usFEFF = 0xfeffU; +static_assert(checkFoldResult<NotBadFoldResult>( + [](size_t n) constexpr { + return __builtin_memcmp(&ui0000FEFF, &usFEFF, n); + }, + withN<1u>(), withExpected<LittleEndian ? 0 : -1>())); + +constexpr unsigned int ui08038700 = 0x08038700u; +constexpr unsigned int ui08048600 = 0x08048600u; +static_assert(checkFoldResult<NotBadFoldResult>( + [](size_t n) constexpr { + return __builtin_memcmp(&ui08038700, &ui08048600, n); + }, + withN<sizeof(int)>(), withExpected<LittleEndian ? 1 : -1>())); +} + namespace WcscmpEtc { constexpr wchar_t kFoobar[6] = {L'f',L'o',L'o',L'b',L'a',L'r'}; constexpr wchar_t kFoobazfoobar[12] = {L'f',L'o',L'o',L'b',L'a',L'z',L'f',L'o',L'o',L'b',L'a',L'r'}; @@ -187,6 +324,27 @@ namespace StrchrEtc { static_assert(__builtin_memchr(nullptr, 'x', 3) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}} static_assert(__builtin_memchr(nullptr, 'x', 0) == nullptr); // FIXME: Should we reject this? + extern struct Incomplete incomplete; + static_assert(__builtin_memchr(&incomplete, 0, 0u) == nullptr); + static_assert(__builtin_memchr(&incomplete, 0, 1u) == nullptr); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}} + + const unsigned char &u1 = 0xf0; + auto &&i1 = (const signed char []){-128}; // expected-warning {{compound literals are a C99-specific feature}} + static_assert(__builtin_memchr(&u1, -(0x0f + 1), 1) == &u1); + static_assert(__builtin_memchr(i1, 0x80, 1) == i1); + + enum class E : unsigned char {}; + struct EPair { E e, f; }; + constexpr EPair ee{E{240}}; + static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); + + constexpr bool kBool[] = {false, true, false}; + constexpr const bool *const kBoolPastTheEndPtr = kBool + 3; + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, 99) == kBoolPastTheEndPtr - 1); + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} + static_assert(__builtin_char_memchr(kStr, 'a', 0) == nullptr); static_assert(__builtin_char_memchr(kStr, 'a', 1) == kStr); static_assert(__builtin_char_memchr(kStr, '\0', 5) == nullptr); @@ -212,6 +370,22 @@ namespace StrchrEtc { constexpr bool b = !memchr("hello", 'h', 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'memchr' cannot be used in a constant expression}} } +namespace MultibyteElementTests::Memchr { +constexpr unsigned int u04030201 = 0x04030201; +static_assert(checkFoldResult<NotBadFoldResult>( + [](size_t n) constexpr { + return __builtin_memchr(&u04030201, *ByteOrderString - '0', n); + }, + withN<1u>(), withExpected<&u04030201>())); + +constexpr unsigned int uED = 0xEDU; +static_assert(checkFoldResult<NotBadFoldResult>( + [](size_t n) constexpr { + return __builtin_memchr(&uED, 0xED, n); + }, + withN<1u>(), withExpected<LittleEndian ? &uED : nullptr>())); +} + namespace WcschrEtc { constexpr const wchar_t *kStr = L"abca\xffff\0dL"; constexpr wchar_t kFoo[] = {L'f', L'o', L'o'}; @@ -269,15 +443,15 @@ namespace MemcpyEtc { wchar_t arr[4] = {1, 2, 3, 4}; __builtin_wmemcpy(arr + a, arr + b, n); // expected-note@-1 2{{overlapping memory regions}} - // expected-note-re@-2 {{source is not a contiguous array of at least 2 elements of type '{{wchar_t|int}}'}} - // expected-note-re@-3 {{destination is not a contiguous array of at least 3 elements of type '{{wchar_t|int}}'}} + // expected-note@-2 {{source is not a contiguous array of at least 2 elements of type 'wchar_t'}} + // expected-note@-3 {{destination is not a contiguous array of at least 3 elements of type 'wchar_t'}} return result(arr); } constexpr int test_wmemmove(int a, int b, int n) { wchar_t arr[4] = {1, 2, 3, 4}; __builtin_wmemmove(arr + a, arr + b, n); - // expected-note-re@-1 {{source is not a contiguous array of at least 2 elements of type '{{wchar_t|int}}'}} - // expected-note-re@-2 {{destination is not a contiguous array of at least 3 elements of type '{{wchar_t|int}}'}} + // expected-note@-1 {{source is not a contiguous array of at least 2 elements of type 'wchar_t'}} + // expected-note@-2 {{destination is not a contiguous array of at least 3 elements of type 'wchar_t'}} return result(arr); } @@ -387,4 +561,41 @@ namespace MemcpyEtc { // designators until we have a long enough matching size, if both designators // point to the start of their respective final elements. static_assert(test_derived_to_base(2) == 3434); // expected-error {{constant}} expected-note {{in call}} + + // Check that when address-of an array is passed to a tested function the + // array can be fully copied. + constexpr int test_address_of_const_array_type() { + int arr[4] = {1, 2, 3, 4}; + __builtin_memmove(&arr, &arr, sizeof(arr)); + return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3]; + } + static_assert(test_address_of_const_array_type() == 1234); + + // Check that an incomplete array is rejected. + constexpr int test_incomplete_array_type() { // expected-error {{never produces a constant}} + extern int arr[]; + __builtin_memmove(arr, arr, 4 * sizeof(arr[0])); + // expected-note@-1 2{{'memmove' not supported: source is not a contiguous array of at least 4 elements of type 'int'}} + return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3]; + } + static_assert(test_incomplete_array_type() == 1234); // expected-error {{constant}} expected-note {{in call}} + + // Check that a pointer to an incomplete array is rejected. + constexpr int test_address_of_incomplete_array_type() { // expected-error {{never produces a constant}} + extern int arr[]; + __builtin_memmove(&arr, &arr, 4 * sizeof(arr[0])); + // expected-note@-1 2{{cannot constant evaluate 'memmove' between objects of incomplete type 'int []'}} + return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3]; + } + static_assert(test_address_of_incomplete_array_type() == 1234); // expected-error {{constant}} expected-note {{in call}} + + // Check that a pointer to an incomplete struct is rejected. + constexpr bool test_address_of_incomplete_struct_type() { // expected-error {{never produces a constant}} + struct Incomplete; + extern Incomplete x, y; + __builtin_memcpy(&x, &x, 4); + // expected-note@-1 2{{cannot constant evaluate 'memcpy' between objects of incomplete type 'Incomplete'}} + return true; + } + static_assert(test_address_of_incomplete_struct_type()); // expected-error {{constant}} expected-note {{in call}} } diff --git a/test/SemaCXX/coreturn-eh.cpp b/test/SemaCXX/coreturn-eh.cpp new file mode 100644 index 0000000000..79065736c0 --- /dev/null +++ b/test/SemaCXX/coreturn-eh.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts -fcxx-exceptions -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks -Wall -Wextra -Wno-error=unreachable-code +// expected-no-diagnostics + +#include "Inputs/std-coroutine.h" + +using std::experimental::suspend_always; +using std::experimental::suspend_never; + +struct awaitable { + bool await_ready(); + void await_suspend(std::experimental::coroutine_handle<>); // FIXME: coroutine_handle + void await_resume(); +} a; + +struct object { ~object() {} }; + +struct promise_void_return_value { + void get_return_object(); + suspend_always initial_suspend(); + suspend_always final_suspend(); + void unhandled_exception(); + void return_value(object); +}; + +struct VoidTagReturnValue { + struct promise_type { + VoidTagReturnValue get_return_object(); + suspend_always initial_suspend(); + suspend_always final_suspend(); + void unhandled_exception(); + void return_value(object); + }; +}; + +template <typename T1> +struct std::experimental::coroutine_traits<void, T1> { using promise_type = promise_void_return_value; }; + +VoidTagReturnValue test() { + object x = {}; + try { + co_return {}; + } catch (...) { + throw; + } +} diff --git a/test/SemaCXX/coroutine-rvo.cpp b/test/SemaCXX/coroutine-rvo.cpp new file mode 100644 index 0000000000..8521b8506f --- /dev/null +++ b/test/SemaCXX/coroutine-rvo.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -stdlib=libc++ -std=c++1z -fcoroutines-ts -fsyntax-only + +namespace std::experimental { +template <class Promise = void> struct coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) noexcept; +}; + +template <> struct coroutine_handle<void> { + static coroutine_handle from_address(void *) noexcept; + coroutine_handle() = default; + template <class PromiseType> + coroutine_handle(coroutine_handle<PromiseType>) noexcept; +}; + +template <class... Args> +struct void_t_imp { + using type = void; +}; +template <class... Args> +using void_t = typename void_t_imp<Args...>::type; + +template <class T, class = void> +struct traits_sfinae_base {}; + +template <class T> +struct traits_sfinae_base<T, void_t<typename T::promise_type>> { + using promise_type = typename T::promise_type; +}; + +template <class Ret, class... Args> +struct coroutine_traits : public traits_sfinae_base<Ret> {}; +} + +struct suspend_never { + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; +}; + +struct MoveOnly { + MoveOnly() {}; + MoveOnly(const MoveOnly&) = delete; + MoveOnly(MoveOnly&&) noexcept {}; + ~MoveOnly() {}; +}; + +template <typename T> +struct task { + struct promise_type { + auto initial_suspend() { return suspend_never{}; } + auto final_suspend() { return suspend_never{}; } + auto get_return_object() { return task{}; } + static void unhandled_exception() {} + void return_value(T&& value) {} + }; +}; + +task<MoveOnly> f() { + MoveOnly value; + co_return value; +} + +int main() { + f(); + return 0; +} + +// expected-no-diagnostics diff --git a/test/SemaCXX/coroutine-source-location-crash.cpp b/test/SemaCXX/coroutine-source-location-crash.cpp deleted file mode 100644 index 04fb1d45c5..0000000000 --- a/test/SemaCXX/coroutine-source-location-crash.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts \ -// RUN: -fsyntax-only -ast-dump | FileCheck %s -#include "Inputs/std-coroutine.h" - -using namespace std::experimental; - -struct A { - bool await_ready(); - void await_resume(); - template <typename F> - void await_suspend(F); -}; - -struct coro_t { - struct promise_type { - coro_t get_return_object(); - suspend_never initial_suspend(); - suspend_never final_suspend(); - void return_void(); - static void unhandled_exception(); - }; -}; - -// {{0x[0-9a-fA-F]+}} <line:[[@LINE+1]]:1, col:36> -// CHECK-LABEL: FunctionDecl {{.*}} f 'coro_t (int)' -coro_t f(int n) { - A a{}; - // CHECK: CoawaitExpr {{0x[0-9a-fA-F]+}} <col:3, col:12> - // CHECK-NEXT: DeclRefExpr {{0x[0-9a-fA-F]+}} <col:12> - // CHECK-NEXT: CXXMemberCallExpr {{0x[0-9a-fA-F]+}} <col:12> - // CHECK-NEXT: MemberExpr {{0x[0-9a-fA-F]+}} <col:12> - co_await a; -} diff --git a/test/SemaCXX/cxx1y-init-captures.cpp b/test/SemaCXX/cxx1y-init-captures.cpp index 4b82452ed5..16cffb2a91 100644 --- a/test/SemaCXX/cxx1y-init-captures.cpp +++ b/test/SemaCXX/cxx1y-init-captures.cpp @@ -144,13 +144,13 @@ int test(T t = T{}) { }; } { // will need to capture x in outer lambda - const int x = 10; //expected-note 2{{declared}} - auto L = [z = x](char a) { //expected-note 2{{begins}} - auto M = [&y = x](T b) { //expected-error 2{{cannot be implicitly captured}} + const int x = 10; //expected-note {{declared}} + auto L = [z = x](char a) { //expected-note {{begins}} + auto M = [&y = x](T b) { //expected-error {{cannot be implicitly captured}} return y; }; return M; - }; + }; } { // no captures diff --git a/test/SemaCXX/cxx2a-compat.cpp b/test/SemaCXX/cxx2a-compat.cpp index 53043d67fb..d51f1e6aab 100644 --- a/test/SemaCXX/cxx2a-compat.cpp +++ b/test/SemaCXX/cxx2a-compat.cpp @@ -21,3 +21,19 @@ B b2 = {1, 2, 3, 4}; #else // expected-error@-4 2{{no viable conversion from 'int' to 'A'}} #endif + +// Essentially any use of a u8 string literal in C++<=17 is broken by C++20. +// Just warn on all such string literals. +struct string { string(const char*); }; // expected-note 0+{{candidate}} +char u8arr[] = u8"hello"; +const char *u8ptr = "wo" u8"rld"; +string u8str = u8"test" u8"test"; +#if __cplusplus <= 201703L +// expected-warning@-4 {{type of UTF-8 string literal will change}} expected-note@-4 {{remove 'u8' prefix}} +// expected-warning@-4 {{type of UTF-8 string literal will change}} expected-note@-4 {{remove 'u8' prefix}} +// expected-warning@-4 {{type of UTF-8 string literal will change}} expected-note@-4 {{remove 'u8' prefix}} +#else +// expected-error@-8 {{ISO C++20 does not permit initialization of char array with UTF-8 string literal}} +// expected-error@-8 {{cannot initialize a variable of type 'const char *' with an lvalue of type 'const char8_t [6]'}} +// expected-error@-8 {{no viable conversion from 'const char8_t [9]' to 'string'}} +#endif diff --git a/test/SemaCXX/enable_if.cpp b/test/SemaCXX/enable_if.cpp index 93014f50d5..ba520b047a 100644 --- a/test/SemaCXX/enable_if.cpp +++ b/test/SemaCXX/enable_if.cpp @@ -414,7 +414,8 @@ static_assert(templated<1>() == 1, ""); template <int N> constexpr int callTemplated() { return templated<N>(); } -constexpr int B = callTemplated<0>(); // expected-error{{initialized by a constant expression}} expected-error@-2{{no matching function for call to 'templated'}} expected-note{{in instantiation of function template}} expected-note@-9{{candidate disabled}} +constexpr int B = 10 + // the carat for the error should be pointing to the problematic call (on the next line), not here. + callTemplated<0>(); // expected-error{{initialized by a constant expression}} expected-error@-3{{no matching function for call to 'templated'}} expected-note{{in instantiation of function template}} expected-note@-10{{candidate disabled}} static_assert(callTemplated<1>() == 1, ""); } diff --git a/test/SemaCXX/enum.cpp b/test/SemaCXX/enum.cpp index cfe5760112..16ebebe31b 100644 --- a/test/SemaCXX/enum.cpp +++ b/test/SemaCXX/enum.cpp @@ -109,6 +109,8 @@ enum { overflow = 123456 * 234567 }; #if __cplusplus >= 201103L // expected-warning@-2 {{not an integral constant expression}} // expected-note@-3 {{value 28958703552 is outside the range of representable values}} +#else +// expected-warning@-5 {{overflow in expression; result is -1106067520 with type 'int'}} #endif // PR28903 diff --git a/test/SemaCXX/friend-template-redecl.cpp b/test/SemaCXX/friend-template-redecl.cpp new file mode 100644 index 0000000000..3e05964fb2 --- /dev/null +++ b/test/SemaCXX/friend-template-redecl.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -std=c++17 -verify -emit-llvm-only %s + +// expected-no-diagnostics + +template <class T> void bar(const T &t) { foo(t); } + +template <class> +struct HasFriend { + template <class T> + friend void foo(const HasFriend<T> &m) noexcept(false); +}; + +template <class T> +void foo(const HasFriend<T> &m) noexcept(false) {} + +void f() { + HasFriend<int> x; + foo(x); + bar(x); +} diff --git a/test/SemaCXX/friend2.cpp b/test/SemaCXX/friend2.cpp index 8eacdeb19c..6d3b545904 100644 --- a/test/SemaCXX/friend2.cpp +++ b/test/SemaCXX/friend2.cpp @@ -129,6 +129,83 @@ C22b<int> c22bi; void func_22() {} // expected-error{{redefinition of 'func_22'}} +// Case of template friend functions. + +template<typename T> void func_31(T *x); +template<typename T1> +struct C31a { + template<typename T> friend void func_31(T *x) {} +}; +template<typename T1> +struct C31b { + template<typename T> friend void func_31(T *x) {} +}; + + +template<typename T> inline void func_32(T *x) {} +template<typename T1> +struct C32a { + template<typename T> friend void func_32(T *x) {} +}; +template<typename T1> +struct C32b { + template<typename T> friend void func_32(T *x) {} +}; + + +template<typename T1> +struct C33a { + template<typename T> friend void func_33(T *x) {} +}; +template<typename T1> +struct C33b { + template<typename T> friend void func_33(T *x) {} +}; + + +template<typename T> inline void func_34(T *x) {} // expected-note{{previous definition is here}} +template<typename T1> +struct C34 { + template<typename T> friend void func_34(T *x) {} // expected-error{{redefinition of 'func_34'}} +}; + +C34<int> v34; // expected-note{{in instantiation of template class 'C34<int>' requested here}} + + +template<typename T> inline void func_35(T *x); +template<typename T1> +struct C35a { + template<typename T> friend void func_35(T *x) {} // expected-note{{previous definition is here}} +}; +template<typename T1> +struct C35b { + template<typename T> friend void func_35(T *x) {} // expected-error{{redefinition of 'func_35'}} +}; + +C35a<int> v35a; +C35b<int> v35b; // expected-note{{in instantiation of template class 'C35b<int>' requested here}} + + +template<typename T> void func_36(T *x); +template<typename T1> +struct C36 { + template<typename T> friend void func_36(T *x) {} // expected-error{{redefinition of 'func_36'}} + // expected-note@-1{{previous definition is here}} +}; + +C36<int> v36a; +C36<long> v36b; //expected-note{{in instantiation of template class 'C36<long>' requested here}} + + +template<typename T> void func_37(T *x); +template<typename T1> +struct C37 { + template<typename T> friend void func_37(T *x) {} // expected-note{{previous definition is here}} +}; + +C37<int> v37; +template<typename T> void func_37(T *x) {} // expected-error{{redefinition of 'func_37'}} + namespace pr22307 { @@ -235,3 +312,15 @@ void func() { cache.insert(); } } + +namespace PR39742 { +template<typename> +struct wrapper { + template<typename> + friend void friend_function_template() {} // expected-error{{redefinition of 'friend_function_template'}} + // expected-note@-1{{previous definition is here}} +}; + +wrapper<bool> x; +wrapper<int> y; // expected-note{{in instantiation of template class 'PR39742::wrapper<int>' requested here}} +} diff --git a/test/SemaCXX/lambda-invalid-capture.cpp b/test/SemaCXX/lambda-invalid-capture.cpp new file mode 100644 index 0000000000..32349704ca --- /dev/null +++ b/test/SemaCXX/lambda-invalid-capture.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// Don't crash. + +struct g { + j; // expected-error {{C++ requires a type specifier for all declarations}} +}; + +void captures_invalid_type() { + g child; + auto q = [child]{}; + const int n = sizeof(q); +} + +void captures_invalid_array_type() { + g child[100]; + auto q = [child]{}; + const int n = sizeof(q); +} diff --git a/test/SemaCXX/multistep-explicit-cast.cpp b/test/SemaCXX/multistep-explicit-cast.cpp deleted file mode 100644 index 5846679135..0000000000 --- a/test/SemaCXX/multistep-explicit-cast.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -ast-dump %s | FileCheck %s - -// We are checking that implicit casts don't get marked with 'part_of_explicit_cast', -// while in explicit casts, the implicitly-inserted implicit casts are marked with 'part_of_explicit_cast' - -unsigned char implicitcast_0(unsigned int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_0 'unsigned char (unsigned int)'{{$}} - // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue>{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} - return x; -} - -signed char implicitcast_1(unsigned int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_1 'signed char (unsigned int)'{{$}} - // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue>{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} - return x; -} - -unsigned char implicitcast_2(signed int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_2 'unsigned char (int)'{{$}} - // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue>{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} - return x; -} - -signed char implicitcast_3(signed int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_3 'signed char (int)'{{$}} - // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue>{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} - return x; -} - -//----------------------------------------------------------------------------// - -unsigned char cstylecast_0(unsigned int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_0 'unsigned char (unsigned int)'{{$}} - // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} - return (unsigned char)x; -} - -signed char cstylecast_1(unsigned int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_1 'signed char (unsigned int)'{{$}} - // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'signed char' <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} - return (signed char)x; -} - -unsigned char cstylecast_2(signed int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_2 'unsigned char (int)'{{$}} - // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} - return (unsigned char)x; -} - -signed char cstylecast_3(signed int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_3 'signed char (int)'{{$}} - // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'signed char' <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} - return (signed char)x; -} - -//----------------------------------------------------------------------------// - -unsigned char cxxstaticcast_0(unsigned int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_0 'unsigned char (unsigned int)'{{$}} - // CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'unsigned char' static_cast<unsigned char> <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} - return static_cast<unsigned char>(x); -} - -signed char cxxstaticcast_1(unsigned int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_1 'signed char (unsigned int)'{{$}} - // CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'signed char' static_cast<signed char> <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} - return static_cast<signed char>(x); -} - -unsigned char cxxstaticcast_2(signed int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_2 'unsigned char (int)'{{$}} - // CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'unsigned char' static_cast<unsigned char> <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} - return static_cast<unsigned char>(x); -} - -signed char cxxstaticcast_3(signed int x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_3 'signed char (int)'{{$}} - // CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'signed char' static_cast<signed char> <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} - return static_cast<signed char>(x); -} - -//----------------------------------------------------------------------------// - -using UnsignedChar = unsigned char; -using SignedChar = signed char; -using UnsignedInt = unsigned int; -using SignedInt = signed int; - -UnsignedChar cxxfunctionalcast_0(UnsignedInt x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_0 'UnsignedChar (UnsignedInt)'{{$}} - // CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' functional cast to UnsignedChar <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' lvalue ParmVar {{.*}} 'x' 'UnsignedInt':'unsigned int'{{$}} - return UnsignedChar(x); -} - -SignedChar cxxfunctionalcast_1(UnsignedInt x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_1 'SignedChar (UnsignedInt)'{{$}} - // CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' functional cast to SignedChar <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' lvalue ParmVar {{.*}} 'x' 'UnsignedInt':'unsigned int'{{$}} - return SignedChar(x); -} - -UnsignedChar cxxfunctionalcast_2(SignedInt x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_2 'UnsignedChar (SignedInt)'{{$}} - // CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' functional cast to UnsignedChar <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' lvalue ParmVar {{.*}} 'x' 'SignedInt':'int'{{$}} - return UnsignedChar(x); -} - -SignedChar cxxfunctionalcast_3(SignedInt x) { - // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_3 'SignedChar (SignedInt)'{{$}} - // CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' functional cast to SignedChar <NoOp>{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' <IntegralCast> part_of_explicit_cast{{$}} - // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' <LValueToRValue> part_of_explicit_cast{{$}} - // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' lvalue ParmVar {{.*}} 'x' 'SignedInt':'int'{{$}} - return SignedChar(x); -} diff --git a/test/SemaCXX/nullptr_t-init.cpp b/test/SemaCXX/nullptr_t-init.cpp new file mode 100644 index 0000000000..f7843de1bc --- /dev/null +++ b/test/SemaCXX/nullptr_t-init.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -ffreestanding -Wuninitialized %s +// expected-no-diagnostics +typedef decltype(nullptr) nullptr_t; + +// Ensure no 'uninitialized when used here' warnings (Wuninitialized), for +// nullptr_t always-initialized extension. +nullptr_t default_init() { + nullptr_t a; + return a; +} diff --git a/test/SemaCXX/sourceranges.cpp b/test/SemaCXX/sourceranges.cpp deleted file mode 100644 index 58772a0639..0000000000 --- a/test/SemaCXX/sourceranges.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// RUN: %clang_cc1 -triple i686-mingw32 -ast-dump %s | FileCheck %s
-// RUN: %clang_cc1 -triple i686-mingw32 -std=c++1z -ast-dump %s | FileCheck %s -check-prefix=CHECK-1Z
-
-template<class T>
-class P {
- public:
- P(T* t) {}
-};
-
-namespace foo {
-class A { public: A(int = 0) {} };
-enum B {};
-typedef int C;
-}
-
-// CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:[[@LINE+1]]:1, col:36> col:15 ImplicitConstrArray 'foo::A [2]'
-static foo::A ImplicitConstrArray[2];
-
-int main() {
- // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::A *'
- P<foo::A> p14 = new foo::A;
- // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::B *'
- P<foo::B> p24 = new foo::B;
- // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::C *'
- P<foo::C> pr4 = new foo::C;
-}
-
-foo::A getName() {
- // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:10, col:17> 'foo::A'
- return foo::A();
-}
-
-void destruct(foo::A *a1, foo::A *a2, P<int> *p1) {
- // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:8> '<bound member function type>' ->~A
- a1->~A();
- // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:16> '<bound member function type>' ->~A
- a2->foo::A::~A();
- // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:13> '<bound member function type>' ->~P
- p1->~P<int>();
-}
-
-struct D {
- D(int);
- ~D();
-};
-
-void construct() {
- using namespace foo;
- A a = A(12);
- // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'foo::A' 'void (int){{( __attribute__\(\(thiscall\)\))?}}'
- D d = D(12);
- // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'D' 'void (int){{( __attribute__\(\(thiscall\)\))?}}'
-}
-
-void abort() __attribute__((noreturn));
-
-namespace std {
-typedef decltype(sizeof(int)) size_t;
-
-template <typename E> struct initializer_list {
- const E *p;
- size_t n;
- initializer_list(const E *p, size_t n) : p(p), n(n) {}
-};
-
-template <typename F, typename S> struct pair {
- F f;
- S s;
- pair(const F &f, const S &s) : f(f), s(s) {}
-};
-
-struct string {
- const char *str;
- string() { abort(); }
- string(const char *S) : str(S) {}
- ~string() { abort(); }
-};
-
-template<typename K, typename V>
-struct map {
- using T = pair<K, V>;
- map(initializer_list<T> i, const string &s = string()) {}
- ~map() { abort(); }
-};
-
-}; // namespace std
-
-#if __cplusplus >= 201703L
-// CHECK-1Z: FunctionDecl {{.*}} construct_with_init_list
-std::map<int, int> construct_with_init_list() {
- // CHECK-1Z-NEXT: CompoundStmt
- // CHECK-1Z-NEXT: ReturnStmt {{.*}} <line:[[@LINE+5]]:3, col:35
- // CHECK-1Z-NEXT: ExprWithCleanups {{.*}} <col:10, col:35
- // CHECK-1Z-NEXT: CXXBindTemporaryExpr {{.*}} <col:10, col:35
- // CHECK-1Z-NEXT: CXXTemporaryObjectExpr {{.*}} <col:10, col:35
- // CHECK-1Z-NEXT: CXXStdInitializerListExpr {{.*}} <col:28, col:35
- return std::map<int, int>{{0, 0}};
-}
-
-// CHECK-1Z: NamespaceDecl {{.*}} in_class_init
-namespace in_class_init {
- struct A {};
-
- // CHECK-1Z: CXXRecordDecl {{.*}} struct B definition
- struct B {
- // CHECK-1Z: FieldDecl {{.*}} a 'in_class_init::A'
- // CHECK-1Z-NEXT: InitListExpr {{.*}} <col:11, col:12
- A a = {};
- };
-}
-
-// CHECK-1Z: NamespaceDecl {{.*}} delegating_constructor_init
-namespace delegating_constructor_init {
- struct A {};
-
- struct B : A {
- A a;
- B(A a) : a(a) {}
- };
-
- // CHECK-1Z: CXXRecordDecl {{.*}} struct C definition
- struct C : B {
- // CHECK-1Z: CXXConstructorDecl {{.*}} C
- // CHECK-1Z-NEXT: CXXCtorInitializer 'delegating_constructor_init::B'
- // CHECK-1Z-NEXT: CXXConstructExpr {{.*}} <col:11, col:15
- // CHECK-1Z-NEXT: InitListExpr {{.*}} <col:13, col:14
- C() : B({}) {};
- };
-}
-
-// CHECK-1Z: NamespaceDecl {{.*}} new_init
-namespace new_init {
- void A() {
- // CHECK-1Z: CXXNewExpr {{.*}} <line:[[@LINE+2]]:5, col:14
- // CHECK-1Z-NEXT: InitListExpr {{.*}} <col:12, col:14
- new int{0};
- }
-}
-#endif
diff --git a/test/SemaCXX/static-assert-cxx17.cpp b/test/SemaCXX/static-assert-cxx17.cpp new file mode 100644 index 0000000000..67b3541bea --- /dev/null +++ b/test/SemaCXX/static-assert-cxx17.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1z -triple=x86_64-linux-gnu + +template <typename U, typename V> +struct S1 { + static constexpr const bool value = false; +}; + +template <typename U, typename V> +inline constexpr bool global_inline_var = S1<U, V>::value; + +template <typename T> +struct S2 { + template <typename U, typename V> + static inline constexpr bool var = global_inline_var<U, V>; +}; + +template <typename U, typename V> +void foo() { + static_assert(S1<U, V>::value); + // expected-error@-1{{static_assert failed due to requirement 'S1<int, float>::value'}} +} +template void foo<int, float>(); +// expected-note@-1{{in instantiation of function template specialization 'foo<int, float>' requested here}} + +template <typename U, typename V> +void foo2() { + static_assert(global_inline_var<U, V>); + // expected-error@-1{{static_assert failed due to requirement 'global_inline_var<int, float>'}} +} +template void foo2<int, float>(); +// expected-note@-1{{in instantiation of function template specialization 'foo2<int, float>' requested here}} + +template <typename T, typename U, typename V> +void foo3() { + static_assert(T::template var<U, V>); + // expected-error@-1{{static_assert failed due to requirement 'S2<long>::var<int, float>'}} +} +template void foo3<S2<long>, int, float>(); +// expected-note@-1{{in instantiation of function template specialization 'foo3<S2<long>, int, float>' requested here}} + +template <typename T> +void foo4() { + static_assert(S1<T[sizeof(T)], int[4]>::value, ""); + // expected-error@-1{{static_assert failed due to requirement 'S1<float [4], int [4]>::value'}} +}; +template void foo4<float>(); +// expected-note@-1{{in instantiation of function template specialization 'foo4<float>' requested here}} + + +template <typename U, typename V> +void foo5() { + static_assert(!!(global_inline_var<U, V>)); + // expected-error@-1{{static_assert failed due to requirement '!!(global_inline_var<int, float>)'}} +} +template void foo5<int, float>(); +// expected-note@-1{{in instantiation of function template specialization 'foo5<int, float>' requested here}} diff --git a/test/SemaCXX/static-assert.cpp b/test/SemaCXX/static-assert.cpp index 846303807a..b43d56a922 100644 --- a/test/SemaCXX/static-assert.cpp +++ b/test/SemaCXX/static-assert.cpp @@ -15,14 +15,14 @@ class C { }; template<int N> struct T { - static_assert(N == 2, "N is not 2!"); // expected-error {{static_assert failed "N is not 2!"}} + static_assert(N == 2, "N is not 2!"); // expected-error {{static_assert failed due to requirement '1 == 2' "N is not 2!"}} }; T<1> t1; // expected-note {{in instantiation of template class 'T<1>' requested here}} T<2> t2; template<typename T> struct S { - static_assert(sizeof(T) > sizeof(char), "Type not big enough!"); // expected-error {{static_assert failed "Type not big enough!"}} + static_assert(sizeof(T) > sizeof(char), "Type not big enough!"); // expected-error {{static_assert failed due to requirement 'sizeof(char) > sizeof(char)' "Type not big enough!"}} }; S<char> s1; // expected-note {{in instantiation of template class 'S<char>' requested here}} @@ -68,3 +68,108 @@ template<typename T> struct second_trait { }; static_assert(first_trait<X>::value && second_trait<X>::value, "message"); // expected-error{{static_assert failed due to requirement 'second_trait<X>::value' "message"}} + +namespace std { + +template <class Tp, Tp v> +struct integral_constant { + static const Tp value = v; + typedef Tp value_type; + typedef integral_constant type; +}; + +template <class Tp, Tp v> +const Tp integral_constant<Tp, v>::value; + +typedef integral_constant<bool, true> true_type; +typedef integral_constant<bool, false> false_type; + +template <class Tp> +struct is_const : public false_type {}; +template <class Tp> +struct is_const<Tp const> : public true_type {}; + +// We do not define is_same in terms of integral_constant to check that both implementations are supported. +template <typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template <typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +} // namespace std + +struct ExampleTypes { + using T = int; + using U = float; +}; + +static_assert(std::is_same<ExampleTypes::T, ExampleTypes::U>::value, "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_same<int, float>::value' "message"}} +static_assert(std::is_const<ExampleTypes::T>::value, "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_const<int>::value' "message"}} +static_assert(!std::is_const<const ExampleTypes::T>::value, "message"); +// expected-error@-1{{static_assert failed due to requirement '!std::is_const<const int>::value' "message"}} +static_assert(!(std::is_const<const ExampleTypes::T>::value), "message"); +// expected-error@-1{{static_assert failed due to requirement '!(std::is_const<const int>::value)' "message"}} +static_assert(std::is_const<const ExampleTypes::T>::value == false, "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_const<const int>::value == false' "message"}} +static_assert(!(std::is_const<const ExampleTypes::T>::value == true), "message"); +// expected-error@-1{{static_assert failed due to requirement '!(std::is_const<const int>::value == true)' "message"}} + +struct BI_tag {}; +struct RAI_tag : BI_tag {}; +struct MyIterator { + using tag = BI_tag; +}; +struct MyContainer { + using iterator = MyIterator; +}; +template <class Container> +void foo() { + static_assert(std::is_same<RAI_tag, typename Container::iterator::tag>::value, "message"); + // expected-error@-1{{static_assert failed due to requirement 'std::is_same<RAI_tag, BI_tag>::value' "message"}} +} +template void foo<MyContainer>(); +// expected-note@-1{{in instantiation of function template specialization 'foo<MyContainer>' requested here}} + +namespace ns { +template <typename T, int v> +struct NestedTemplates1 { + struct NestedTemplates2 { + template <typename U> + struct NestedTemplates3 : public std::is_same<T, U> {}; + }; +}; +} // namespace ns + +template <typename T, typename U, int a> +void foo2() { + static_assert(::ns::NestedTemplates1<T, a>::NestedTemplates2::template NestedTemplates3<U>::value, "message"); + // expected-error@-1{{static_assert failed due to requirement '::ns::NestedTemplates1<int, 3>::NestedTemplates2::NestedTemplates3<float>::value' "message"}} +} +template void foo2<int, float, 3>(); +// expected-note@-1{{in instantiation of function template specialization 'foo2<int, float, 3>' requested here}} + +template <class T> +void foo3(T t) { + static_assert(std::is_const<T>::value, "message"); + // expected-error-re@-1{{static_assert failed due to requirement 'std::is_const<(lambda at {{.*}}static-assert.cpp:{{[0-9]*}}:{{[0-9]*}})>::value' "message"}} + static_assert(std::is_const<decltype(t)>::value, "message"); + // expected-error-re@-1{{static_assert failed due to requirement 'std::is_const<(lambda at {{.*}}static-assert.cpp:{{[0-9]*}}:{{[0-9]*}})>::value' "message"}} +} +void callFoo3() { + foo3([]() {}); + // expected-note@-1{{in instantiation of function template specialization 'foo3<(lambda at }} +} + +template <class T> +void foo4(T t) { + static_assert(std::is_const<typename T::iterator>::value, "message"); + // expected-error@-1{{type 'int' cannot be used prior to '::' because it has no members}} +} +void callFoo4() { foo4(42); } +// expected-note@-1{{in instantiation of function template specialization 'foo4<int>' requested here}} diff --git a/test/SemaCXX/struct-class-redecl.cpp b/test/SemaCXX/struct-class-redecl.cpp index 7375319186..622d5a0b65 100644 --- a/test/SemaCXX/struct-class-redecl.cpp +++ b/test/SemaCXX/struct-class-redecl.cpp @@ -47,14 +47,43 @@ class E; struct F; struct F; -struct F {}; +struct F {}; // expected-note {{previous use}} struct F; +class F; // expected-warning {{previously declared as a struct}} expected-note {{did you mean struct}} template<class U> class G; // expected-note{{previous use is here}}\ // expected-note{{did you mean struct here?}} template<class U> struct G; // expected-warning{{struct template 'G' was previously declared as a class template}} template<class U> struct G {}; // expected-warning{{'G' defined as a struct template here but previously declared as a class template}} +// Declarations from contexts where the warning is disabled are entirely +// ignored for the purpose of this warning. +struct J; +struct K; // expected-note {{previous use}} +struct L; +struct M; // expected-note {{previous use}} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmismatched-tags" +struct H; +class I {}; +class J; +class K; +class L; +class M {}; +#pragma clang diagnostic pop + +class H; // expected-note {{previous use}} +struct H; // expected-warning {{previously declared as a class}} + +struct I; // expected-note {{previous use}} +class I; // expected-warning {{previously declared as a struct}} + +struct J; +class K; // expected-warning {{previously declared as a struct}} +struct L; +class M; // expected-warning {{previously declared as a struct}} + /* *** 'X' messages *** CHECK: warning: struct 'X' was previously declared as a class diff --git a/test/SemaCXX/switch-implicit-fallthrough.cpp b/test/SemaCXX/switch-implicit-fallthrough.cpp index 9540b1ff28..6ccac122cf 100644 --- a/test/SemaCXX/switch-implicit-fallthrough.cpp +++ b/test/SemaCXX/switch-implicit-fallthrough.cpp @@ -314,3 +314,18 @@ int fallthrough_targets(int n) { } return n; } + +int fallthrough_alt_spelling(int n) { + switch (n) { + case 0: + n++; + [[clang::fallthrough]]; + case 1: + n++; + [[clang::__fallthrough__]]; + case 2: + n++; + break; + } + return n; +} diff --git a/test/SemaCXX/template-implicit-vars.cpp b/test/SemaCXX/template-implicit-vars.cpp deleted file mode 100644 index 25d35fbdb8..0000000000 --- a/test/SemaCXX/template-implicit-vars.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -ast-dump | FileCheck %s -template<typename T> -void f(T t) { - T a[] = {t}; - for (auto x : a) {} -} - -void g() { - f(1); -} -// CHECK: VarDecl {{.*}} implicit used __range -// CHECK: VarDecl {{.*}} implicit used __range -// CHECK: VarDecl {{.*}} implicit used __begin -// CHECK: VarDecl {{.*}} implicit used __end diff --git a/test/SemaCXX/vector.cpp b/test/SemaCXX/vector.cpp index 56a8a6db5b..a6a4ceb0e5 100644 --- a/test/SemaCXX/vector.cpp +++ b/test/SemaCXX/vector.cpp @@ -17,14 +17,14 @@ void f0_test(char16 c16, longlong16 ll16, char16_e c16e, longlong16_e ll16e) { f0(ll16e); } -int &f1(char16); // expected-note 2{{candidate function}} -float &f1(longlong16); // expected-note 2{{candidate function}} +int &f1(char16); +float &f1(longlong16); void f1_test(char16 c16, longlong16 ll16, char16_e c16e, longlong16_e ll16e) { int &ir1 = f1(c16); float &fr1 = f1(ll16); - f1(c16e); // expected-error{{call to 'f1' is ambiguous}} - f1(ll16e); // expected-error{{call to 'f1' is ambiguous}} + int &ir2 = f1(c16e); + float &fr2 = f1(ll16e); } void f2(char16_e); // expected-note{{no known conversion from 'longlong16_e' (vector of 2 'long long' values) to 'char16_e' (vector of 16 'char' values) for 1st argument}} \ diff --git a/test/SemaCXX/warn-comma-operator.cpp b/test/SemaCXX/warn-comma-operator.cpp index 3192f688f1..0ed127b943 100644 --- a/test/SemaCXX/warn-comma-operator.cpp +++ b/test/SemaCXX/warn-comma-operator.cpp @@ -1,8 +1,16 @@ // RUN: %clang_cc1 -fsyntax-only -Wcomma -std=c++11 -verify %s // RUN: %clang_cc1 -fsyntax-only -Wcomma -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c89 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c99 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c17 -verify %s + +// int returning function +int return_four() { return 5; } + // Test builtin operators -void test1() { +void test_builtin() { int x = 0, y = 0; for (; y < 10; x++, y++) {} for (; y < 10; ++x, y++) {} @@ -23,6 +31,116 @@ void test1() { for (; y < 10; x ^= 5, ++y) {} } +// Test nested comma operators +void test_nested() { + int x1, x2, x3; + int y1, *y2 = 0, y3 = 5; + +#if __STDC_VERSION >= 199901L + for (int z1 = 5, z2 = 4, z3 = 3; x1 <4; ++x1) {} +#endif +} + +// Confusing "," for "==" +void test_compare() { + if (return_four(), 5) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:7-[[@LINE-3]]:7}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:20-[[@LINE-4]]:20}:")" + + if (return_four() == 5) {} +} + +// Confusing "," for "+" +int test_plus() { + return return_four(), return_four(); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" + + return return_four() + return_four(); +} + +// Be sure to look through parentheses +void test_parentheses() { + int x, y; + for (x = 0; return_four(), x;) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:15-[[@LINE-3]]:15}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:28-[[@LINE-4]]:28}:")" + + for (x = 0; (return_four()), (x) ;) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:15-[[@LINE-3]]:15}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:30-[[@LINE-4]]:30}:")" +} + +void test_increment() { + int x, y; + ++x, ++y; + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:6-[[@LINE-4]]:6}:")" +} + +// Check for comma operator in conditions. +void test_conditions(int x) { + x = (return_four(), x); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:8-[[@LINE-3]]:8}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:21-[[@LINE-4]]:21}:")" + + int y = (return_four(), x); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:12-[[@LINE-3]]:12}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:25-[[@LINE-4]]:25}:")" + + for (; return_four(), x;) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" + + while (return_four(), x) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" + + if (return_four(), x) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:7-[[@LINE-3]]:7}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:20-[[@LINE-4]]:20}:")" + + do { } while (return_four(), x); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:17-[[@LINE-3]]:17}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:30-[[@LINE-4]]:30}:")" +} + +// Nested comma operator with fix-its. +void test_nested_fixits() { + return_four(), return_four(), return_four(), return_four(); + // expected-warning@-1 3{{comma operator}} + // expected-note@-2 3{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:16-[[@LINE-4]]:16}:")" + // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:18-[[@LINE-5]]:18}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:31-[[@LINE-6]]:31}:")" + // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:33-[[@LINE-7]]:33}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")" +} + +#ifdef __cplusplus class S2 { public: void advance(); @@ -45,7 +163,7 @@ public: }; // Test overloaded operators -void test2() { +void test_overloaded_operator() { S2 x; int y; for (; y < 10; x++, y++) {} @@ -67,22 +185,13 @@ void test2() { for (; y < 10; x ^= 5, ++y) {} } -// Test nested comma operators -void test3() { - int x1, x2, x3; - int y1, *y2 = 0, y3 = 5; - for (int z1 = 5, z2 = 4, z3 = 3; x1 <4; ++x1) {} -} - class Stream { public: Stream& operator<<(int); } cout; -int return_four() { return 5; } - // Confusing "," for "<<" -void test4() { +void test_stream() { cout << 5 << return_four(); cout << 5, return_four(); // expected-warning@-1{{comma operator}} @@ -91,33 +200,11 @@ void test4() { // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:12-[[@LINE-4]]:12}:")" } -// Confusing "," for "==" -void test5() { - if (return_four(), 5) {} - // expected-warning@-1{{comma operator}} - // expected-note@-2{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:7-[[@LINE-3]]:7}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:20-[[@LINE-4]]:20}:")" - - if (return_four() == 5) {} -} - -// Confusing "," for "+" -int test6() { - return return_four(), return_four(); - // expected-warning@-1{{comma operator}} - // expected-note@-2{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" - - return return_four() + return_four(); -} - void Concat(int); void Concat(int, int); // Testing extra parentheses in function call -void test7() { +void test_overloaded_function() { Concat((return_four() , 5)); // expected-warning@-1{{comma operator}} // expected-note@-2{{cast expression to void}} @@ -127,22 +214,6 @@ void test7() { Concat(return_four() , 5); } -// Be sure to look through parentheses -void test8() { - int x, y; - for (x = 0; return_four(), x;) {} - // expected-warning@-1{{comma operator}} - // expected-note@-2{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:15-[[@LINE-3]]:15}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:28-[[@LINE-4]]:28}:")" - - for (x = 0; (return_four()), (x) ;) {} - // expected-warning@-1{{comma operator}} - // expected-note@-2{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:15-[[@LINE-3]]:15}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:30-[[@LINE-4]]:30}:")" -} - bool DoStuff(); class S9 { public: @@ -151,24 +222,15 @@ public: }; // Ignore comma operator in for-loop initializations and increments. -void test9() { +void test_for_loop() { int x, y; for (x = 0, y = 5; x < y; ++x) {} for (x = 0; x < 10; DoStuff(), ++x) {} for (S9 s; s.More(); s.Advance(), ++x) {} } -void test10() { - int x, y; - ++x, ++y; - // expected-warning@-1{{comma operator}} - // expected-note@-2{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:6-[[@LINE-4]]:6}:")" -} - // Ignore comma operator in templates. -namespace test11 { +namespace test_template { template <bool T> struct B { static const bool value = T; }; @@ -188,7 +250,7 @@ class Foo { const auto X = Foo<true_type>(); } -namespace test12 { +namespace test_mutex { class Mutex { public: Mutex(); @@ -225,54 +287,13 @@ bool get_status() { } } -// Check for comma operator in conditions. -void test13(int x) { - x = (return_four(), x); - // expected-warning@-1{{comma operator}} - // expected-note@-2{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:8-[[@LINE-3]]:8}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:21-[[@LINE-4]]:21}:")" - - int y = (return_four(), x); - // expected-warning@-1{{comma operator}} - // expected-note@-2{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:12-[[@LINE-3]]:12}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:25-[[@LINE-4]]:25}:")" - - for (; return_four(), x;) {} - // expected-warning@-1{{comma operator}} - // expected-note@-2{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" - - while (return_four(), x) {} - // expected-warning@-1{{comma operator}} - // expected-note@-2{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" - - if (return_four(), x) {} - // expected-warning@-1{{comma operator}} - // expected-note@-2{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:7-[[@LINE-3]]:7}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:20-[[@LINE-4]]:20}:")" +// PR39375 - test cast to void to silence warnings +template <typename T> +void test_dependent_cast() { + (void)42, 0; + static_cast<void>(42), 0; - do { } while (return_four(), x); - // expected-warning@-1{{comma operator}} - // expected-note@-2{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:17-[[@LINE-3]]:17}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:30-[[@LINE-4]]:30}:")" -} - -// Nested comma operator with fix-its. -void test14() { - return_four(), return_four(), return_four(), return_four(); - // expected-warning@-1 3{{comma operator}} - // expected-note@-2 3{{cast expression to void}} - // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:16-[[@LINE-4]]:16}:")" - // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:18-[[@LINE-5]]:18}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:31-[[@LINE-6]]:31}:")" - // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:33-[[@LINE-7]]:33}:"static_cast<void>(" - // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")" + (void)T{}, 0; + static_cast<void>(T{}), 0; } +#endif // ifdef __cplusplus diff --git a/test/SemaCXX/warn-loop-analysis.cpp b/test/SemaCXX/warn-loop-analysis.cpp index 2934003848..324dd38629 100644 --- a/test/SemaCXX/warn-loop-analysis.cpp +++ b/test/SemaCXX/warn-loop-analysis.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wloop-analysis -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wloop-analysis -verify -std=c++17 %s struct S { bool stop() { return false; } @@ -278,3 +278,24 @@ void test9() { // Don't warn when variable is defined by the loop condition. for (int i = 0; int x = f(i); ++i) {} } + +// Don't warn when decomposition variables are in the loop condition. +// TODO: BindingDecl's which make a copy should warn. +void test10() { + int arr[] = {1, 2, 3}; + for (auto[i, j, k] = arr;;) { } + for (auto[i, j, k] = arr; i < j; ++i, ++j) { } + + for (auto[i, j, k] = arr; i;) { } + for (auto[i, j, k] = arr; i < j;) { } + for (auto[i, j, k] = arr; i < j; ++arr[0]) { } + + int a = 1, b = 2; + for (auto[i, j, k] = arr; a < b;) { } // expected-warning{{variables 'a' and 'b' used in loop condition not modified in loop body}} + for (auto[i, j, k] = arr; a < b; ++a) { } + + for (auto [i, j, k] = arr; i < a;) { } + for (auto[i, j, k] = arr; i < a; ++a) { } + for (auto[i, j, k] = arr; i < a; ++i) { } + for (auto[i, j, k] = arr; i < a; ++arr[0]) { } +}; diff --git a/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp b/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp index e69a81b77f..3312b5635f 100644 --- a/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp +++ b/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify +// RUN: %clang_cc1 %s -fsyntax-only -verify -Wcall-to-pure-virtual-from-ctor-dtor struct A { A() { f(); } // expected-warning {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the constructor of 'A'}} ~A() { f(); } // expected-warning {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the destructor of 'A'}} diff --git a/test/SemaCXX/warn-shadow-in-lambdas.cpp b/test/SemaCXX/warn-shadow-in-lambdas.cpp index b0dcd122a5..a772af049a 100644 --- a/test/SemaCXX/warn-shadow-in-lambdas.cpp +++ b/test/SemaCXX/warn-shadow-in-lambdas.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow -D AVOID %s // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow -Wshadow-uncaptured-local %s // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow-all %s +// RUN: %clang_cc1 -std=c++17 -verify -fsyntax-only -Wshadow-all %s void foo(int param) { // expected-note 1+ {{previous declaration is here}} int var = 0; // expected-note 1+ {{previous declaration is here}} @@ -79,7 +80,7 @@ void foo(int param) { // expected-note 1+ {{previous declaration is here}} int var = 1; // expected-warning {{declaration shadows a local variable}} }; auto f2 = [param] // expected-note {{variable 'param' is explicitly captured here}} - (int param) { ; }; // expected-warning {{declaration shadows a local variable}} + (int param) { ; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}} } // Warn for variables defined in the capture list. @@ -135,7 +136,7 @@ void foo(int param) { // expected-note 1+ {{previous declaration is here}} auto g2 = [=](auto param) { ; }; // expected-warning {{declaration shadows a local variable}} #endif auto g3 = [param] // expected-note {{variable 'param' is explicitly captured here}} - (auto param) { ; }; // expected-warning {{declaration shadows a local variable}} + (auto param) { ; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}} } void avoidWarningWhenRedefining() { diff --git a/test/SemaCXX/warn-shadow.cpp b/test/SemaCXX/warn-shadow.cpp index 3d09c78628..f4a904b7ed 100644 --- a/test/SemaCXX/warn-shadow.cpp +++ b/test/SemaCXX/warn-shadow.cpp @@ -59,13 +59,13 @@ class A { // expected-warning-re@+1 4 {{constructor parameter 'f{{[0-4]}}' shadows the field 'f{{[0-9]}}' of 'A'}} A(int f1, int f2, int f3, int f4, double overload_dummy) {} - void test() { - char *field; // expected-warning {{declaration shadows a field of 'A'}} - char *data; // expected-warning {{declaration shadows a static data member of 'A'}} + void test() {
+ char *field; // expected-warning {{declaration shadows a field of 'A'}}
+ char *data; // expected-warning {{declaration shadows a static data member of 'A'}}
char *a1; // no warning - char *a2; // no warning - char *jj; // no warning - char *jjj; // no warning + char *a2; // no warning
+ char *jj; // no warning
+ char *jjj; // no warning
} void test2() { @@ -196,14 +196,14 @@ void avoidWarningWhenRedefining(int b) { // expected-note {{previous definition int k; // expected-note {{previous definition is here}} typedef int k; // expected-error {{redefinition of 'k'}} - using l=char; // no warning or error. - using l=char; // no warning or error. - typedef char l; // no warning or error. + using l=char; // no warning or error.
+ using l=char; // no warning or error.
+ typedef char l; // no warning or error.
typedef char n; // no warning or error. typedef char n; // no warning or error. - using n=char; // no warning or error. -} + using n=char; // no warning or error.
+}
} @@ -219,6 +219,49 @@ void f(int a) { struct A { void g(int a) {} A() { int a; } + };
+}
+}
+
+namespace PR34120 {
+struct A {
+ int B; // expected-note 2 {{declared here}}
+};
+
+class C : public A {
+ void D(int B) {} // expected-warning {{parameter 'B' shadows member inherited from type 'A'}}
+ void E() {
+ extern void f(int B); // Ok
+ }
+ void F(int B); // Ok, declaration; not definition.
+ void G(int B);
+};
+
+void C::G(int B) { // expected-warning {{parameter 'B' shadows member inherited from type 'A'}}
+}
+
+class Private {
+ int B;
+};
+class Derived : Private {
+ void D(int B) {} // Ok
+};
+
+struct Static {
+ static int B;
+};
+
+struct Derived2 : Static {
+ void D(int B) {}
+};
+}
+ +int PR24718; +enum class X { PR24718 }; // Ok, not shadowing + +struct PR24718_1; +struct PR24718_2 { + enum { + PR24718_1 // Does not shadow a type. }; -} -} +}; diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp index 057fd17608..54e3369f4d 100644 --- a/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1754,6 +1754,13 @@ struct TestTryLock { mu.Unlock(); } + void foo2_builtin_expect() { + if (__builtin_expect(!mu.TryLock(), false)) + return; + a = 2; + mu.Unlock(); + } + void foo3() { bool b = mu.TryLock(); if (b) { @@ -1762,6 +1769,14 @@ struct TestTryLock { } } + void foo3_builtin_expect() { + bool b = mu.TryLock(); + if (__builtin_expect(b, true)) { + a = 3; + mu.Unlock(); + } + } + void foo4() { bool b = mu.TryLock(); if (!b) return; @@ -1858,6 +1873,23 @@ struct TestTryLock { int i = a; mu.Unlock(); } + + // Test with conditional operator + void foo13() { + if (mu.TryLock() ? 1 : 0) + mu.Unlock(); + } + + void foo14() { + if (mu.TryLock() ? 0 : 1) + return; + mu.Unlock(); + } + + void foo15() { + if (mu.TryLock() ? 0 : 1) // expected-note{{mutex acquired here}} + mu.Unlock(); // expected-warning{{releasing mutex 'mu' that was not held}} + } // expected-warning{{mutex 'mu' is not held on every path through here}} }; // end TestTrylock } // end namespace TrylockTest @@ -4982,6 +5014,8 @@ public: void operator+(const Foo& f); void operator[](const Foo& g); + + void operator()(); }; template<class T> @@ -4999,8 +5033,23 @@ void destroy(Foo&& f); void operator/(const Foo& f, const Foo& g); void operator*(const Foo& f, const Foo& g); +// Test constructors. +struct FooRead { + FooRead(const Foo &); +}; +struct FooWrite { + FooWrite(Foo &); +}; +// Test variadic functions +template<typename... T> +void copyVariadic(T...) {} +template<typename... T> +void writeVariadic(T&...) {} +template<typename... T> +void readVariadic(const T&...) {} +void copyVariadicC(int, ...); class Bar { public: @@ -5032,6 +5081,14 @@ public: read2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} destroy(mymove(foo)); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} + copyVariadic(foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} + readVariadic(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} + writeVariadic(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} + copyVariadicC(1, foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} + + FooRead reader(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} + FooWrite writer(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} + mwrite1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} mwrite2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} mread1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} @@ -5050,6 +5107,7 @@ public: // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}} foo[foo2]; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \ // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}} + foo(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} (*this) << foo; // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} copy(*foop); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu'}} |