diff options
author | dim <dim@FreeBSD.org> | 2015-05-27 18:47:56 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-05-27 18:47:56 +0000 |
commit | 3191b2b32a96e1a6ee833fcca73e5c8e0c67ba65 (patch) | |
tree | dbbd4047878da71c1a706e26ce05b4e7791b14cc /test/SemaCXX | |
parent | 38d6f2e7f2ce51a5b3836d26596c6c34a3288752 (diff) | |
download | FreeBSD-src-3191b2b32a96e1a6ee833fcca73e5c8e0c67ba65.zip FreeBSD-src-3191b2b32a96e1a6ee833fcca73e5c8e0c67ba65.tar.gz |
Vendor import of clang trunk r238337:
https://llvm.org/svn/llvm-project/cfe/trunk@238337
Diffstat (limited to 'test/SemaCXX')
113 files changed, 2892 insertions, 231 deletions
diff --git a/test/SemaCXX/MicrosoftCompatibility.cpp b/test/SemaCXX/MicrosoftCompatibility.cpp index 56486b8..1536007 100644 --- a/test/SemaCXX/MicrosoftCompatibility.cpp +++ b/test/SemaCXX/MicrosoftCompatibility.cpp @@ -1,9 +1,19 @@ -// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions - +// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions -fms-compatibility-version=19.00 +// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions -fms-compatibility-version=18.00 +#if defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT +char16_t x; +char32_t y; +#else typedef unsigned short char16_t; typedef unsigned int char32_t; +#endif + +#if _MSC_VER >= 1900 +_Atomic(int) z; +#else struct _Atomic {}; +#endif typename decltype(3) a; // expected-warning {{expected a qualified name after 'typename'}} diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp index 57d6f0d..db5e458 100644 --- a/test/SemaCXX/MicrosoftExtensions.cpp +++ b/test/SemaCXX/MicrosoftExtensions.cpp @@ -344,6 +344,18 @@ struct StructWithUnnamedMember { __declspec(property(get=GetV)) int : 10; // expected-error {{anonymous property is not supported}} }; +struct MSPropertyClass { + int get() { return 42; } + int __declspec(property(get = get)) n; +}; + +int *f(MSPropertyClass &x) { + return &x.n; // expected-error {{address of property expression requested}} +} +int MSPropertyClass::*g() { + return &MSPropertyClass::n; // expected-error {{address of property expression requested}} +} + namespace rdar14250378 { class Bar {}; diff --git a/test/SemaCXX/MicrosoftSuper.cpp b/test/SemaCXX/MicrosoftSuper.cpp index cb21656..df63691 100644 --- a/test/SemaCXX/MicrosoftSuper.cpp +++ b/test/SemaCXX/MicrosoftSuper.cpp @@ -147,3 +147,12 @@ void instantiate() { DerivedFromTemplateParameter<Base1> t; t.foo(); } + +namespace { +struct B { int a; }; +template <class C> +struct A : B { + // Don't crash on dependent_type_var '->' '__super' + void f() { int a = this->__super::a; } +}; +} diff --git a/test/SemaCXX/PR21679.cpp b/test/SemaCXX/PR21679.cpp new file mode 100644 index 0000000..06db2bf --- /dev/null +++ b/test/SemaCXX/PR21679.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int w = z.; // expected-error {{use of undeclared identifier 'z'}} \ + // expected-error {{expected unqualified-id}} + +int x = { y[ // expected-error {{use of undeclared identifier 'y'}} \ + // expected-note {{to match this '['}} \ + // expected-note {{to match this '{'}} \ + // expected-error {{expected ';' after top level declarator}} + +// The errors below all occur on the last line of the file, so splitting them +// among multiple lines doesn't work. +// expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected '}'}} diff --git a/test/SemaCXX/PR23334.cpp b/test/SemaCXX/PR23334.cpp new file mode 100644 index 0000000..cd6b4f4 --- /dev/null +++ b/test/SemaCXX/PR23334.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-unused + +// This must be at the start of the file (the failure depends on a SmallPtrSet +// not having been reallocated yet). +void fn1() { + // expected-no-diagnostics + constexpr int kIsolationClass = 0; + const int kBytesPerConnection = 0; + [=] { kIsolationClass, kBytesPerConnection, kBytesPerConnection; }; +} diff --git a/test/SemaCXX/PR9461.cpp b/test/SemaCXX/PR9461.cpp index beed348..f97a208 100644 --- a/test/SemaCXX/PR9461.cpp +++ b/test/SemaCXX/PR9461.cpp @@ -22,9 +22,9 @@ _S_construct(); // expected-error {{requires}} }; template<typename _CharT,typename _Traits,typename _Alloc> -basic_string<_CharT,_Traits,_Alloc>::basic_string(const _CharT*,const _Alloc&) +basic_string<_CharT,_Traits,_Alloc>::basic_string(const _CharT* c,const _Alloc&) :us(_S_construct) -{string a;} +{string a(c);} struct runtime_error{runtime_error(string);}; diff --git a/test/SemaCXX/__try.cpp b/test/SemaCXX/__try.cpp index 28a3701..eb4612f 100644 --- a/test/SemaCXX/__try.cpp +++ b/test/SemaCXX/__try.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fborland-extensions -fcxx-exceptions %s +// RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fborland-extensions -fcxx-exceptions %s // This test is from http://docwiki.embarcadero.com/RADStudio/en/Try diff --git a/test/SemaCXX/accessible-base.cpp b/test/SemaCXX/accessible-base.cpp new file mode 100644 index 0000000..6bf06ce --- /dev/null +++ b/test/SemaCXX/accessible-base.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A { + int a; +}; + +struct X1 : virtual A +{}; + +struct Y1 : X1, virtual A +{}; + +struct Y2 : X1, A // expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n struct Y2 -> struct X1 -> struct A\n struct Y2 -> struct A}} +{}; + +struct X2 : A +{}; + +struct Z1 : X2, virtual A // expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n struct Z1 -> struct X2 -> struct A\n struct Z1 -> struct A}} +{}; + +struct Z2 : X2, A // expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n struct Z2 -> struct X2 -> struct A\n struct Z2 -> struct A}} +{}; diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp index 358fe8d..6d05503 100644 --- a/test/SemaCXX/addr-of-overloaded-function.cpp +++ b/test/SemaCXX/addr-of-overloaded-function.cpp @@ -222,11 +222,11 @@ namespace test1 { void (Qualifiers::*X)(); X = &Qualifiers::C; // expected-error-re {{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (none vs const)}} X = &Qualifiers::V; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (none vs volatile)}} - X = &Qualifiers::R; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} restrict': different qualifiers (none vs restrict)}} + X = &Qualifiers::R; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} __restrict': different qualifiers (none vs restrict)}} X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (none vs const and volatile)}} - X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const restrict': different qualifiers (none vs const and restrict)}} - X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile restrict': different qualifiers (none vs volatile and restrict)}} - X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile restrict': different qualifiers (none vs const, volatile, and restrict)}} + X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const __restrict': different qualifiers (none vs const and restrict)}} + X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile __restrict': different qualifiers (none vs volatile and restrict)}} + X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile __restrict': different qualifiers (none vs const, volatile, and restrict)}} } struct Dummy { diff --git a/test/SemaCXX/alignof.cpp b/test/SemaCXX/alignof.cpp index 011f459..e3690ea 100644 --- a/test/SemaCXX/alignof.cpp +++ b/test/SemaCXX/alignof.cpp @@ -77,3 +77,23 @@ namespace alignof_array_expr { // ok, does not complete type of S<-1>::a static_assert(alignof(S<-1>::a) == alignof(int), ""); // expected-warning {{GNU extension}} } + +template <typename T> void n(T) { + alignas(T) int T1; + char k[__alignof__(T1)]; + static_assert(sizeof(k) == alignof(long long), ""); +} +template void n(long long); + +namespace PR22042 { +template <typename T> +void Fun(T A) { + typedef int __attribute__((__aligned__(A))) T1; // expected-error {{requested alignment is dependent but declaration is not dependent}} + int k1[__alignof__(T1)]; +} + +template <int N> +struct S { + typedef __attribute__((aligned(N))) int Field[sizeof(N)]; // expected-error {{requested alignment is dependent but declaration is not dependent}} +}; +} diff --git a/test/SemaCXX/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp index 46d426c..3520245 100644 --- a/test/SemaCXX/anonymous-union.cpp +++ b/test/SemaCXX/anonymous-union.cpp @@ -39,13 +39,14 @@ void X::test_unqual_references() { a = 0; } -void X::test_unqual_references_const() const { +void X::test_unqual_references_const() const { // expected-note 2{{member function 'X::test_unqual_references_const' is declared const here}} d = 0.0; - f2 = 0; // expected-error{{read-only variable is not assignable}} - a = 0; // expected-error{{read-only variable is not assignable}} + f2 = 0; // expected-error{{cannot assign to non-static data member within const member function 'test_unqual_references_const'}} + a = 0; // expected-error{{cannot assign to non-static data member within const member function 'test_unqual_references_const'}} } void test_unqual_references(X x, const X xc) { + // expected-note@-1 2{{variable 'xc' declared const here}} x.i = 0; x.f = 0.0; x.f2 = x.f; @@ -54,8 +55,8 @@ void test_unqual_references(X x, const X xc) { x.a = 0; xc.d = 0.0; - xc.f = 0; // expected-error{{read-only variable is not assignable}} - xc.a = 0; // expected-error{{read-only variable is not assignable}} + xc.f = 0; // expected-error{{cannot assign to variable 'xc' with const-qualified type 'const X'}} + xc.a = 0; // expected-error{{cannot assign to variable 'xc' with const-qualified type 'const X'}} } diff --git a/test/SemaCXX/ast-print.cpp b/test/SemaCXX/ast-print.cpp index baece3c..1b57406 100644 --- a/test/SemaCXX/ast-print.cpp +++ b/test/SemaCXX/ast-print.cpp @@ -53,7 +53,7 @@ void test6() { test6fn((int&)y); } -// CHECK: S s( 1, 2 ); +// CHECK: S s(1, 2); template <class S> void test7() { @@ -213,3 +213,9 @@ namespace { // CHECK: struct {{\[\[gnu::visibility\(\"hidden\"\)\]\]}} S; struct [[gnu::visibility("hidden")]] S; } + +// CHECK: struct CXXFunctionalCastExprPrint fce = CXXFunctionalCastExprPrint{}; +struct CXXFunctionalCastExprPrint {} fce = CXXFunctionalCastExprPrint{}; + +// CHECK: struct CXXTemporaryObjectExprPrint toe = CXXTemporaryObjectExprPrint{}; +struct CXXTemporaryObjectExprPrint { CXXTemporaryObjectExprPrint(); } toe = CXXTemporaryObjectExprPrint{}; diff --git a/test/SemaCXX/atomic-type.cpp b/test/SemaCXX/atomic-type.cpp index 779b067..a2b314a 100644 --- a/test/SemaCXX/atomic-type.cpp +++ b/test/SemaCXX/atomic-type.cpp @@ -71,6 +71,8 @@ namespace copy_init { #if __cplusplus >= 201103L _Atomic(X) e2{0}; // expected-error {{illegal initializer}} _Atomic(X) a{X(0)}; + // FIXME: This does not seem like the right answer. + _Atomic(int) e3{0}; // expected-error {{illegal initializer}} #endif struct Y { @@ -79,9 +81,14 @@ namespace copy_init { }; Y y1 = { X(0), 4 }; Y y2 = { 0, 4 }; // expected-error {{cannot initialize}} + // FIXME: It's not really clear if we should allow these. Generally, C++11 - // allows extraneous braces around initializers. - Y y3 = { { X(0) }, { 4 } }; // expected-error 2{{illegal initializer type}} + // allows extraneous braces around initializers. We should at least give the + // same answer in all these cases: + Y y3 = { X(0), { 4 } }; // expected-error {{illegal initializer type}} + Y y4 = { { X(0) }, 4 }; + _Atomic(int) ai = { 4 }; // expected-error {{illegal initializer type}} + _Atomic(X) ax = { X(0) }; } bool PR21836(_Atomic(int) *x) { diff --git a/test/SemaCXX/attr-flag-enum-reject.cpp b/test/SemaCXX/attr-flag-enum-reject.cpp new file mode 100644 index 0000000..f28d60c --- /dev/null +++ b/test/SemaCXX/attr-flag-enum-reject.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -Wassign-enum %s + +enum __attribute__((flag_enum)) flag { // expected-warning {{ignored}} +}; diff --git a/test/SemaCXX/attr-no-sanitize.cpp b/test/SemaCXX/attr-no-sanitize.cpp new file mode 100644 index 0000000..741f760 --- /dev/null +++ b/test/SemaCXX/attr-no-sanitize.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// RUN: not %clang_cc1 -std=c++11 -ast-dump %s | FileCheck --check-prefix=DUMP %s +// RUN: not %clang_cc1 -std=c++11 -ast-print %s | FileCheck --check-prefix=PRINT %s + +int v1 __attribute__((no_sanitize("address"))); // expected-error{{'no_sanitize' attribute only applies to functions and methods}} + +int f1() __attribute__((no_sanitize)); // expected-error{{'no_sanitize' attribute takes at least 1 argument}} + +int f2() __attribute__((no_sanitize(1))); // expected-error{{'no_sanitize' attribute requires a string}} + +// DUMP-LABEL: FunctionDecl {{.*}} f3 +// DUMP: NoSanitizeAttr {{.*}} address +// PRINT: int f3() __attribute__((no_sanitize("address"))) +int f3() __attribute__((no_sanitize("address"))); + +// DUMP-LABEL: FunctionDecl {{.*}} f4 +// DUMP: NoSanitizeAttr {{.*}} thread +// PRINT: int f4() {{\[\[}}clang::no_sanitize("thread")]] +[[clang::no_sanitize("thread")]] int f4(); + +// DUMP-LABEL: FunctionDecl {{.*}} f5 +// DUMP: NoSanitizeAttr {{.*}} address thread +// PRINT: int f5() __attribute__((no_sanitize("address", "thread"))) +int f5() __attribute__((no_sanitize("address", "thread"))); + +// DUMP-LABEL: FunctionDecl {{.*}} f6 +// DUMP: NoSanitizeAttr {{.*}} unknown +// PRINT: int f6() __attribute__((no_sanitize("unknown"))) +int f6() __attribute__((no_sanitize("unknown"))); // expected-warning{{unknown sanitizer 'unknown' ignored}} diff --git a/test/SemaCXX/attr-selectany.cpp b/test/SemaCXX/attr-selectany.cpp index c27a915..058f2fc 100644 --- a/test/SemaCXX/attr-selectany.cpp +++ b/test/SemaCXX/attr-selectany.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 %s // MSVC produces similar diagnostics. __declspec(selectany) void foo() { } // expected-error{{'selectany' can only be applied to data items with external linkage}} @@ -34,3 +34,17 @@ __declspec(selectany) X x(1); namespace { class Internal {}; } __declspec(selectany) auto x8 = Internal(); // expected-error {{'selectany' can only be applied to data items with external linkage}} + + +// The D3D11 headers do something like this. MSVC doesn't error on this at +// all, even without the __declspec(selectany), in violation of the standard. +// We fall back to a warning for selectany to accept headers. +struct SomeStruct {}; +extern const __declspec(selectany) SomeStruct some_struct; // expected-warning {{default initialization of an object of const type 'const SomeStruct' without a user-provided default constructor is a Microsoft extension}} + +// It should be possible to redeclare variables that were defined +// __declspec(selectany) previously. +extern const SomeStruct some_struct; + +// Without selectany, this should stay an error. +const SomeStruct some_struct2; // expected-error {{default initialization of an object of const type 'const SomeStruct' without a user-provided default constructor}} diff --git a/test/SemaCXX/builtins-arm.cpp b/test/SemaCXX/builtins-arm.cpp index 8a0cf81..bd70b81 100644 --- a/test/SemaCXX/builtins-arm.cpp +++ b/test/SemaCXX/builtins-arm.cpp @@ -2,5 +2,5 @@ // va_list on ARM AAPCS is struct { void* __ap }. int test1(const __builtin_va_list &ap) { - return __builtin_va_arg(ap, int); // expected-error {{binding of reference to type '__builtin_va_list' to a value of type 'const __builtin_va_list' drops qualifiers}} + return __builtin_va_arg(ap, int); // expected-error {{binding value of type 'const __builtin_va_list' to reference to type '__builtin_va_list' drops 'const' qualifier}} } diff --git a/test/SemaCXX/captured-statements.cpp b/test/SemaCXX/captured-statements.cpp index 5fb686c..d8f77e6 100644 --- a/test/SemaCXX/captured-statements.cpp +++ b/test/SemaCXX/captured-statements.cpp @@ -81,11 +81,11 @@ void test_capture_var() { } template <typename S, typename T> -S template_capture_var(S x, T y) { +S template_capture_var(S x, T y) { // expected-note{{variable 'y' declared const here}} #pragma clang _debug captured { x++; - y++; // expected-error{{read-only variable is not assignable}} + y++; // expected-error{{cannot assign to variable 'y' with const-qualified type 'const int'}} } return x; diff --git a/test/SemaCXX/class-layout.cpp b/test/SemaCXX/class-layout.cpp index 64c8ceb..96552de 100644 --- a/test/SemaCXX/class-layout.cpp +++ b/test/SemaCXX/class-layout.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++98 -// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 +// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++98 -Wno-inaccessible-base +// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base // expected-no-diagnostics #define SA(n, p) int a##n[(p) ? 1 : -1] diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp index 636f584..a669440 100644 --- a/test/SemaCXX/class.cpp +++ b/test/SemaCXX/class.cpp @@ -119,9 +119,9 @@ struct C4 { // PR5415 - don't hang! struct S { - void f(); // expected-note 1 {{previous declaration}} - void S::f() {} // expected-error {{extra qualification on member}} expected-error {{class member cannot be redeclared}} expected-note {{previous declaration}} expected-note {{previous definition}} - void f() {} // expected-error {{class member cannot be redeclared}} expected-error {{redefinition}} + void f(); // expected-note 1 {{previous declaration}} expected-note {{previous declaration}} + void S::f() {} // expected-error {{extra qualification on member}} expected-error {{class member cannot be redeclared}} + void f() {} // expected-error {{class member cannot be redeclared}} }; // Don't crash on this bogus code. diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index 14c0ae3..3a1f6c6 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -1179,7 +1179,7 @@ namespace ExternConstexpr { void f() { extern constexpr int i; // expected-error {{constexpr variable declaration must be a definition}} constexpr int j = 0; - constexpr int k; // expected-error {{default initialization of an object of const type}} expected-note{{add an explicit initializer to initialize 'k'}} + constexpr int k; // expected-error {{default initialization of an object of const type}} } } @@ -1984,3 +1984,13 @@ struct InvalidRedef { int f; // expected-note{{previous definition is here}} constexpr int f(void); // expected-error{{redefinition of 'f'}} expected-warning{{will not be implicitly 'const'}} }; + +namespace PR17938 { + template <typename T> constexpr T const &f(T const &x) { return x; } + + struct X {}; + struct Y : X {}; + struct Z : Y { constexpr Z() {} }; + + static constexpr auto z = f(Z()); +} diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp index 3657c18..0651111 100644 --- a/test/SemaCXX/constexpr-value-init.cpp +++ b/test/SemaCXX/constexpr-value-init.cpp @@ -14,7 +14,7 @@ void f() { constexpr A a; // expected-error {{constant expression}} expected-note {{in call to 'A()'}} } -constexpr B b1; // expected-error {{without a user-provided default constructor}} expected-note {{add an explicit initializer to initialize 'b1'}} +constexpr B b1; // expected-error {{without a user-provided default constructor}} constexpr B b2 = B(); // ok static_assert(b2.a.a == 1, ""); static_assert(b2.a.b == 2, ""); @@ -23,9 +23,9 @@ struct C { int c; }; struct D : C { int d; }; -constexpr C c1; // expected-error {{without a user-provided default constructor}} expected-note{{add an explicit initializer to initialize 'c1'}} +constexpr C c1; // expected-error {{without a user-provided default constructor}} constexpr C c2 = C(); // ok -constexpr D d1; // expected-error {{without a user-provided default constructor}} expected-note{{add an explicit initializer to initialize 'd1'}} +constexpr D d1; // expected-error {{without a user-provided default constructor}} constexpr D d2 = D(); // ok with DR1452 static_assert(D().c == 0, ""); static_assert(D().d == 0, ""); diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp index 81dc19e..e3ab610 100644 --- a/test/SemaCXX/constructor-initializer.cpp +++ b/test/SemaCXX/constructor-initializer.cpp @@ -26,7 +26,7 @@ public: D() : B(), C() { } }; -class E : public D, public B { +class E : public D, public B { // expected-warning{{direct base 'B' is inaccessible due to ambiguity:\n class E -> class D -> class C -> class B\n class E -> class B}} public: E() : B(), D() { } // expected-error{{base class initializer 'B' names both a direct base class and an inherited virtual base class}} }; @@ -94,7 +94,7 @@ struct Current : Derived { Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}} Derived::V(), ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} - INT::NonExisting() {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or scoped enumeration}} \ + INT::NonExisting() {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or enumeration}} \ // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} }; @@ -204,7 +204,8 @@ struct A { }; struct B : virtual A { }; -struct C : A, B { }; + + struct C : A, B { }; // expected-warning{{direct base 'Test2::A' is inaccessible due to ambiguity:\n struct Test2::C -> struct Test2::A\n struct Test2::C -> struct Test2::B -> struct Test2::A}} C f(C c) { return c; diff --git a/test/SemaCXX/crashes.cpp b/test/SemaCXX/crashes.cpp index 6ae476f..12251bb 100644 --- a/test/SemaCXX/crashes.cpp +++ b/test/SemaCXX/crashes.cpp @@ -175,16 +175,16 @@ namespace test3 { namespace pr16964 { template<typename> struct bs { bs(); - static int* member(); + static int* member(); // expected-note{{possible target}} member(); // expected-error{{C++ requires a type specifier for all declarations}} static member(); // expected-error{{C++ requires a type specifier for all declarations}} - static int* member(int); + static int* member(int); // expected-note{{possible target}} }; - template<typename T> bs<T>::bs() { member; } + template<typename T> bs<T>::bs() { member; } // expected-error{{did you mean to call it}} bs<int> test() { - return bs<int>(); + return bs<int>(); // expected-note{{in instantiation}} } } @@ -195,7 +195,7 @@ namespace pr12791 { struct forward_iterator_tag : public input_iterator_tag {}; template<typename _CharT, typename _Traits, typename _Alloc> struct basic_string { - struct _Alloc_hider : _Alloc {}; + struct _Alloc_hider : _Alloc { _Alloc_hider(_CharT*, const _Alloc&); }; mutable _Alloc_hider _M_dataplus; template<class _InputIterator> basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc()); template<class _InIterator> static _CharT* _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, input_iterator_tag); @@ -206,12 +206,11 @@ namespace pr12791 { template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InputIterator> basic_string<_CharT, _Traits, _Alloc>:: basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) - : _M_dataplus(_S_construct(__beg, __end, __a), __a) {} + : _M_dataplus(_S_construct(__beg, __end, __a, input_iterator_tag()), __a) {} template<typename _CharT, typename _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT> > struct basic_stringbuf { typedef _CharT char_type; typedef basic_string<char_type, _Traits, _Alloc> __string_type; - typedef typename __string_type::size_type __size_type; __string_type str() const {__string_type((char_type*)0,(char_type*)0);} }; diff --git a/test/SemaCXX/cxx0x-constexpr-const.cpp b/test/SemaCXX/cxx0x-constexpr-const.cpp index 197edeb..a4398b3 100644 --- a/test/SemaCXX/cxx0x-constexpr-const.cpp +++ b/test/SemaCXX/cxx0x-constexpr-const.cpp @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -constexpr int x = 1; +constexpr int x = 1; // expected-note {{variable 'x' declared const here}} constexpr int id(int x) { return x; } void foo(void) { - x = 2; // expected-error {{read-only variable is not assignable}} + x = 2; // expected-error {{cannot assign to variable 'x' with const-qualified type 'const int'}} int (*idp)(int) = id; } diff --git a/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 375cf4a..dfca17a 100644 --- a/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -25,7 +25,7 @@ void fn1 () { non_const_copy ncc2 = ncc; ncc = ncc2; const non_const_copy cncc{}; - const non_const_copy cncc1; // expected-error {{default initialization of an object of const type 'const non_const_copy' without a user-provided default constructor}} expected-note {{add an explicit initializer to initialize 'cncc1'}} + const non_const_copy cncc1; // expected-error {{default initialization of an object of const type 'const non_const_copy' without a user-provided default constructor}} non_const_copy ncc3 = cncc; // expected-error {{no matching}} ncc = cncc; // expected-error {{no viable overloaded}} }; @@ -42,6 +42,28 @@ struct bad_decls { bad_decls& operator = (const bad_decls&) const = default; // expected-error {{may not have 'const', 'constexpr' or 'volatile' qualifiers}} }; +struct DefaultDelete { + DefaultDelete() = default; // expected-note {{previous declaration is here}} + DefaultDelete() = delete; // expected-error {{constructor cannot be redeclared}} + + ~DefaultDelete() = default; // expected-note {{previous declaration is here}} + ~DefaultDelete() = delete; // expected-error {{destructor cannot be redeclared}} + + DefaultDelete &operator=(const DefaultDelete &) = default; // expected-note {{previous declaration is here}} + DefaultDelete &operator=(const DefaultDelete &) = delete; // expected-error {{class member cannot be redeclared}} +}; + +struct DeleteDefault { + DeleteDefault() = delete; // expected-note {{previous definition is here}} + DeleteDefault() = default; // expected-error {{constructor cannot be redeclared}} + + ~DeleteDefault() = delete; // expected-note {{previous definition is here}} + ~DeleteDefault() = default; // expected-error {{destructor cannot be redeclared}} + + DeleteDefault &operator=(const DeleteDefault &) = delete; // expected-note {{previous definition is here}} + DeleteDefault &operator=(const DeleteDefault &) = default; // expected-error {{class member cannot be redeclared}} +}; + struct A {}; struct B {}; struct except_spec_a { diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp index bc03bcd..617a257 100644 --- a/test/SemaCXX/cxx0x-defaulted-functions.cpp +++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp @@ -173,7 +173,7 @@ namespace PR14577 { extern "C" { template<typename _Tp> // expected-error {{templates must have C++ linkage}} - void PR13573(const _Tp&) = delete; // expected-error {{only functions can have deleted definitions}} + void PR13573(const _Tp&) = delete; } namespace PR15597 { diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp index 3ea5309..6202bf6 100644 --- a/test/SemaCXX/cxx0x-initializer-constructor.cpp +++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp @@ -142,6 +142,7 @@ namespace objects { one ov2(int); two ov2(F<3>); + // expected-warning@+1 {{braces around scalar initializer}} static_assert(sizeof(ov2({1})) == sizeof(one), "bad overload"); // list -> int ranks as identity static_assert(sizeof(ov2({1, 2, 3})) == sizeof(two), "bad overload"); // list -> F only viable } @@ -214,7 +215,10 @@ namespace PR12092 { namespace PR12117 { struct A { A(int); }; - struct B { B(A); } b{{0}}; + struct B { B(A); } b{{0}}; //FIXME: non-conformant. Temporary fix until standard resolution. + // expected- error {{call to constructor of 'struct B' is ambiguous}} \ + // expected- note 2{{candidate is the implicit}} \ + // expected- note {{candidate constructor}} struct C { C(int); } c{0}; } diff --git a/test/SemaCXX/cxx0x-initializer-references.cpp b/test/SemaCXX/cxx0x-initializer-references.cpp index d1a9ed3..390047e 100644 --- a/test/SemaCXX/cxx0x-initializer-references.cpp +++ b/test/SemaCXX/cxx0x-initializer-references.cpp @@ -105,12 +105,13 @@ namespace inner_init { B b2 { { 0 } }; B b3 { { { 0 } } }; // expected-warning {{braces around scalar init}} - struct C { C(int); }; + struct C { C(int); }; // expected-note 2{{candidate constructor (the implicit}} \ + // expected-note {{candidate constructor not viable: cannot convert initializer list argument to 'int'}} struct D { C &&r; }; D d1 { 0 }; // ok, 0 implicitly converts to C D d2 { { 0 } }; // ok, { 0 } calls C(0) - D d3 { { { 0 } } }; // ok, { { 0 } } calls C({ 0 }) - D d4 { { { { 0 } } } }; // expected-warning {{braces around scalar init}} + D d3 { { { 0 } } }; // ok, { { 0 } } calls C({ 0 }), expected-warning {{braces around scalar init}} + D d4 { { { { 0 } } } }; // expected-error {{no matching constructor for initialization of 'inner_init::C &&'}} struct E { explicit E(int); }; // expected-note 2{{here}} struct F { E &&r; }; @@ -124,3 +125,7 @@ namespace PR20844 { struct B { operator A&(); } b; A &a{b}; // expected-error {{excess elements}} expected-note {{in initialization of temporary of type 'PR20844::A'}} } + +namespace PR21834 { +const int &a = (const int &){0}; // expected-error {{cannot bind to an initializer list}} +} diff --git a/test/SemaCXX/cxx0x-initializer-scalars.cpp b/test/SemaCXX/cxx0x-initializer-scalars.cpp index 1475dcf..c9d5ffd 100644 --- a/test/SemaCXX/cxx0x-initializer-scalars.cpp +++ b/test/SemaCXX/cxx0x-initializer-scalars.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -pedantic-errors struct one { char c[1]; }; struct two { char c[2]; }; @@ -55,7 +55,7 @@ namespace integral { int ar[10]; (void) ar[{1}]; // expected-error {{array subscript is not an integer}} - return {1}; + return {1}; // expected-warning {{braces around scalar init}} } void inline_init() { @@ -70,15 +70,15 @@ namespace integral { void function_call() { void takes_int(int); - takes_int({1}); + takes_int({1}); // expected-warning {{braces around scalar init}} } void overloaded_call() { one overloaded(int); two overloaded(double); - static_assert(sizeof(overloaded({0})) == sizeof(one), "bad overload"); - static_assert(sizeof(overloaded({0.0})) == sizeof(two), "bad overload"); + static_assert(sizeof(overloaded({0})) == sizeof(one), "bad overload"); // expected-warning {{braces around scalar init}} + static_assert(sizeof(overloaded({0.0})) == sizeof(two), "bad overload"); // expected-warning {{braces around scalar init}} void ambiguous(int, double); // expected-note {{candidate}} void ambiguous(double, int); // expected-note {{candidate}} diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp index 2405d2a..a78f022 100644 --- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -260,3 +260,18 @@ namespace ListInitInstantiate { template<typename T> void g() { int k = f({0}); } template void g<int>(); } + +namespace TemporaryInitListSourceRange_PR22367 { + struct A { + constexpr A() {} + A(std::initializer_list<int>); // expected-note {{here}} + }; + constexpr int f(A) { return 0; } + constexpr int k = f( // expected-error {{must be initialized by a constant expression}} + // The point of this test is to check that the caret points to + // 'std::initializer_list', not to '{0}'. + std::initializer_list // expected-note {{constructor}} + <int> + {0} + ); +} diff --git a/test/SemaCXX/cxx0x-return-init-list.cpp b/test/SemaCXX/cxx0x-return-init-list.cpp index da83271..84bd89b 100644 --- a/test/SemaCXX/cxx0x-return-init-list.cpp +++ b/test/SemaCXX/cxx0x-return-init-list.cpp @@ -4,7 +4,7 @@ // required for libstdc++ 4.5) is supported in C++98. int test0(int i) { - return { i }; // expected-warning{{generalized initializer lists are a C++11 extension}} + return { i }; // expected-warning{{generalized initializer lists are a C++11 extension}} expected-warning {{scalar}} } template<typename T, typename U> diff --git a/test/SemaCXX/cxx11-ast-print.cpp b/test/SemaCXX/cxx11-ast-print.cpp index 5604374..27726de 100644 --- a/test/SemaCXX/cxx11-ast-print.cpp +++ b/test/SemaCXX/cxx11-ast-print.cpp @@ -38,6 +38,11 @@ const char *p8 = 4.9_quux; const char *p9 = 0x42e3F_fritz; // CHECK: const char *p10 = 3.300e+15_fritz; const char *p10 = 3.300e+15_fritz; + +template <class C, C...> const char *operator"" _suffix(); +// CHECK: const char *PR23120 = operator "" _suffix<char32_t, 66615>(); +const char *PR23120 = U"𐐷"_suffix; + // CHECK: ; ; // CHECK-NOT: ; diff --git a/test/SemaCXX/cxx11-call-to-deleted-constructor.cpp b/test/SemaCXX/cxx11-call-to-deleted-constructor.cpp new file mode 100644 index 0000000..dd04345 --- /dev/null +++ b/test/SemaCXX/cxx11-call-to-deleted-constructor.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// rdar://20281011 + +namespace std { +template<class _Ep> class initializer_list { }; +} + +namespace cva { + +template <class VT, unsigned int ROWS = 0, unsigned int COLS = 0> +class Matrix { +public: + + typedef VT value_type; + inline __attribute__((always_inline)) value_type& at(); +}; + +template <class VT, unsigned int SIZE> using Vector = Matrix<VT, SIZE, 1>; + +template <class VT> +using RGBValue = Vector<VT, 3>; +using RGBFValue = RGBValue<float>; + +template <class VT> class Matrix<VT, 0, 0> { // expected-note {{passing argument to parameter here}} +public: + typedef VT value_type; + Matrix(const unsigned int nRows, const unsigned int nColumns, const value_type* data = nullptr); + + Matrix(const std::initializer_list<value_type>& list) = delete; // expected-note {{'Matrix' has been explicitly marked deleted here}} + +}; + +void getLaplacianClosedForm() +{ + Matrix<double> winI(0, 3); + RGBFValue* inputPreL; + winI = { inputPreL->at() }; // expected-error {{call to deleted constructor of 'cva::Matrix<double, 0, 0> &&'}} +} + +} diff --git a/test/SemaCXX/cxx11-crashes.cpp b/test/SemaCXX/cxx11-crashes.cpp index bd51af1..97c9594 100644 --- a/test/SemaCXX/cxx11-crashes.cpp +++ b/test/SemaCXX/cxx11-crashes.cpp @@ -74,3 +74,20 @@ namespace b6981007 { } } } + +namespace incorrect_auto_type_deduction_for_typo { +struct S { + template <typename T> S(T t) { + (void)sizeof(t); + (void)new auto(t); + } +}; + +void Foo(S); + +void test(int some_number) { // expected-note {{'some_number' declared here}} + auto x = sum_number; // expected-error {{use of undeclared identifier 'sum_number'; did you mean 'some_number'?}} + auto lambda = [x] {}; + Foo(lambda); +} +} diff --git a/test/SemaCXX/cxx11-gnu-attrs.cpp b/test/SemaCXX/cxx11-gnu-attrs.cpp index 9f18224..ac9cc55 100644 --- a/test/SemaCXX/cxx11-gnu-attrs.cpp +++ b/test/SemaCXX/cxx11-gnu-attrs.cpp @@ -15,6 +15,9 @@ void aliasb [[gnu::alias("_Z6alias1v")]] (); void alias1() {} void aliasa [[gnu::alias("_Z6alias1v")]] (); +extern struct PR22493Ty { +} PR22493 [[gnu::alias("_ZN7pcrecpp2RE6no_argE")]]; + [[gnu::aligned(8)]] int aligned; void aligned_fn [[gnu::aligned(32)]] (); struct [[gnu::aligned(8)]] aligned_struct {}; diff --git a/test/SemaCXX/cxx1y-constexpr-not-const.cpp b/test/SemaCXX/cxx1y-constexpr-not-const.cpp index 071b39c..2352bb7 100644 --- a/test/SemaCXX/cxx1y-constexpr-not-const.cpp +++ b/test/SemaCXX/cxx1y-constexpr-not-const.cpp @@ -11,8 +11,6 @@ struct X { // expected-error@6 {{class member cannot be redeclared}} // expected-note@5 {{previous}} -// expected-error@6 {{non-constexpr declaration of 'f' follows constexpr declaration}} -// expected-note@5 {{previous}} #else // expected-warning@5 {{'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior}} #endif diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp index 50e0cf7..225d234 100644 --- a/test/SemaCXX/cxx1y-deduced-return-type.cpp +++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp @@ -21,8 +21,8 @@ int conv1c = conv1.operator auto(); int conv1d = conv1.operator int(); // expected-error {{no member named 'operator int'}} struct Conv2 { - operator auto() { return 0; } // expected-note 2{{previous}} - operator auto() { return 0.; } // expected-error {{cannot be redeclared}} expected-error {{redefinition of 'operator auto'}} + operator auto() { return 0; } // expected-note {{previous}} + operator auto() { return 0.; } // expected-error {{cannot be redeclared}} expected-error {{cannot initialize return object of type 'auto' with an rvalue of type 'double'}} }; struct Conv3 { diff --git a/test/SemaCXX/cxx1y-generic-lambdas.cpp b/test/SemaCXX/cxx1y-generic-lambdas.cpp index 90ecf69..f4c67fb 100644 --- a/test/SemaCXX/cxx1y-generic-lambdas.cpp +++ b/test/SemaCXX/cxx1y-generic-lambdas.cpp @@ -899,8 +899,10 @@ struct X1 { int L2 = ([](auto i) { return i; })(2); void fooG(T i = ([] (auto i) { return i; })(2)) { } int BG : ([](auto i) { return i; })(3); //expected-error{{not an integral constant}}\ - //expected-note{{non-literal type}} - int arrG[([](auto i) { return i; })(3)]; //expected-error{{must have a constant size}} + //expected-note{{non-literal type}}\ + //expected-error{{inside of a constant expression}} + int arrG[([](auto i) { return i; })(3)]; //expected-error{{must have a constant size}} \ + //expected-error{{inside of a constant expression}} int (*fpG)(T) = [](auto i) { return i; }; void fooptrG(T (*fp)(char) = [](auto c) { return 0; }) { } template<class U = char> int fooG2(T (*fp)(U) = [](auto a) { return 0; }) { return 0; } diff --git a/test/SemaCXX/cxx1y-init-captures.cpp b/test/SemaCXX/cxx1y-init-captures.cpp index 64fe50a7..203e28d 100644 --- a/test/SemaCXX/cxx1y-init-captures.cpp +++ b/test/SemaCXX/cxx1y-init-captures.cpp @@ -166,4 +166,27 @@ int test(T t = T{}) { int run = test(); //expected-note {{instantiation}} -}
\ No newline at end of file +} + +namespace classification_of_captures_of_init_captures { + +template <typename T> +void f() { + [a = 24] () mutable { + [&a] { a = 3; }(); + }(); +} + +template <typename T> +void h() { + [a = 24] (auto param) mutable { + [&a] { a = 3; }(); + }(42); +} + +int run() { + f<int>(); + h<int>(); +} + +} diff --git a/test/SemaCXX/cxx1y-sized-deallocation.cpp b/test/SemaCXX/cxx1y-sized-deallocation.cpp index 81a8eeb..3ec65a6 100644 --- a/test/SemaCXX/cxx1y-sized-deallocation.cpp +++ b/test/SemaCXX/cxx1y-sized-deallocation.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -std=c++1y -verify %s -fsized-deallocation -fexceptions -fcxx-exceptions using size_t = decltype(sizeof(0)); +void operator delete(void *, size_t) noexcept; // expected-note {{'operator delete' declared here}} +void operator delete[](void *, size_t) noexcept; void f(void *p, void *q) { // OK, implicitly declared. diff --git a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp index 93a2095..9ff73da 100644 --- a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp +++ b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp @@ -58,13 +58,13 @@ namespace out_of_line { template<typename T, typename T0> static CONST T b = T(100); template<typename T> static CONST T b<T,int>; }; - template<typename T, typename T0> CONST T B4::a; // expected-error {{default initialization of an object of const type 'const int'}} expected-note {{add an explicit initializer to initialize 'a<int, char>'}} + template<typename T, typename T0> CONST T B4::a; // expected-error {{default initialization of an object of const type 'const int'}} template<typename T> CONST T B4::a<T,int>; template CONST int B4::a<int,char>; // expected-note {{in instantiation of}} template CONST int B4::a<int,int>; template<typename T, typename T0> CONST T B4::b; - template<typename T> CONST T B4::b<T,int>; // expected-error {{default initialization of an object of const type 'const int'}} expected-note {{add an explicit initializer to initialize 'b<int, int>'}} + template<typename T> CONST T B4::b<T,int>; // expected-error {{default initialization of an object of const type 'const int'}} template CONST int B4::b<int,char>; template CONST int B4::b<int,int>; // expected-note {{in instantiation of}} } diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp index 029e909..4227272 100644 --- a/test/SemaCXX/cxx98-compat.cpp +++ b/test/SemaCXX/cxx98-compat.cpp @@ -74,10 +74,10 @@ int InitList(int i = {}) { // expected-warning {{generalized initializer lists a InitListCtor ilc = { true, false }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}} const int &r = { 0 }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}} struct { int a; const int &r; } rr = { 0, {0} }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}} - return { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}} + return { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}} expected-warning {{scalar}} } struct DelayedDefaultArgumentParseInitList { - void f(int i = {1}) { // expected-warning {{generalized initializer lists are incompatible with C++98}} + void f(int i = {1}) { // expected-warning {{generalized initializer lists are incompatible with C++98}} expected-warning {{scalar}} } }; diff --git a/test/SemaCXX/decl-microsoft-call-conv.cpp b/test/SemaCXX/decl-microsoft-call-conv.cpp index a4b68cd..6c392ea 100644 --- a/test/SemaCXX/decl-microsoft-call-conv.cpp +++ b/test/SemaCXX/decl-microsoft-call-conv.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -verify %s -// RUN: %clang_cc1 -triple i686-pc-mingw32 -verify %s -// RUN: %clang_cc1 -triple i686-pc-mingw32 -fms-extensions -verify %s +// RUN: %clang_cc1 -std=c++14 -triple i686-pc-win32 -fms-extensions -verify %s +// RUN: %clang_cc1 -std=c++14 -triple i686-pc-mingw32 -verify %s +// RUN: %clang_cc1 -std=c++14 -triple i686-pc-mingw32 -fms-extensions -verify %s typedef void void_fun_t(); typedef void __cdecl cdecl_fun_t(); @@ -242,3 +242,19 @@ namespace test8 { s.f(p); // expected-note {{in instantiation of member function 'test8::S<void *>::f' requested here}} } } + +namespace test9 { + // Used to fail when we forgot to make lambda call operators use __thiscall. + template <typename F> + decltype(auto) deduce(F f) { + return &decltype(f)::operator(); + } + template <typename C, typename R, typename A> + decltype(auto) signaturehelper(R (C::*f)(A) const) { + return R(); + } + void f() { + auto l = [](int x) { return x * 2; }; + decltype(signaturehelper(deduce(l))) p; + } +} diff --git a/test/SemaCXX/declspec-thread.cpp b/test/SemaCXX/declspec-thread.cpp index 0ace9a6..2b931bb 100644 --- a/test/SemaCXX/declspec-thread.cpp +++ b/test/SemaCXX/declspec-thread.cpp @@ -1,17 +1,30 @@ -// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -fms-extensions -verify %s +// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -fms-extensions -fms-compatibility-version=18.00 -verify %s +// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -fms-extensions -fms-compatibility-version=19.00 -verify %s __thread __declspec(thread) int a; // expected-error {{already has a thread-local storage specifier}} __declspec(thread) __thread int b; // expected-error {{already has a thread-local storage specifier}} __declspec(thread) int c(); // expected-warning {{only applies to variables}} __declspec(thread) int d; int foo(); +#if _MSC_VER >= 1900 +__declspec(thread) int e = foo(); +#else __declspec(thread) int e = foo(); // expected-error {{must be a constant expression}} expected-note {{thread_local}} +#endif struct HasCtor { HasCtor(); int x; }; +#if _MSC_VER >= 1900 +__declspec(thread) HasCtor f; +#else __declspec(thread) HasCtor f; // expected-error {{must be a constant expression}} expected-note {{thread_local}} +#endif struct HasDtor { ~HasDtor(); int x; }; -__declspec(thread) HasDtor g; // expected-error {{non-trivial destruction}} expected-note {{thread_local}} +#if _MSC_VER >= 1900 +__declspec(thread) HasDtor g; +#else +__declspec(thread) HasCtor g; // expected-error {{must be a constant expression}} expected-note {{thread_local}} +#endif struct HasDefaultedDefaultCtor { HasDefaultedDefaultCtor() = default; diff --git a/test/SemaCXX/default-assignment-operator.cpp b/test/SemaCXX/default-assignment-operator.cpp index 7ef6f77..f202b61 100644 --- a/test/SemaCXX/default-assignment-operator.cpp +++ b/test/SemaCXX/default-assignment-operator.cpp @@ -112,7 +112,7 @@ namespace MultiplePaths { struct X1 : public virtual X0 { }; - struct X2 : X0, X1 { }; + struct X2 : X0, X1 { }; // expected-warning{{direct base 'MultiplePaths::X0' is inaccessible due to ambiguity:\n struct MultiplePaths::X2 -> struct MultiplePaths::X0\n struct MultiplePaths::X2 -> struct MultiplePaths::X1 -> struct MultiplePaths::X0}} void f(X2 x2) { x2 = x2; } } diff --git a/test/SemaCXX/delete-mismatch.h b/test/SemaCXX/delete-mismatch.h new file mode 100644 index 0000000..84fcd61 --- /dev/null +++ b/test/SemaCXX/delete-mismatch.h @@ -0,0 +1,15 @@ +// Header for PCH test delete.cpp +namespace pch_test { +struct X { + int *a; + X(); + X(int); + X(bool) + : a(new int[1]) { } // expected-note{{allocated with 'new[]' here}} + ~X() + { + delete a; // expected-warning{{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]" + } +}; +} diff --git a/test/SemaCXX/delete.cpp b/test/SemaCXX/delete.cpp index 5824fac..f94a863 100644 --- a/test/SemaCXX/delete.cpp +++ b/test/SemaCXX/delete.cpp @@ -1,9 +1,130 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: cp %s %t -// RUN: %clang_cc1 -fixit -x c++ %t -// RUN: %clang_cc1 -E -o - %t | FileCheck %s +// Test without PCH +// RUN: %clang_cc1 -fsyntax-only -include %S/delete-mismatch.h -fdiagnostics-parseable-fixits -std=c++11 %s 2>&1 | FileCheck %s + +// Test with PCH +// RUN: %clang_cc1 -x c++-header -std=c++11 -emit-pch -o %t %S/delete-mismatch.h +// RUN: %clang_cc1 -std=c++11 -include-pch %t -DWITH_PCH -fsyntax-only -verify %s -ast-dump void f(int a[10][20]) { - // CHECK: delete[] a; delete a; // expected-warning {{'delete' applied to a pointer-to-array type}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]" +} +namespace MemberCheck { +struct S { + int *a = new int[5]; // expected-note4 {{allocated with 'new[]' here}} + int *b; + int *c; + static int *d; + S(); + S(int); + ~S() { + delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} + delete b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} + delete[] c; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} + } + void f(); +}; + +void S::f() +{ + delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} + delete b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} +} + +S::S() +: b(new int[1]), c(new int) {} // expected-note3 {{allocated with 'new[]' here}} +// expected-note@-1 {{allocated with 'new' here}} + +S::S(int i) +: b(new int[i]), c(new int) {} // expected-note3 {{allocated with 'new[]' here}} +// expected-note@-1 {{allocated with 'new' here}} + +struct S2 : S { + ~S2() { + delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} + } +}; +int *S::d = new int[42]; // expected-note {{allocated with 'new[]' here}} +void f(S *s) { + int *a = new int[1]; // expected-note {{allocated with 'new[]' here}} + delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} + delete s->a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} + delete s->b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} + delete s->c; + delete s->d; + delete S::d; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} +} + +// At least one constructor initializes field with matching form of 'new'. +struct MatchingNewIsOK { + int *p; + bool is_array_; + MatchingNewIsOK() : p{new int}, is_array_(false) {} + explicit MatchingNewIsOK(unsigned c) : p{new int[c]}, is_array_(true) {} + ~MatchingNewIsOK() { + if (is_array_) + delete[] p; + else + delete p; + } +}; + +// At least one constructor's body is missing; no proof of mismatch. +struct CantProve_MissingCtorDefinition { + int *p; + CantProve_MissingCtorDefinition(); + CantProve_MissingCtorDefinition(int); + ~CantProve_MissingCtorDefinition(); +}; + +CantProve_MissingCtorDefinition::CantProve_MissingCtorDefinition() + : p(new int) +{ } + +CantProve_MissingCtorDefinition::~CantProve_MissingCtorDefinition() +{ + delete[] p; +} + +struct base {}; +struct derived : base {}; +struct InitList { + base *p, *p2 = nullptr, *p3{nullptr}, *p4; + InitList(unsigned c) : p(new derived[c]), p4(nullptr) {} // expected-note {{allocated with 'new[]' here}} + InitList(unsigned c, unsigned) : p{new derived[c]}, p4{nullptr} {} // expected-note {{allocated with 'new[]' here}} + ~InitList() { + delete p; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} + delete [] p; + delete p2; + delete [] p3; + delete p4; + } +}; +} + +namespace NonMemberCheck { +#define DELETE_ARRAY(x) delete[] (x) +#define DELETE(x) delete (x) +void f() { + int *a = new int(5); // expected-note2 {{allocated with 'new' here}} + delete[] a; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} + int *b = new int; + delete b; + int *c{new int}; // expected-note {{allocated with 'new' here}} + int *d{new int[1]}; // expected-note2 {{allocated with 'new[]' here}} + delete [ ] c; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:17}:"" + delete d; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]" + DELETE_ARRAY(a); // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} + DELETE(d); // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} +} } +#ifndef WITH_PCH +pch_test::X::X() + : a(new int[1]) // expected-note{{allocated with 'new[]' here}} +{ } +pch_test::X::X(int i) + : a(new int[i]) // expected-note{{allocated with 'new[]' here}} +{ } +#endif diff --git a/test/SemaCXX/deleted-function.cpp b/test/SemaCXX/deleted-function.cpp index d7ef9b2..bd6fc09 100644 --- a/test/SemaCXX/deleted-function.cpp +++ b/test/SemaCXX/deleted-function.cpp @@ -65,3 +65,31 @@ template void test3<int>(); void test4() {} // expected-note {{previous definition is here}} void test4() = delete; // expected-error {{redefinition of 'test4'}} + +struct DelCtor { // expected-note 4{{implicit}} + DelCtor(int) = delete; // expected-note 14{{deleted}} + // ensure the class is not an aggregate + DelCtor(int, int, int, int); +}; +DelCtor dc1 = 0; // expected-error {{deleted}} +DelCtor dc2(0); // expected-error {{deleted}} +DelCtor dc3 = {0}; // expected-error {{deleted}} +DelCtor dc4{0}; // expected-error {{deleted}} +DelCtor dc5 = (DelCtor)0; // expected-error {{deleted}} +DelCtor dc6 = DelCtor(0); // expected-error {{deleted}} +DelCtor dc7 = DelCtor{0}; // expected-error {{deleted}} +DelCtor *dc8 = new DelCtor(0); // expected-error {{deleted}} +DelCtor *dc9 = new DelCtor{0}; // expected-error {{deleted}} +DelCtor dc10[] = {0}; // expected-error {{deleted}} +int use_dc(DelCtor); // expected-note 2{{here}} +int dc11 = use_dc(0); // expected-error {{deleted}} +int dc12 = use_dc({0}); // expected-error {{deleted}} +int use_dcr(const DelCtor &); // expected-note {{here}} +int dc13 = use_dcr(0); // expected-error {{deleted}} +int dc14 = use_dcr({0}); // expected-error {{deleted}} + +struct DelCtorTemplate { + template<typename T> DelCtorTemplate(T) = delete; // expected-note {{deleted}} +}; +int use_dct(const DelCtorTemplate &); +int dc15 = use_dct(0); // expected-error {{deleted}} diff --git a/test/SemaCXX/derived-to-base-ambig.cpp b/test/SemaCXX/derived-to-base-ambig.cpp index 129ec79..93bd361 100644 --- a/test/SemaCXX/derived-to-base-ambig.cpp +++ b/test/SemaCXX/derived-to-base-ambig.cpp @@ -14,8 +14,8 @@ class A2 : public Object2 { }; class B2 : public virtual A2 { }; class C2 : virtual public A2 { }; class D2 : public B2, public C2 { }; -class E2 : public D2, public C2, public virtual A2 { }; -class F2 : public E2, public A2 { }; +class E2 : public D2, public C2, public virtual A2 { }; // expected-warning{{direct base 'C2' is inaccessible due to ambiguity:\n class E2 -> class D2 -> class C2\n class E2 -> class C2}} +class F2 : public E2, public A2 { }; // expected-warning{{direct base 'A2' is inaccessible due to ambiguity:\n class F2 -> class E2 -> class D2 -> class B2 -> class A2\n class F2 -> class A2}} void g(E2* e2, F2* f2) { Object2* o2; diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp index 5305ff5..60cb0ef 100644 --- a/test/SemaCXX/destructor.cpp +++ b/test/SemaCXX/destructor.cpp @@ -173,6 +173,12 @@ protected: ~S7(); }; +struct S8 {} s8; + +UnknownType S8::~S8() { // expected-error {{unknown type name 'UnknownType'}} + s8.~S8(); +} + template<class T> class TS : public B { virtual void m(); }; @@ -386,3 +392,14 @@ struct S { volatile ~S() { } // expected-error{{destructor cannot have a return type}} }; } + +namespace PR22668 { +struct S { +}; +void f(S s) { + (s.~S)(); +} +void g(S s) { + (s.~S); // expected-error{{reference to destructor must be called}} +} +} diff --git a/test/SemaCXX/devirtualize-vtable-marking.cpp b/test/SemaCXX/devirtualize-vtable-marking.cpp index fc3e8ce..1b32182 100644 --- a/test/SemaCXX/devirtualize-vtable-marking.cpp +++ b/test/SemaCXX/devirtualize-vtable-marking.cpp @@ -1,29 +1,32 @@ // RUN: %clang_cc1 -verify -std=c++11 %s - +// expected-no-diagnostics template <typename T> struct OwnPtr { T *p; ~OwnPtr() { - // expected-error@+1 {{invalid application of 'sizeof'}} static_assert(sizeof(T) > 0, "incomplete T"); delete p; } }; namespace use_vtable_for_vcall { -struct Incomplete; // expected-note {{forward declaration}} +struct Incomplete; struct A { virtual ~A() {} virtual void m() {} }; -struct B : A { // expected-note {{in instantiation}} +struct B : A { B(); virtual void m() { } virtual void m2() { static_cast<A *>(this)->m(); } OwnPtr<Incomplete> m_sqlError; }; -B *f() { - return new B(); +void f() { + // Since B's constructor is declared out of line, nothing in this file + // references a vtable, so the destructor doesn't get built. + A *b = new B(); + b->m(); + delete b; } } diff --git a/test/SemaCXX/dllexport-pr22591.cpp b/test/SemaCXX/dllexport-pr22591.cpp new file mode 100644 index 0000000..42c6155 --- /dev/null +++ b/test/SemaCXX/dllexport-pr22591.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple i686-windows-gnu -fms-extensions -verify -std=c++03 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -fms-extensions -verify -std=c++11 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -fms-extensions -verify -std=c++03 -DERROR %s +// RUN: %clang_cc1 -triple i686-windows-msvc -fms-extensions -verify -std=c++11 %s + +#ifndef ERROR +// expected-no-diagnostics +#endif + +struct NonCopyable { +private: +#ifdef ERROR + // expected-note@+2{{declared private here}} +#endif + NonCopyable(); +}; + +#ifdef ERROR +// expected-error@+4{{field of type 'NonCopyable' has private default constructor}} +// expected-note@+3{{implicit default constructor for 'S' first required here}} +// expected-note@+2{{due to 'S' being dllexported; try compiling in C++11 mode}} +#endif +struct __declspec(dllexport) S { + NonCopyable member; +}; diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp index 5d002ac..e419525 100644 --- a/test/SemaCXX/dllexport.cpp +++ b/test/SemaCXX/dllexport.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -verify -std=c++11 -Wunsupported-dll-base-class-template -DMS %s -// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s -// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -verify -std=c++1y -Wunsupported-dll-base-class-template %s -// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 -Wunsupported-dll-base-class-template %s +// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DMS %s +// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s +// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template %s +// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template %s // Helper structs to make templates more expressive. struct ImplicitInst_Exported {}; @@ -353,10 +353,10 @@ ImplicitlyInstantiatedExportedTemplate<IncompleteType> implicitlyInstantiatedExp // Don't instantiate class members of templates with explicit instantiation declarations, even if they are exported. struct IncompleteType2; -template <typename T> struct __declspec(dllexport) ExportedTemplateWithExplicitInstantiationDecl { +template <typename T> struct __declspec(dllexport) ExportedTemplateWithExplicitInstantiationDecl { // expected-note{{attribute is here}} int f() { return sizeof(T); } // no-error }; -extern template struct ExportedTemplateWithExplicitInstantiationDecl<IncompleteType2>; +extern template struct ExportedTemplateWithExplicitInstantiationDecl<IncompleteType2>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}} // Instantiate class members for explicitly instantiated exported templates. struct IncompleteType3; // expected-note{{forward declaration of 'IncompleteType3'}} @@ -386,7 +386,18 @@ template <typename T> struct __declspec(dllexport) ExportedBaseClassTemplateOfEx }; struct __declspec(dllexport) ExportedBaseClass2 : public ExportedBaseClassTemplateOfExportedClass<IncompleteType5> {}; +// Warn about explicit instantiation declarations of dllexport classes. +template <typename T> struct ExplicitInstantiationDeclTemplate {}; +extern template struct __declspec(dllexport) ExplicitInstantiationDeclTemplate<int>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}} expected-note{{attribute is here}} +template <typename T> struct __declspec(dllexport) ExplicitInstantiationDeclExportedTemplate {}; // expected-note{{attribute is here}} +extern template struct ExplicitInstantiationDeclExportedTemplate<int>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}} + +namespace { struct InternalLinkageType {}; } +struct __declspec(dllexport) PR23308 { + void f(InternalLinkageType*); +}; +void PR23308::f(InternalLinkageType*) {} // No error; we don't try to export f because it has internal linkage. //===----------------------------------------------------------------------===// // Classes with template base classes diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp index eb6a554..6052ea1 100644 --- a/test/SemaCXX/dllimport.cpp +++ b/test/SemaCXX/dllimport.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -verify -std=c++11 -Wunsupported-dll-base-class-template -DMS %s -// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s -// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -verify -std=c++1y -Wunsupported-dll-base-class-template -DGNU %s -// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %s +// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DMS %s +// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s +// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DGNU %s +// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %s // Helper structs to make templates more expressive. struct ImplicitInst_Imported {}; diff --git a/test/SemaCXX/empty-class-layout.cpp b/test/SemaCXX/empty-class-layout.cpp index 3cfc491..e802a0c 100644 --- a/test/SemaCXX/empty-class-layout.cpp +++ b/test/SemaCXX/empty-class-layout.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify +// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -Wno-inaccessible-base // expected-no-diagnostics #define SA(n, p) int a##n[(p) ? 1 : -1] diff --git a/test/SemaCXX/enum-bitfield.cpp b/test/SemaCXX/enum-bitfield.cpp index ec849b7..676ae44 100644 --- a/test/SemaCXX/enum-bitfield.cpp +++ b/test/SemaCXX/enum-bitfield.cpp @@ -28,3 +28,11 @@ struct D { A::B : C; }; } + +enum WithUnderlying : unsigned { wu_value }; +struct WithUnderlyingBitfield { + WithUnderlying wu : 3; +} wu = { wu_value }; +int want_unsigned(unsigned); +int want_unsigned(int) = delete; +int check_enum_bitfield_promotes_correctly = want_unsigned(wu.wu); diff --git a/test/SemaCXX/err_reference_bind_drops_quals.cpp b/test/SemaCXX/err_reference_bind_drops_quals.cpp new file mode 100644 index 0000000..afdd832 --- /dev/null +++ b/test/SemaCXX/err_reference_bind_drops_quals.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#define restrict __restrict__ +typedef int* ptr; +void test1(ptr p, const ptr cp, restrict ptr rp, const restrict ptr crp, + volatile ptr vp, const volatile ptr cvp, restrict volatile ptr rvp, + const restrict volatile ptr crvp) { + ptr& p1 = p; + ptr& p2 = cp; // expected-error {{drops 'const' qualifier}} + ptr& p3 = rp; // expected-error {{drops 'restrict' qualifier}} + ptr& p4 = crp; // expected-error {{drops 'const' and 'restrict' qualifiers}} + ptr& p5 = vp; // expected-error {{drops 'volatile' qualifier}} + ptr& p6 = cvp; // expected-error {{drops 'const' and 'volatile' qualifiers}} + ptr& p7 = rvp; // expected-error {{drops 'restrict' and 'volatile' qualifiers}} + ptr& p8 = crvp; // expected-error {{drops 'const', 'restrict', and 'volatile' qualifiers}} + + const ptr& cp1 = p; + const ptr& cp2 = cp; + const ptr& cp3 = rp; // expected-error {{drops 'restrict' qualifier}} + const ptr& cp4 = crp; // expected-error {{drops 'restrict' qualifier}} + const ptr& cp5 = vp; // expected-error {{drops 'volatile' qualifier}} + const ptr& cp6 = cvp; // expected-error {{drops 'volatile' qualifier}} + const ptr& cp7 = rvp; // expected-error {{drops 'restrict' and 'volatile' qualifiers}} + const ptr& cp8 = crvp; // expected-error {{drops 'restrict' and 'volatile' qualifiers}} + + const volatile ptr& cvp1 = p; + const volatile ptr& cvp2 = cp; + const volatile ptr& cvp3 = rp; // expected-error {{drops 'restrict' qualifier}} + const volatile ptr& cvp4 = crp; // expected-error {{drops 'restrict' qualifier}} + const volatile ptr& cvp5 = vp; + const volatile ptr& cvp6 = cvp; + const volatile ptr& cvp7 = rvp; // expected-error {{drops 'restrict' qualifier}} + const volatile ptr& cvp8 = crvp; // expected-error {{drops 'restrict' qualifier}} + + const restrict volatile ptr& crvp1 = p; + const restrict volatile ptr& crvp2 = cp; + const restrict volatile ptr& crvp3 = rp; + const restrict volatile ptr& crvp4 = crp; + const restrict volatile ptr& crvp5 = vp; + const restrict volatile ptr& crvp6 = cvp; + const restrict volatile ptr& crvp7 = rvp; + const restrict volatile ptr& crvp8 = crvp; +} diff --git a/test/SemaCXX/err_typecheck_assign_const.cpp b/test/SemaCXX/err_typecheck_assign_const.cpp new file mode 100644 index 0000000..376b6e6 --- /dev/null +++ b/test/SemaCXX/err_typecheck_assign_const.cpp @@ -0,0 +1,124 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +const int global = 5; // expected-note{{variable 'global' declared const here}} +void test1() { + global = 2; // expected-error{{cannot assign to variable 'global' with const-qualified type 'const int'}} +} + +void test2 () { + const int local = 5; // expected-note{{variable 'local' declared const here}} + local = 0; // expected-error{{cannot assign to variable 'local' with const-qualified type 'const int'}} +} + +void test2 (const int parameter) { // expected-note{{variable 'parameter' declared const here}} + parameter = 2; // expected-error{{cannot assign to variable 'parameter' with const-qualified type 'const int'}} +} + +class test3 { + int field; + const int const_field = 1; // expected-note 2{{non-static data member 'const_field' declared const here}} + static const int static_const_field = 1; // expected-note 2{{variable 'static_const_field' declared const here}} + void test() { + const_field = 4; // expected-error{{cannot assign to non-static data member 'const_field' with const-qualified type 'const int'}} + static_const_field = 4; // expected-error{{cannot assign to variable 'static_const_field' with const-qualified type 'const int'}} + } + void test_const() const { // expected-note 2{{member function 'test3::test_const' is declared const here}} + field = 4; // expected-error{{cannot assign to non-static data member within const member function 'test_const'}} + const_field = 4 ; // expected-error{{cannot assign to non-static data member 'const_field' with const-qualified type 'const int'}} + static_const_field = 4; // expected-error{{cannot assign to variable 'static_const_field' with const-qualified type 'const int'}} + } +}; + +const int &return_const_ref(); // expected-note{{function 'return_const_ref' which returns const-qualified type 'const int &' declared here}} + +void test4() { + return_const_ref() = 10; // expected-error{{cannot assign to return value because function 'return_const_ref' returns a const value}} +} + +struct S5 { + int field; + const int const_field = 4; // expected-note {{non-static data member 'const_field' declared const here}} +}; + +void test5() { + S5 s5; + s5.field = 5; + s5.const_field = 5; // expected-error{{cannot assign to non-static data member 'const_field' with const-qualified type 'const int'}} +} + +struct U1 { + int a = 5; +}; + +struct U2 { + U1 u1; +}; + +struct U3 { + const U2 u2 = U2(); // expected-note{{non-static data member 'u2' declared const here}} +}; + +struct U4 { + U3 u3; +}; + +void test6() { + U4 u4; + u4.u3.u2.u1.a = 5; // expected-error{{cannot assign to non-static data member 'u2' with const-qualified type 'const U2'}} +} + +struct A { + int z; +}; +struct B { + A a; +}; +struct C { + B b; + C(); +}; +const C &getc(); // expected-note{{function 'getc' which returns const-qualified type 'const C &' declared here}} +void test7() { + const C c; // expected-note{{variable 'c' declared const here}} + c.b.a.z = 5; // expected-error{{cannot assign to variable 'c' with const-qualified type 'const C'}} + + getc().b.a.z = 5; // expected-error{{cannot assign to return value because function 'getc' returns a const value}} +} + +struct D { const int n; }; // expected-note 2{{non-static data member 'n' declared const here}} +struct E { D *const d = 0; }; +void test8() { + extern D *const d; + d->n = 0; // expected-error{{cannot assign to non-static data member 'n' with const-qualified type 'const int'}} + + E e; + e.d->n = 0; // expected-error{{cannot assign to non-static data member 'n' with const-qualified type 'const int'}} +} + +struct F { int n; }; +struct G { const F *f; }; // expected-note{{non-static data member 'f' declared const here}} +void test10() { + const F *f; // expected-note{{variable 'f' declared const here}} + f->n = 0; // expected-error{{cannot assign to variable 'f' with const-qualified type 'const F *'}} + + G g; + g.f->n = 0; // expected-error{{cannot assign to non-static data member 'f' with const-qualified type 'const F *'}} +} + +void test11( + const int x, // expected-note{{variable 'x' declared const here}} + const int& y // expected-note{{variable 'y' declared const here}} + ) { + x = 5; // expected-error{{cannot assign to variable 'x' with const-qualified type 'const int'}} + y = 5; // expected-error{{cannot assign to variable 'y' with const-qualified type 'const int &'}} +} + +struct H { + const int a = 0; // expected-note{{non-static data member 'a' declared const here}} + const int &b = a; // expected-note{{non-static data member 'b' declared const here}} +}; + +void test12(H h) { + h.a = 1; // expected-error {{cannot assign to non-static data member 'a' with const-qualified type 'const int'}} + h.b = 2; // expected-error {{cannot assign to non-static data member 'b' with const-qualified type 'const int &'}} +} diff --git a/test/SemaCXX/err_typecheck_assign_const_filecheck.cpp b/test/SemaCXX/err_typecheck_assign_const_filecheck.cpp new file mode 100644 index 0000000..0d29b1e --- /dev/null +++ b/test/SemaCXX/err_typecheck_assign_const_filecheck.cpp @@ -0,0 +1,252 @@ +// RUN: not %clang_cc1 -fsyntax-only -std=c++11 %s 2>&1 | FileCheck %s + +struct E { + int num; + const int Cnum = 0; + mutable int Mnum; + static int Snum; + const static int CSnum; +}; + +struct D { + E e; + const E Ce; + mutable E Me; + static E Se; + const static E CSe; + E &getE() const; + const E &getCE() const; +}; + +struct C { + D d; + const D Cd; + mutable D Md; + static D Sd; + const static D CSd; + D &getD() const; + const D &getCD() const; +}; + +struct B { + C c; + const C Cc; + mutable C Mc; + static C Sc; + const static C CSc; + C &getC() const; + static C &getSC(); + const C &getCC() const; + static const C &getSCC(); +}; + +struct A { + B b; + const B Cb; + mutable B Mb; + static B Sb; + const static B CSb; + B &getB() const; + static B &getSB(); + const B &getCB() const; + static const B &getSCB(); +}; + +A& getA(); + +// Valid assignment +void test1(A a, const A Ca) { + a.b.c.d.e.num = 5; + a.b.c.d.e.Mnum = 5; + Ca.b.c.d.e.Mnum = 5; + a.b.c.d.e.Snum = 5; + Ca.b.c.d.e.Snum = 5; + Ca.b.c.Md.e.num = 5; + Ca.Mb.Cc.d.e.Mnum = 5; + Ca.Mb.getC().d.e.num = 5; + Ca.getSB().c.d.e.num = 5; + a.getSCB().c.d.Me.num = 5; + Ca.Cb.Cc.Cd.Ce.Snum = 5; + // CHECK-NOT: error: + // CHECK-NOT: note: +} + +// One note +void test2(A a, const A Ca) { + Ca.b.c.d.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ca' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ca' + // CHECK-NOT: note: + + a.Cb.c.d.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cb' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cb' + // CHECK-NOT: note: + + a.b.c.Cd.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + + a.b.c.d.e.CSnum = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'CSnum' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'CSnum' + // CHECK-NOT: note: + + a.b.c.d.e.Cnum = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cnum' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cnum' + // CHECK-NOT: note: + + a.getCB().c.d.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'getCB' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'getCB' + // CHECK-NOT: note: + + a.getSCB().c.d.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'getSCB' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'getSCB' + // CHECK-NOT: note: +} + +// Two notes +void test3(A a, const A Ca) { + + a.getSCB().Cc.d.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cc' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cc' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'getSCB' + // CHECK-NOT: note: + + Ca.b.c.Cd.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ca' + // CHECK-NOT: note: + + a.getCB().c.Cd.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'getCB' + // CHECK-NOT: note: + + a.b.getCC().d.e.Cnum = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cnum' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cnum' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'getCC' + // CHECK-NOT: note: + + a.b.c.Cd.Ce.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + + a.b.CSc.Cd.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'CSc' + // CHECK-NOT: note: + + a.CSb.c.Cd.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'CSb' + // CHECK-NOT: note: +} + +// No errors +void test4(const A Ca) { + // Mutable cases + Ca.Mb.c.d.e.num = 5; + Ca.CSb.Mc.d.e.num = 5; + Ca.getCB().Mc.d.e.num = 5; + Ca.getSCB().Mc.d.e.num = 5; + + // Returning non-const reference + Ca.getB().c.d.e.num = 5; + Ca.CSb.getC().d.e.num = 5; + Ca.getCB().getC().d.e.num = 5; + Ca.getSCB().getC().d.e.num = 5; + + // Returning non-const reference + Ca.getSB().c.d.e.num = 5; + Ca.CSb.getSC().d.e.num = 5; + Ca.getCB().getSC().d.e.num = 5; + Ca.getSCB().getSC().d.e.num = 5; + + // Static member + Ca.Sb.c.d.e.num = 5; + Ca.CSb.Sc.d.e.num = 5; + Ca.getCB().Sc.d.e.num = 5; + Ca.getSCB().Sc.d.e.num = 5; + + // CHECK-NOT: error: + // CHECK-NOT: note: +} + +// Only display notes for relavent cases. +void test5(const A Ca) { + Ca.Mb.c.d.Ce.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ce' + // CHECK-NOT: note: + + Ca.getB().c.d.Ce.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ce' + // CHECK-NOT: note: + + Ca.getSB().c.d.Ce.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ce' + // CHECK-NOT: note: + + Ca.Sb.c.d.Ce.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ce' + // CHECK-NOT: note: +} diff --git a/test/SemaCXX/exceptions-seh.cpp b/test/SemaCXX/exceptions-seh.cpp new file mode 100644 index 0000000..7375ec9 --- /dev/null +++ b/test/SemaCXX/exceptions-seh.cpp @@ -0,0 +1,115 @@ +// RUN: %clang_cc1 -std=c++03 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s +// RUN: %clang_cc1 -std=c++11 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s + +// Basic usage should work. +int safe_div(int n, int d) { + int r; + __try { + r = n / d; + } __except(_exception_code() == 0xC0000094) { + r = 0; + } + return r; +} + +void might_crash(); + +// Diagnose obvious builtin mis-usage. +void bad_builtin_scope() { + __try { + might_crash(); + } __except(1) { + } + _exception_code(); // expected-error {{'_exception_code' only allowed in __except block or filter expression}} + _exception_info(); // expected-error {{'_exception_info' only allowed in __except filter expression}} +} + +// Diagnose obvious builtin misusage in a template. +template <void FN()> +void bad_builtin_scope_template() { + __try { + FN(); + } __except(1) { + } + _exception_code(); // expected-error {{'_exception_code' only allowed in __except block or filter expression}} + _exception_info(); // expected-error {{'_exception_info' only allowed in __except filter expression}} +} +void instantiate_bad_scope_tmpl() { + bad_builtin_scope_template<might_crash>(); +} + +#if __cplusplus < 201103L +// FIXME: Diagnose this case. For now we produce undef in codegen. +template <typename T, T FN()> +T func_template() { + return FN(); +} +void inject_builtins() { + func_template<void *, __exception_info>(); + func_template<unsigned long, __exception_code>(); +} +#endif + +void use_seh_after_cxx() { + try { // expected-note {{conflicting 'try' here}} + might_crash(); + } catch (int) { + } + __try { // expected-error {{cannot use C++ 'try' in the same function as SEH '__try'}} + might_crash(); + } __except(1) { + } +} + +void use_cxx_after_seh() { + __try { // expected-note {{conflicting '__try' here}} + might_crash(); + } __except(1) { + } + try { // expected-error {{cannot use C++ 'try' in the same function as SEH '__try'}} + might_crash(); + } catch (int) { + } +} + +#if __cplusplus >= 201103L +void use_seh_in_lambda() { + ([]() { + __try { + might_crash(); + } __except(1) { + } + })(); + try { + might_crash(); + } catch (int) { + } +} +#endif + +void use_seh_in_block() { + void (^b)() = ^{ + __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}} + might_crash(); + } __except(1) { + } + }; + try { + b(); + } catch (int) { + } +} + +void (^use_seh_in_global_block)() = ^{ + __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}} + might_crash(); + } __except(1) { + } +}; + +void (^use_cxx_in_global_block)() = ^{ + try { + might_crash(); + } catch(int) { + } +}; diff --git a/test/SemaCXX/exceptions.cpp b/test/SemaCXX/exceptions.cpp index 9646a9c..9802a1a 100644 --- a/test/SemaCXX/exceptions.cpp +++ b/test/SemaCXX/exceptions.cpp @@ -145,3 +145,111 @@ namespace Decay { } void rval_ref() throw (int &&); // expected-error {{rvalue reference type 'int &&' is not allowed in exception specification}} expected-warning {{C++11}} + +namespace HandlerInversion { +struct B {}; +struct D : B {}; +struct D2 : D {}; + +void f1() { + try { + } catch (B &b) { // expected-note {{for type 'HandlerInversion::B &'}} + } catch (D &d) { // expected-warning {{exception of type 'HandlerInversion::D &' will be caught by earlier handler}} + } +} + +void f2() { + try { + } catch (B *b) { // expected-note {{for type 'HandlerInversion::B *'}} + } catch (D *d) { // expected-warning {{exception of type 'HandlerInversion::D *' will be caught by earlier handler}} + } +} + +void f3() { + try { + } catch (D &d) { // Ok + } catch (B &b) { + } +} + +void f4() { + try { + } catch (B &b) { // Ok + } +} + +void f5() { + try { + } catch (int) { + } catch (float) { + } +} + +void f6() { + try { + } catch (B &b) { // expected-note {{for type 'HandlerInversion::B &'}} + } catch (D2 &d) { // expected-warning {{exception of type 'HandlerInversion::D2 &' will be caught by earlier handler}} + } +} + +void f7() { + try { + } catch (B *b) { // Ok + } catch (D &d) { // Ok + } + + try { + } catch (B b) { // Ok + } catch (D *d) { // Ok + } +} + +void f8() { + try { + } catch (const B &b) { // expected-note {{for type 'const HandlerInversion::B &'}} + } catch (D2 &d) { // expected-warning {{exception of type 'HandlerInversion::D2 &' will be caught by earlier handler}} + } + + try { + } catch (B &b) { // expected-note {{for type 'HandlerInversion::B &'}} + } catch (const D2 &d) { // expected-warning {{exception of type 'const HandlerInversion::D2 &' will be caught by earlier handler}} + } + + try { + } catch (B b) { // expected-note {{for type 'HandlerInversion::B'}} + } catch (D &d) { // expected-warning {{exception of type 'HandlerInversion::D &' will be caught by earlier handler}} + } +} +} + +namespace ConstVolatileThrow { +struct S { + S() {} // expected-note{{candidate constructor not viable}} + S(const S &s); // expected-note{{candidate constructor not viable}} +}; + +typedef const volatile S CVS; + +void f() { + throw CVS(); // expected-error{{no matching constructor for initialization}} +} +} + +namespace ConstVolatileCatch { +struct S { + S() {} + S(const volatile S &s); + +private: + S(const S &s); // expected-note {{declared private here}} +}; + +void f(); + +void g() { + try { + f(); + } catch (volatile S s) { // expected-error {{calling a private constructor}} + } +} +} diff --git a/test/SemaCXX/explicit.cpp b/test/SemaCXX/explicit.cpp index 155141c..a3902e5 100644 --- a/test/SemaCXX/explicit.cpp +++ b/test/SemaCXX/explicit.cpp @@ -56,7 +56,7 @@ namespace Conversion { void testExplicit() { // Taken from 12.3.2p2 - class X { X(); }; // expected-note+ {{candidate constructor}} + class X { X(); }; class Y { }; // expected-note+ {{candidate constructor (the implicit}} struct Z { @@ -89,14 +89,10 @@ namespace Conversion { const Y& y11{z}; // expected-error {{excess elements}} expected-note {{in initialization of temporary of type 'const Y'}} const int& y12{z}; - // X is not an aggregate, so constructors are considered. - // However, by 13.3.3.1/4, only standard conversion sequences and - // ellipsis conversion sequences are considered here, so this is not - // allowed. - // FIXME: It's not really clear that this is a sensible restriction for this - // case. g++ allows this, EDG does not. - const X x1{z}; // expected-error {{no matching constructor}} - const X& x2{z}; // expected-error {{no matching constructor}} + // X is not an aggregate, so constructors are considered, + // per 13.3.3.1/4 & DR1467. + const X x1{z}; + const X& x2{z}; } void testBool() { diff --git a/test/SemaCXX/for-range-examples.cpp b/test/SemaCXX/for-range-examples.cpp index d07331c..9359ae6 100644 --- a/test/SemaCXX/for-range-examples.cpp +++ b/test/SemaCXX/for-range-examples.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 namespace value_range_detail { template<typename T> @@ -226,7 +226,7 @@ namespace test7 { // we check the alignment attribute before we perform the auto // deduction. for (d alignas(1) : arr) {} // expected-error {{requires type for loop variable}} - for (e [[deprecated]] : arr) { e = 0; } // expected-warning {{deprecated}} expected-note {{here}} expected-error {{requires type for loop variable}} + for (e [[deprecated]] : arr) { e = 0; } // expected-warning{{use of the 'deprecated' attribute is a C++14 extension}} expected-warning {{deprecated}} expected-note {{here}} expected-error {{requires type for loop variable}} } } diff --git a/test/SemaCXX/format-strings-0x-nopedantic.cpp b/test/SemaCXX/format-strings-0x-nopedantic.cpp new file mode 100644 index 0000000..62e7ade --- /dev/null +++ b/test/SemaCXX/format-strings-0x-nopedantic.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wformat -std=c++11 %s +// expected-no-diagnostics +extern "C" { +extern int scanf(const char *restrict, ...); +extern int printf(const char *restrict, ...); +} + +void f(char *c) { + printf("%p", c); +} diff --git a/test/SemaCXX/format-strings-0x.cpp b/test/SemaCXX/format-strings-0x.cpp index 7e41c7f..ad57b77 100644 --- a/test/SemaCXX/format-strings-0x.cpp +++ b/test/SemaCXX/format-strings-0x.cpp @@ -8,6 +8,9 @@ extern int printf(const char *restrict, ...); void f(char **sp, float *fp) { scanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'char **'}} + printf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'char **'}} + scanf("%p", sp); // expected-warning{{format specifies type 'void **' but the argument has type 'char **'}} + printf("%a", 1.0); scanf("%afoobar", fp); printf(nullptr); diff --git a/test/SemaCXX/format-strings.cpp b/test/SemaCXX/format-strings.cpp index 4177570..fa7251d 100644 --- a/test/SemaCXX/format-strings.cpp +++ b/test/SemaCXX/format-strings.cpp @@ -133,3 +133,18 @@ namespace Templates { } } +namespace implicit_this_tests { +struct t { + void func1(const char *, ...) __attribute__((__format__(printf, 1, 2))); // expected-error {{format attribute cannot specify the implicit this argument as the format string}} + void (*func2)(const char *, ...) __attribute__((__format__(printf, 1, 2))); + static void (*func3)(const char *, ...) __attribute__((__format__(printf, 1, 2))); + static void func4(const char *, ...) __attribute__((__format__(printf, 1, 2))); +}; + +void f() { + t t1; + t1.func2("Hello %s"); // expected-warning {{more '%' conversions than data arguments}} + t::func3("Hello %s"); // expected-warning {{more '%' conversions than data arguments}} + t::func4("Hello %s"); // expected-warning {{more '%' conversions than data arguments}} +} +} diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp index 55aa069..a8e2043 100644 --- a/test/SemaCXX/friend.cpp +++ b/test/SemaCXX/friend.cpp @@ -349,3 +349,17 @@ void file_scope_friend() { (void)a.p; } } + +template<typename T> +struct X_pr6954 { + operator int(); + friend void f_pr6954(int x); +}; + +int array0_pr6954[sizeof(X_pr6954<int>)]; +int array1_pr6954[sizeof(X_pr6954<float>)]; + +void g_pr6954() { + f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}} +} + diff --git a/test/SemaCXX/function-type-qual.cpp b/test/SemaCXX/function-type-qual.cpp index 613ac9b..bb25c17 100644 --- a/test/SemaCXX/function-type-qual.cpp +++ b/test/SemaCXX/function-type-qual.cpp @@ -17,8 +17,8 @@ class C { x = 0; } - void m2() const { - x = 0; // expected-error {{read-only variable is not assignable}} + void m2() const { // expected-note {{member function 'C::m2' is declared const here}} + x = 0; // expected-error {{cannot assign to non-static data member within const member function 'm2'}} } int x; diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp index f5ca76c..9db95e8 100644 --- a/test/SemaCXX/functional-cast.cpp +++ b/test/SemaCXX/functional-cast.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s // REQUIRES: LP64 // ------------ not interpreted as C-style cast ------------ @@ -11,7 +11,7 @@ struct InitViaConstructor { InitViaConstructor(int i = 7); }; -struct NoValueInit { // expected-note 2 {{candidate constructor (the implicit copy constructor)}} +struct NoValueInit { // expected-note 2 {{candidate constructor (the implicit copy constructor)}} expected-note 2 {{candidate constructor (the implicit move constructor)}} NoValueInit(int i, int j); // expected-note 2 {{candidate constructor}} }; @@ -25,6 +25,7 @@ void test_cxx_function_cast_multi() { (void)NoValueInit(0, 0); (void)NoValueInit(0, 0, 0); // expected-error{{no matching constructor for initialization}} (void)int(1, 2); // expected-error{{excess elements in scalar initializer}} + (void)int({}, 2); // expected-error{{excess elements in scalar initializer}} } diff --git a/test/SemaCXX/generalized-deprecated.cpp b/test/SemaCXX/generalized-deprecated.cpp new file mode 100644 index 0000000..8fa20d0 --- /dev/null +++ b/test/SemaCXX/generalized-deprecated.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -fms-extensions -Wno-deprecated %s + +// NOTE: use -Wno-deprecated to avoid cluttering the output with deprecated +// warnings + +[[deprecated("1")]] int function_1(); +// expected-warning@-1 {{use of the 'deprecated' attribute is a C++14 extension}} + +[[gnu::deprecated("3")]] int function_3(); + +int __attribute__ (( deprecated("2") )) function_2(); + +__declspec(deprecated("4")) int function_4(); + diff --git a/test/SemaCXX/increment-decrement.cpp b/test/SemaCXX/increment-decrement.cpp index 11b7d1e..4f131d7 100644 --- a/test/SemaCXX/increment-decrement.cpp +++ b/test/SemaCXX/increment-decrement.cpp @@ -5,8 +5,8 @@ volatile int i; const int &inc = i++; const int &dec = i--; -const int &incfail = ++i; // expected-error {{drops qualifiers}} -const int &decfail = --i; // expected-error {{drops qualifiers}} +const int &incfail = ++i; // expected-error {{drops 'volatile' qualifier}} +const int &decfail = --i; // expected-error {{drops 'volatile' qualifier}} // PR7794 void f0(int e) { diff --git a/test/SemaCXX/integer-overflow.cpp b/test/SemaCXX/integer-overflow.cpp new file mode 100644 index 0000000..566bb05 --- /dev/null +++ b/test/SemaCXX/integer-overflow.cpp @@ -0,0 +1,166 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -std=gnu++98 +typedef unsigned long long uint64_t; +typedef unsigned long long uint32_t; + +uint64_t f0(uint64_t); +uint64_t f1(uint64_t, uint32_t); +uint64_t f2(uint64_t, ...); + +static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-warning {{overflow in expression; result is 536870912 with type 'int'}} + +uint64_t check_integer_overflows(int i) { //expected-note {{declared here}} +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + uint64_t overflow = 4608 * 1024 * 1024, +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + overflow2 = (uint64_t)(4608 * 1024 * 1024), +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + overflow3 = (uint64_t)(4608 * 1024 * 1024 * i), +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + overflow4 = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL), +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + overflow5 = static_cast<uint64_t>(4608 * 1024 * 1024), +// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} + multi_overflow = (uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + overflow += overflow2 = overflow3 = (uint64_t)(4608 * 1024 * 1024); +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + overflow += overflow2 = overflow3 = 4608 * 1024 * 1024; + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + overflow += overflow2 = overflow3 = static_cast<uint64_t>(4608 * 1024 * 1024); + + uint64_t not_overflow = 4608 * 1024 * 1024ULL; + uint64_t not_overflow2 = (1ULL * ((uint64_t)(4608) * (1024 * 1024)) + 2ULL); + +// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} + overflow = 4608 * 1024 * 1024 ? 4608 * 1024 * 1024 : 0; + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + overflow = 0 ? 0 : 4608 * 1024 * 1024; + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + if (4608 * 1024 * 1024) + return 0; + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + if ((uint64_t)(4608 * 1024 * 1024)) + return 1; + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + if (static_cast<uint64_t>(4608 * 1024 * 1024)) + return 1; + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + if ((uint64_t)(4608 * 1024 * 1024)) + return 2; + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + if ((uint64_t)(4608 * 1024 * 1024 * i)) + return 3; + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + if ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)) + return 4; + +// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} + if ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))) + return 5; + + switch (i) { +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + case 4608 * 1024 * 1024: + return 6; +// expected-warning@+1 {{overflow in expression; result is 537919488 with type 'int'}} + case (uint64_t)(4609 * 1024 * 1024): + return 7; +// expected-warning@+1 {{overflow in expression; result is 537919488 with type 'int'}} + case 1 + static_cast<uint64_t>(4609 * 1024 * 1024): + return 7; +// expected-error@+2 {{expression is not an integral constant expression}} +// expected-note@+1 {{read of non-const variable 'i' is not allowed in a constant expression}} + case ((uint64_t)(4608 * 1024 * 1024 * i)): + return 8; +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + case ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)): + return 9; +// expected-warning@+2 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow converting case value to switch condition type (288230376151711744 to 0)}} + case ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))): + return 10; + } + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + while (4608 * 1024 * 1024); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + while ((uint64_t)(4608 * 1024 * 1024)); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + while (static_cast<uint64_t>(4608 * 1024 * 1024)); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + while ((uint64_t)(4608 * 1024 * 1024)); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + while ((uint64_t)(4608 * 1024 * 1024 * i)); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)); + +// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} + while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + do { } while (4608 * 1024 * 1024); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + do { } while ((uint64_t)(4608 * 1024 * 1024)); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + do { } while (static_cast<uint64_t>(4608 * 1024 * 1024)); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + do { } while ((uint64_t)(4608 * 1024 * 1024)); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + do { } while ((uint64_t)(4608 * 1024 * 1024 * i)); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + do { } while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)); + +// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} + do { } while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))); + +// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}} + for (uint64_t i = 4608 * 1024 * 1024; + (uint64_t)(4608 * 1024 * 1024); + i += (uint64_t)(4608 * 1024 * 1024 * i)); + +// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+3 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+3 2{{overflow in expression; result is 536870912 with type 'int'}} + for (uint64_t i = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL); + ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))); + i = ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)))); + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + _Complex long long x = 4608 * 1024 * 1024; + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + (__real__ x) = 4608 * 1024 * 1024; + +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + (__imag__ x) = 4608 * 1024 * 1024; + +// expected-warning@+4 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+3 {{array index 536870912 is past the end of the array (which contains 10 elements)}} +// expected-note@+1 {{array 'a' declared here}} + uint64_t a[10]; + a[4608 * 1024 * 1024] = 1i; + +// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} + return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024))); +} diff --git a/test/SemaCXX/linkage.cpp b/test/SemaCXX/linkage.cpp index 8a2013f..aa59594 100644 --- a/test/SemaCXX/linkage.cpp +++ b/test/SemaCXX/linkage.cpp @@ -83,7 +83,7 @@ extern "C" { // Test both for mangling in the code generation and warnings from use // of internal, undefined names via -Werror. // CHECK: call i32 @g( - // CHECK: load i32* @a, + // CHECK: load i32, i32* @a, return g() + a; } }; @@ -94,8 +94,8 @@ extern "C" { } } -// CHECK: define linkonce_odr i8* @_ZN5test21A1BILj0EE3fooEv( // CHECK: define linkonce_odr i8* @_ZN5test11A3fooILj0EEEPvv( +// CHECK: define linkonce_odr i8* @_ZN5test21A1BILj0EE3fooEv( namespace test5 { struct foo { diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp index e0955ae..5b3393e 100644 --- a/test/SemaCXX/member-expr.cpp +++ b/test/SemaCXX/member-expr.cpp @@ -87,7 +87,7 @@ namespace test5 { } void test2(A &x) { - x->A::foo<int>(); // expected-error {{'test5::A' is not a pointer; maybe you meant to use '.'?}} + x->A::foo<int>(); // expected-error {{'test5::A' is not a pointer; did you mean to use '.'?}} } } @@ -181,7 +181,7 @@ namespace PR15045 { int f() { Cl0 c; - return c->a; // expected-error {{member reference type 'PR15045::Cl0' is not a pointer; maybe you meant to use '.'?}} + return c->a; // expected-error {{member reference type 'PR15045::Cl0' is not a pointer; did you mean to use '.'?}} } struct bar { @@ -202,7 +202,7 @@ namespace PR15045 { foo f; // Show that recovery has happened by also triggering typo correction - e->Func(); // expected-error {{member reference type 'PR15045::bar' is not a pointer; maybe you meant to use '.'?}} \ + e->Func(); // expected-error {{member reference type 'PR15045::bar' is not a pointer; did you mean to use '.'?}} \ // expected-error {{no member named 'Func' in 'PR15045::bar'; did you mean 'func'?}} // Make sure a fixit isn't given in the case that the '->' isn't actually @@ -221,6 +221,6 @@ namespace pr16676 { int f(S* s) { T t; return t.get_s // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}} - .i; // expected-error {{member reference type 'pr16676::S *' is a pointer; maybe you meant to use '->'}} + .i; // expected-error {{member reference type 'pr16676::S *' is a pointer; did you mean to use '->'}} } } diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp index 39cf601..83aeb01 100644 --- a/test/SemaCXX/member-pointer-ms.cpp +++ b/test/SemaCXX/member-pointer-ms.cpp @@ -93,15 +93,15 @@ static_assert(sizeof(void (IncSingle::*)()) == kSingleFunctionSize, ""); static_assert(sizeof(void (IncMultiple::*)()) == kMultipleFunctionSize, ""); static_assert(sizeof(void (IncVirtual::*)()) == kVirtualFunctionSize, ""); -static_assert(__alignof(int IncSingle::*) == kSingleDataAlign, ""); -static_assert(__alignof(int IncMultiple::*) == kMultipleDataAlign, ""); -static_assert(__alignof(int IncVirtual::*) == kVirtualDataAlign, ""); -static_assert(__alignof(void (IncSingle::*)()) == kSingleFunctionAlign, ""); -static_assert(__alignof(void (IncMultiple::*)()) == kMultipleFunctionAlign, ""); -static_assert(__alignof(void (IncVirtual::*)()) == kVirtualFunctionAlign, ""); +static_assert(__alignof(int IncSingle::*) == __alignof(void *), ""); +static_assert(__alignof(int IncMultiple::*) == __alignof(void *), ""); +static_assert(__alignof(int IncVirtual::*) == __alignof(void *), ""); +static_assert(__alignof(void (IncSingle::*)()) == __alignof(void *), ""); +static_assert(__alignof(void (IncMultiple::*)()) == __alignof(void *), ""); +static_assert(__alignof(void (IncVirtual::*)()) == __alignof(void *), ""); // An incomplete type with an unspecified inheritance model seems to take one -// more slot than virtual. It's not clear what it's used for yet. +// more slot than virtual. class IncUnspecified; static_assert(sizeof(int IncUnspecified::*) == kUnspecifiedDataSize, ""); static_assert(sizeof(void (IncUnspecified::*)()) == kUnspecifiedFunctionSize, ""); diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp index b8631bc..afb7455 100644 --- a/test/SemaCXX/member-pointer.cpp +++ b/test/SemaCXX/member-pointer.cpp @@ -12,8 +12,10 @@ class H : A {}; // expected-note 2{{implicitly declared private here}} int A::*pdi1; int (::A::*pdi2); int (A::*pfi)(int); +void (*A::*ppfie)() throw(); // expected-error {{exception specifications are not allowed beyond a single level of indirection}} -int B::*pbi; // expected-error {{'B' is not a class, namespace, or scoped enumeration}} +int B::*pbi; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}} \ + // expected-error {{'pbi' does not point into a class}} int C::*pci; // expected-error {{'pci' does not point into a class}} void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}} int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}} diff --git a/test/SemaCXX/microsoft-dtor-lookup.cpp b/test/SemaCXX/microsoft-dtor-lookup.cpp index 412749f..312598e 100644 --- a/test/SemaCXX/microsoft-dtor-lookup.cpp +++ b/test/SemaCXX/microsoft-dtor-lookup.cpp @@ -23,8 +23,9 @@ struct VC : A, B { virtual ~VC(); // expected-error {{member 'operator delete' found in multiple base classes of different types}} }; -void f(VC vc) { +void f() { // This marks VC's vtable used. + VC vc; } } diff --git a/test/SemaCXX/microsoft-new-delete.cpp b/test/SemaCXX/microsoft-new-delete.cpp index 6c9be22..b929e61 100644 --- a/test/SemaCXX/microsoft-new-delete.cpp +++ b/test/SemaCXX/microsoft-new-delete.cpp @@ -31,4 +31,4 @@ struct explicit_ctor_tag {} ect; void *operator new[](size_t, explicit_ctor_tag, explicit_ctor); void *operator new(size_t, explicit_ctor_tag, int); void *t = new (ect, 0) int[4]; -void *u = new (ect, {0}) int[4]; +void *u = new (ect, {0}) int[4]; // expected-warning {{braces around scalar init}} diff --git a/test/SemaCXX/ms-novtable.cpp b/test/SemaCXX/ms-novtable.cpp new file mode 100644 index 0000000..2d55c48 --- /dev/null +++ b/test/SemaCXX/ms-novtable.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions -Wno-microsoft -std=c++11 + +struct __declspec(novtable) S {}; +enum __declspec(novtable) E {}; // expected-warning{{'novtable' attribute only applies to classes}} +int __declspec(novtable) I; // expected-warning{{'novtable' attribute only applies to classes}} +typedef struct T __declspec(novtable) U; // expected-warning{{'novtable' attribute only applies to classes}} +auto z = []() __declspec(novtable) { return nullptr; }; // expected-warning{{'novtable' attribute only applies to classes}} diff --git a/test/SemaCXX/ms_integer_suffix.cpp b/test/SemaCXX/ms_integer_suffix.cpp index 6b4594d..d65e7f4 100644 --- a/test/SemaCXX/ms_integer_suffix.cpp +++ b/test/SemaCXX/ms_integer_suffix.cpp @@ -3,6 +3,11 @@ #ifdef __SIZEOF_INT8__ static_assert(sizeof(0i8) == __SIZEOF_INT8__, ""); + +constexpr int f(char) { return 1; } +constexpr int f(signed char) { return 2; } + +static_assert(f(0i8) == 1, ""); #endif #ifdef __SIZEOF_INT16__ static_assert(sizeof(0i16) == __SIZEOF_INT16__, ""); diff --git a/test/SemaCXX/ms_mutable_reference_member.cpp b/test/SemaCXX/ms_mutable_reference_member.cpp new file mode 100644 index 0000000..ae1389d --- /dev/null +++ b/test/SemaCXX/ms_mutable_reference_member.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-compatibility + +struct S { + mutable int &a; // expected-warning {{'mutable' on a reference type is a Microsoft extension}} + S(int &b) : a(b) {} +}; + +int main() { + int a = 0; + const S s(a); + s.a = 10; + return s.a + a; +} diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp index bdeb00d..0fbdedc 100644 --- a/test/SemaCXX/nested-name-spec.cpp +++ b/test/SemaCXX/nested-name-spec.cpp @@ -13,7 +13,7 @@ namespace A { } A:: ; // expected-error {{expected unqualified-id}} -::A::ax::undef ex3; // expected-error {{'ax' is not a class, namespace, or scoped enumeration}} +::A::ax::undef ex3; // expected-error {{'ax' is not a class, namespace, or enumeration}} A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}} int A::C::Ag1() { return 0; } @@ -88,9 +88,9 @@ void f3() { // declared here", "template 'X' declared here", etc) to help explain what it // is if it's 'not a class, namespace, or scoped enumeration'. int N; // expected-note {{'N' declared here}} - N::x = 0; // expected-error {{'N' is not a class, namespace, or scoped enumeration}} + N::x = 0; // expected-error {{'N' is not a class, namespace, or enumeration}} { int A; A::ax = 0; } - { typedef int A; A::ax = 0; } // expected-error{{'A' (aka 'int') is not a class, namespace, or scoped enumeration}} + { typedef int A; A::ax = 0; } // expected-error{{'A' (aka 'int') is not a class, namespace, or enumeration}} { typedef A::C A; A::ax = 0; } // expected-error {{no member named 'ax'}} { typedef A::C A; A::cx = 0; } } @@ -115,8 +115,8 @@ namespace E { X = 0 }; - void f() { - return E::X; // expected-error{{'E::Nested::E' is not a class, namespace, or scoped enumeration}} + int f() { + return E::X; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}} } } } @@ -310,7 +310,7 @@ namespace N { } namespace TypedefNamespace { typedef int F; }; -TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; // expected-error {{'F' (aka 'int') is not a class, namespace, or scoped enumeration}} +TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; // expected-error {{'F' (aka 'int') is not a class, namespace, or enumeration}} namespace PR18587 { @@ -410,3 +410,28 @@ struct S7c { }; } + +namespace PR16951 { + namespace ns { + enum an_enumeration { + ENUMERATOR // expected-note{{'ENUMERATOR' declared here}} + }; + } + + int x1 = ns::an_enumeration::ENUMERATOR; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}} + + int x2 = ns::an_enumeration::ENUMERATOR::vvv; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}} \ + // expected-error{{'ENUMERATOR' is not a class, namespace, or enumeration}} \ + + int x3 = ns::an_enumeration::X; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}} \ + // expected-error{{no member named 'X'}} + + enum enumerator_2 { + ENUMERATOR_2 + }; + + int x4 = enumerator_2::ENUMERATOR_2; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}} + int x5 = enumerator_2::X2; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}} \ + // expected-error{{no member named 'X2' in 'PR16951::enumerator_2'}} + +} diff --git a/test/SemaCXX/new-array-size-conv.cpp b/test/SemaCXX/new-array-size-conv.cpp index e8bb679..c987c28 100644 --- a/test/SemaCXX/new-array-size-conv.cpp +++ b/test/SemaCXX/new-array-size-conv.cpp @@ -16,7 +16,8 @@ struct ValueEnum { struct ValueBoth : ValueInt, ValueEnum { }; struct IndirectValueInt : ValueInt { }; -struct TwoValueInts : ValueInt, IndirectValueInt { }; +struct TwoValueInts : ValueInt, IndirectValueInt { }; // expected-warning{{direct base 'ValueInt' is inaccessible due to ambiguity:\n struct TwoValueInts -> struct ValueInt\n struct TwoValueInts -> struct IndirectValueInt -> struct ValueInt}} + void test() { (void)new int[ValueInt(10)]; // expected-warning{{implicit conversion from array size expression of type 'ValueInt' to integral type 'int' is a C++11 extension}} diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp index cb43458..7bc724b 100644 --- a/test/SemaCXX/new-delete.cpp +++ b/test/SemaCXX/new-delete.cpp @@ -524,3 +524,11 @@ namespace PR18544 { // PR19968 inline void* operator new(); // expected-error {{'operator new' must have at least one parameter}} + +namespace { +template <class C> +struct A { + void f() { this->::new; } // expected-error {{expected unqualified-id}} + void g() { this->::delete; } // expected-error {{expected unqualified-id}} +}; +} diff --git a/test/SemaCXX/overload-decl.cpp b/test/SemaCXX/overload-decl.cpp index fdb14cb..1201396 100644 --- a/test/SemaCXX/overload-decl.cpp +++ b/test/SemaCXX/overload-decl.cpp @@ -30,10 +30,8 @@ class X { static void g(int); // expected-error {{static and non-static member functions with the same parameter types cannot be overloaded}} static void g(float); // expected-error {{class member cannot be redeclared}} - void h(); // expected-note {{previous declaration is here}} \ - expected-note {{previous declaration is here}} - void h() __restrict; // expected-error {{class member cannot be redeclared}} \ - expected-error {{conflicting types for 'h'}} + void h(); // expected-note {{previous declaration is here}} + void h() __restrict; // expected-error {{class member cannot be redeclared}} }; int main() {} // expected-note {{previous definition is here}} diff --git a/test/SemaCXX/pr9812.c b/test/SemaCXX/pr9812.c deleted file mode 100644 index cbbe44b..0000000 --- a/test/SemaCXX/pr9812.c +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -#define bool _Bool -int test1(int argc, char** argv) -{ - bool signed; // expected-error {{'bool' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}} - - return 0; -} -#undef bool - -typedef int bool; - -int test2(int argc, char** argv) -{ - bool signed; // expected-error {{'type-name' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}} - _Bool signed; // expected-error {{'_Bool' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}} - - return 0; -} - diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp index 95363e5..45f1eaf 100644 --- a/test/SemaCXX/pseudo-destructors.cpp +++ b/test/SemaCXX/pseudo-destructors.cpp @@ -46,7 +46,7 @@ void f(A* a, Foo *f, int *i, double *d, int ii) { i->N::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}} i->Integer::~Double(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('Double' (aka 'double')) in pseudo-destructor expression}} - ii->~Integer(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}} + ii->~Integer(); // expected-error{{member reference type 'int' is not a pointer; did you mean to use '.'?}} ii.~Integer(); cv_test(a); @@ -59,7 +59,11 @@ void f(A* a, Foo *f, int *i, double *d, int ii) { typedef int Integer; void destroy_without_call(int *ip) { - ip->~Integer; // expected-error{{called immediately}} + ip->~Integer; // expected-error{{reference to pseudo-destructor must be called}} +} + +void paren_destroy_with_call(int *ip) { + (ip->~Integer)(); } // PR5530 diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp index cfe7dc1..dc59d50 100644 --- a/test/SemaCXX/references.cpp +++ b/test/SemaCXX/references.cpp @@ -54,7 +54,7 @@ void test4() { void test5() { // const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0 const volatile int cvi = 1; - const int& r = cvi; // expected-error{{binding of reference to type 'const int' to a value of type 'const volatile int' drops qualifiers}} + const int& r = cvi; // expected-error{{binding value of type 'const volatile int' to reference to type 'const int' drops 'volatile' qualifier}} } // C++ [dcl.init.ref]p3 @@ -70,7 +70,7 @@ class Test6 { // expected-warning{{class 'Test6' does not declare any constructo int& okay; // expected-note{{reference member 'okay' will never be initialized}} }; -struct C : B, A { }; +struct C : B, A { }; // expected-warning {{direct base 'A' is inaccessible due to ambiguity:\n struct C -> struct B -> struct A\nstruct C -> struct A}} void test7(C& c) { A& a1 = c; // expected-error {{ambiguous conversion from derived class 'C' to base class 'A':}} diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp index 4284032..7c88dc0 100644 --- a/test/SemaCXX/reinterpret-cast.cpp +++ b/test/SemaCXX/reinterpret-cast.cpp @@ -201,11 +201,11 @@ void dereference_reinterpret_cast() { (void)*reinterpret_cast<float*>(v_ptr); // Casting to void pointer - (void)*reinterpret_cast<void*>(&a); - (void)*reinterpret_cast<void*>(&b); - (void)*reinterpret_cast<void*>(&l); - (void)*reinterpret_cast<void*>(&d); - (void)*reinterpret_cast<void*>(&f); + (void)*reinterpret_cast<void*>(&a); // expected-warning {{ISO C++ does not allow}} + (void)*reinterpret_cast<void*>(&b); // expected-warning {{ISO C++ does not allow}} + (void)*reinterpret_cast<void*>(&l); // expected-warning {{ISO C++ does not allow}} + (void)*reinterpret_cast<void*>(&d); // expected-warning {{ISO C++ does not allow}} + (void)*reinterpret_cast<void*>(&f); // expected-warning {{ISO C++ does not allow}} } void reinterpret_cast_whitelist () { diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp index ac70099..9e00332 100644 --- a/test/SemaCXX/scope-check.cpp +++ b/test/SemaCXX/scope-check.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions %s -Wno-unreachable-code -// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions -std=gnu++11 %s -Wno-unreachable-code +// RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fblocks -fcxx-exceptions -fms-extensions %s -Wno-unreachable-code +// RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fblocks -fcxx-exceptions -fms-extensions -std=gnu++11 %s -Wno-unreachable-code namespace testInvalid { Invalid inv; // expected-error {{unknown type name}} @@ -441,3 +441,190 @@ namespace test_recovery { } } } + +namespace seh { + +// Jumping into SEH try blocks is not permitted. + +void jump_into_except() { + goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}} + __try { // expected-note {{jump bypasses initialization of __try block}} + into_try_except_try: + ; + } __except(0) { + } + + goto into_try_except_except; // expected-error {{cannot jump from this goto statement to its label}} + __try { + } __except(0) { // expected-note {{jump bypasses initialization of __except block}} + into_try_except_except: + ; + } +} + +void jump_into_finally() { + goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}} + __try { // expected-note {{jump bypasses initialization of __try block}} + into_try_except_try: + ; + } __finally { + } + + goto into_try_except_finally; // expected-error {{cannot jump from this goto statement to its label}} + __try { + } __finally { // expected-note {{jump bypasses initialization of __finally block}} + into_try_except_finally: + ; + } +} + +// Jumping out of SEH try blocks ok in general. (Jumping out of a __finally +// has undefined behavior.) + +void jump_out_of_except() { + __try { + goto out_of_except_try; + } __except(0) { + } +out_of_except_try: + ; + + __try { + } __except(0) { + goto out_of_except_except; + } +out_of_except_except: + ; +} + +void jump_out_of_finally() { + __try { + goto out_of_finally_try; + } __finally { + } +out_of_finally_try: + ; + + __try { + } __finally { + goto out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}} + } + + __try { + } __finally { + goto *&&out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}} + } +out_of_finally_finally: + ; +} + +// Jumping between protected scope and handler is not permitted. + +void jump_try_except() { + __try { + goto from_try_to_except; // expected-error {{cannot jump from this goto statement to its label}} + } __except(0) { // expected-note {{jump bypasses initialization of __except block}} + from_try_to_except: + ; + } + + __try { // expected-note {{jump bypasses initialization of __try block}} + from_except_to_try: + ; + } __except(0) { + goto from_except_to_try; // expected-error {{cannot jump from this goto statement to its label}} + } +} + +void jump_try_finally() { + __try { + goto from_try_to_finally; // expected-error {{cannot jump from this goto statement to its label}} + } __finally { // expected-note {{jump bypasses initialization of __finally block}} + from_try_to_finally: + ; + } + + __try { // expected-note {{jump bypasses initialization of __try block}} + from_finally_to_try: + ; + } __finally { + goto from_finally_to_try; // expected-error {{cannot jump from this goto statement to its label}} expected-warning {{jump out of __finally block has undefined behavior}} + } +} + +void nested() { + // These are not permitted. + __try { + __try { + } __finally { + goto outer_except; // expected-error {{cannot jump from this goto statement to its label}} + } + } __except(0) { // expected-note {{jump bypasses initialization of __except bloc}} + outer_except: + ; + } + + __try { + __try{ + } __except(0) { + goto outer_finally; // expected-error {{cannot jump from this goto statement to its label}} + } + } __finally { // expected-note {{jump bypasses initialization of __finally bloc}} + outer_finally: + ; + } + + // These are permitted. + __try { + __try { + } __finally { + goto after_outer_except; // expected-warning {{jump out of __finally block has undefined behavior}} + } + } __except(0) { + } +after_outer_except: + ; + + __try { + __try{ + } __except(0) { + goto after_outer_finally; + } + } __finally { + } +after_outer_finally: + ; +} + +// This section is academic, as MSVC doesn't support indirect gotos. + +void indirect_jumps(void **ip) { + static void *ips[] = { &&l }; + + __try { // expected-note {{jump exits __try block}} + // FIXME: Should this be allowed? Jumping out of the guarded section of a + // __try/__except doesn't require unwinding. + goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} + } __except(0) { + } + + __try { + } __except(0) { // expected-note {{jump exits __except block}} + // FIXME: What about here? + goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} + } + + __try { // expected-note {{jump exits __try block}} + goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} + } __finally { + } + + __try { + } __finally { // expected-note {{jump exits __finally block}} + goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} + } +l: // expected-note 4 {{possible target of indirect goto statement}} + ; +} + +} // namespace seh diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp index 06fd863..b3fe49a 100644 --- a/test/SemaCXX/static-cast.cpp +++ b/test/SemaCXX/static-cast.cpp @@ -9,8 +9,8 @@ struct F : public C1 {}; // Single path to B with virtual. struct G1 : public B {}; struct G2 : public B {}; struct H : public G1, public G2 {}; // Ambiguous path to B. -struct I; // Incomplete. -struct J; // Incomplete. +struct I; // Incomplete. expected-note {{'I' is incomplete}} +struct J; // Incomplete. expected-note {{'J' is incomplete}} enum Enum { En1, En2 }; enum Onom { On1, On2 }; @@ -92,9 +92,13 @@ void t_529_5_8() (void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast private base class 'A' to 'E'}} (void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} - (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'B *' to 'E *' is not allowed}} + (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'B *' to 'E *', which are not related by inheritance, is not allowed}} (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'E' cannot bind to a value of unrelated type 'B'}} + + (void)static_cast<E*>((J*)0); // expected-error {{static_cast from 'J *' to 'E *', which are not related by inheritance, is not allowed}} + (void)static_cast<I*>((B*)0); // expected-error {{static_cast from 'B *' to 'I *', which are not related by inheritance, is not allowed}} + // TODO: Test inaccessible base in context where it's accessible, i.e. // member function and friend. diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index 4833c14..2265c28 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -1857,6 +1857,9 @@ void trivial_checks() { int arr[T(__is_trivially_copyable(HasNonPOD))]; } { int arr[T(__is_trivially_copyable(DerivesHasCons))]; } { int arr[T(__is_trivially_copyable(DerivesHasRef))]; } + { int arr[T(__is_trivially_copyable(NonTrivialDefault))]; } + { int arr[T(__is_trivially_copyable(NonTrivialDefault[]))]; } + { int arr[T(__is_trivially_copyable(NonTrivialDefault[3]))]; } { int arr[F(__is_trivially_copyable(HasCopyAssign))]; } { int arr[F(__is_trivially_copyable(HasMoveAssign))]; } diff --git a/test/SemaCXX/typo-correction-cxx11.cpp b/test/SemaCXX/typo-correction-cxx11.cpp new file mode 100644 index 0000000..99cb166 --- /dev/null +++ b/test/SemaCXX/typo-correction-cxx11.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +namespace PR23186 { +decltype(ned); // expected-error-re {{use of undeclared identifier 'ned'{{$}}}} +// The code below was triggering an UNREACHABLE in ASTContext::getTypeInfoImpl +// once the above code failed to recover properly after making the bogus +// correction of 'ned' to 'new'. +template <typename> +struct S { + enum { V }; + void f() { + switch (0) + case V: + ; + } +}; +} + +namespace PR23140 { +auto lneed = gned.*[] {}; // expected-error-re {{use of undeclared identifier 'gned'{{$}}}} + +void test(int aaa, int bbb, int thisvar) { // expected-note {{'thisvar' declared here}} + int thatval = aaa * (bbb + thatvar); // expected-error {{use of undeclared identifier 'thatvar'; did you mean 'thisvar'?}} +} +} + +namespace PR18854 { +void f() { + for (auto&& x : e) { // expected-error-re {{use of undeclared identifier 'e'{{$}}}} + auto Functor = [x]() {}; + long Alignment = __alignof__(Functor); + } +} +} diff --git a/test/SemaCXX/typo-correction-delayed.cpp b/test/SemaCXX/typo-correction-delayed.cpp index 79ab3f5..121863d 100644 --- a/test/SemaCXX/typo-correction-delayed.cpp +++ b/test/SemaCXX/typo-correction-delayed.cpp @@ -158,6 +158,16 @@ a = b ? : 0; // expected-error {{C++ requires a type specifier for all declarat // expected-error-re {{use of undeclared identifier 'b'{{$}}}} } +extern long clock (void); +struct Pointer { + void set_xpos(int); + void set_ypos(int); +}; +void MovePointer(Pointer &Click, int x, int y) { // expected-note 2 {{'Click' declared here}} + click.set_xpos(x); // expected-error {{use of undeclared identifier 'click'; did you mean 'Click'?}} + click.set_ypos(x); // expected-error {{use of undeclared identifier 'click'; did you mean 'Click'?}} +} + namespace PR22250 { // expected-error@+4 {{use of undeclared identifier 'size_t'; did you mean 'sizeof'?}} // expected-error-re@+3 {{use of undeclared identifier 'y'{{$}}}} @@ -183,3 +193,19 @@ void f() { TimeTicks::now(); // expected-error {{no member named 'now' in 'PR22297::TimeTicks'; did you mean 'Now'?}} } } + +namespace PR23005 { +void f() { int a = Unknown::b(c); } // expected-error {{use of undeclared identifier 'Unknown'}} +// expected-error@-1 {{use of undeclared identifier 'c'}} +} + +namespace PR23350 { +int z = 1 ? N : ; // expected-error {{expected expression}} +// expected-error-re@-1 {{use of undeclared identifier 'N'{{$}}}} +} + +// PR 23285. This test must be at the end of the file to avoid additional, +// unwanted diagnostics. +// expected-error-re@+2 {{use of undeclared identifier 'uintmax_t'{{$}}}} +// expected-error@+1 {{expected ';' after top level declarator}} +unsigned int a = 0(uintmax_t diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp index 3249001..174b140 100644 --- a/test/SemaCXX/typo-correction.cpp +++ b/test/SemaCXX/typo-correction.cpp @@ -634,3 +634,9 @@ namespace testArraySubscriptIndex { } }; } + +namespace crash_has_include { +int has_include(int); // expected-note {{'has_include' declared here}} +// expected-error@+1 {{__has_include must be used within a preprocessing directive}} +int foo = __has_include(42); // expected-error {{use of undeclared identifier '__has_include'; did you mean 'has_include'?}} +} diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp index 018b1fe..5769a0c 100644 --- a/test/SemaCXX/uninitialized.cpp +++ b/test/SemaCXX/uninitialized.cpp @@ -86,7 +86,6 @@ void test_stuff () { int aa = (ref(aa) += 10); // expected-warning {{variable 'aa' is uninitialized when used within its own initialization}} int bb = bb ? x : y; // expected-warning {{variable 'bb' is uninitialized when used within its own initialization}} - for (;;) { int a = a; // no-warning: used to signal intended lack of initialization. int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}} @@ -124,6 +123,50 @@ void test_stuff () { } } +void test_comma() { + int a; // expected-note {{initialize the variable 'a' to silence this warning}} + int b = (a, a ?: 2); // expected-warning {{variable 'a' is uninitialized when used here}} + int c = (a, a, b, c); // expected-warning {{variable 'c' is uninitialized when used within its own initialization}} + int d; // expected-note {{initialize the variable 'd' to silence this warning}} + int e = (foo(d), e, b); // expected-warning {{variable 'd' is uninitialized when used here}} + int f; // expected-note {{initialize the variable 'f' to silence this warning}} + f = f + 1, 2; // expected-warning {{variable 'f' is uninitialized when used here}} + int h; + int g = (h, g, 2); // no-warning: h, g are evaluated but not used. +} + +namespace member_ptr { +struct A { + int x; + int y; + A(int x) : x{x} {} +}; + +void test_member_ptr() { + int A::* px = &A::x; + A a{a.*px}; // expected-warning {{variable 'a' is uninitialized when used within its own initialization}} + A b = b; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}} +} +} + +namespace const_ptr { +void foo(int *a); +void bar(const int *a); +void foobar(const int **a); + +void test_const_ptr() { + int a; + int b; // expected-note {{initialize the variable 'b' to silence this warning}} + foo(&a); + bar(&b); + b = a + b; // expected-warning {{variable 'b' is uninitialized when used here}} + int *ptr; //expected-note {{initialize the variable 'ptr' to silence this warning}} + const int *ptr2; + foo(ptr); // expected-warning {{variable 'ptr' is uninitialized when used here}} + foobar(&ptr2); +} +} + // Also test similar constructs in a field's initializer. struct S { int x; @@ -1385,3 +1428,12 @@ class A { A(int (*) [7]) : a(rvalueref::notmove(a)) {} }; } + +void array_capture(bool b) { + const char fname[] = "array_capture"; + if (b) { + int unused; // expected-warning {{unused variable}} + } else { + [fname]{}; + } +} diff --git a/test/SemaCXX/unreachable-catch-clauses.cpp b/test/SemaCXX/unreachable-catch-clauses.cpp index c75067f..8dcb47b 100644 --- a/test/SemaCXX/unreachable-catch-clauses.cpp +++ b/test/SemaCXX/unreachable-catch-clauses.cpp @@ -8,7 +8,6 @@ void f(); void test() try {} -catch (BaseEx &e) { f(); } -catch (Ex1 &e) { f(); } // expected-note {{for type class Ex1 &}} -catch (Ex2 &e) { f(); } // expected-warning {{exception of type Ex2 & will be caught by earlier handler}} - +catch (BaseEx &e) { f(); } // expected-note 2{{for type 'BaseEx &'}} +catch (Ex1 &e) { f(); } // expected-warning {{exception of type 'Ex1 &' will be caught by earlier handler}} +catch (Ex2 &e) { f(); } // expected-warning {{exception of type 'Ex2 &' (aka 'Ex1 &') will be caught by earlier handler}} diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp index e95acab..ec884f3 100644 --- a/test/SemaCXX/virtual-override.cpp +++ b/test/SemaCXX/virtual-override.cpp @@ -46,7 +46,7 @@ namespace T4 { struct a { }; struct a1 : a { }; -struct b : a, a1 { }; +struct b : a, a1 { }; // expected-warning{{direct base 'T4::a' is inaccessible due to ambiguity:\n struct T4::b -> struct T4::a\n struct T4::b -> struct T4::a1 -> struct T4::a}} class A { virtual a* f(); // expected-note{{overridden virtual function is here}} diff --git a/test/SemaCXX/vla.cpp b/test/SemaCXX/vla.cpp index dae6450..6efb648 100644 --- a/test/SemaCXX/vla.cpp +++ b/test/SemaCXX/vla.cpp @@ -17,3 +17,6 @@ namespace PR18581 { incomplete c[n]; // expected-error {{incomplete}} } } + +void pr23151(int (&)[*]) { // expected-error {{variable length array must be bound in function definition}} +} diff --git a/test/SemaCXX/warn-bad-memaccess.cpp b/test/SemaCXX/warn-bad-memaccess.cpp index e86610a..67cde10 100644 --- a/test/SemaCXX/warn-bad-memaccess.cpp +++ b/test/SemaCXX/warn-bad-memaccess.cpp @@ -21,7 +21,7 @@ public: void foo() {} } c1; -struct X1 { virtual void f(); } x1; +struct X1 { virtual void f(); } x1, x1arr[2]; struct X2 : virtual S1 {} x2; struct ContainsDynamic { X1 dynamic; } contains_dynamic; @@ -33,6 +33,10 @@ void test_warn() { memset(&x1, 0, sizeof x1); // \ // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \ // expected-note {{explicitly cast the pointer to silence this warning}} + memset(x1arr, 0, sizeof x1arr); // \ + // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \ + // expected-note {{explicitly cast the pointer to silence this warning}} + memset((void*)x1arr, 0, sizeof x1arr); memset(&x2, 0, sizeof x2); // \ // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \ // expected-note {{explicitly cast the pointer to silence this warning}} diff --git a/test/SemaCXX/warn-consumed-analysis.cpp b/test/SemaCXX/warn-consumed-analysis.cpp index 977b862..0a6aed6 100644 --- a/test/SemaCXX/warn-consumed-analysis.cpp +++ b/test/SemaCXX/warn-consumed-analysis.cpp @@ -638,6 +638,18 @@ void testWhileLoop1() { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} } +// Tests if state information is correctly discarded for certain shapes of CFGs. +void testSwitchGOTO(void) { + int a; + + LABEL0: + switch (a) + case 0: + goto LABEL0; + + goto LABEL0; +} + typedef const int*& IntegerPointerReference; void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {} diff --git a/test/SemaCXX/warn-empty-body.cpp b/test/SemaCXX/warn-empty-body.cpp index d3aaac1..a248c42 100644 --- a/test/SemaCXX/warn-empty-body.cpp +++ b/test/SemaCXX/warn-empty-body.cpp @@ -4,10 +4,17 @@ void a(int i); int b(); int c(); +#define MACRO_A 0 + void test1(int x, int y) { while(true) { if (x); // expected-warning {{if statement has empty body}} expected-note{{put the semicolon on a separate line to silence this warning}} + // Check that we handle conditions that start or end with a macro + // correctly. + if (x == MACRO_A); // expected-warning {{if statement has empty body}} expected-note{{put the semicolon on a separate line to silence this warning}} + if (MACRO_A == x); // expected-warning {{if statement has empty body}} expected-note{{put the semicolon on a separate line to silence this warning}} + int i; // PR11329 for (i = 0; i < x; i++); { // expected-warning{{for loop has empty body}} expected-note{{put the semicolon on a separate line to silence this warning}} diff --git a/test/SemaCXX/warn-memset-bad-sizeof.cpp b/test/SemaCXX/warn-memset-bad-sizeof.cpp index e388634..cca15fc 100644 --- a/test/SemaCXX/warn-memset-bad-sizeof.cpp +++ b/test/SemaCXX/warn-memset-bad-sizeof.cpp @@ -95,9 +95,11 @@ void f(Mat m, const Foo& const_foo, char *buffer) { int iarr[14]; memset(&iarr[0], 0, sizeof iarr); + memset(iarr, 0, sizeof iarr); int* iparr[14]; memset(&iparr[0], 0, sizeof iparr); + memset(iparr, 0, sizeof iparr); memset(m, 0, sizeof(Mat)); diff --git a/test/SemaCXX/warn-missing-prototypes.cpp b/test/SemaCXX/warn-missing-prototypes.cpp index f7e8db3..cb41933 100644 --- a/test/SemaCXX/warn-missing-prototypes.cpp +++ b/test/SemaCXX/warn-missing-prototypes.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-prototypes %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-prototypes -std=c++11 %s void f() { } // expected-warning {{no previous prototype for function 'f'}} @@ -30,3 +30,5 @@ class I { friend void I_friend() {} }; +// Don't warn on explicitly deleted functions. +void j() = delete; diff --git a/test/SemaCXX/warn-pessmizing-move.cpp b/test/SemaCXX/warn-pessmizing-move.cpp new file mode 100644 index 0000000..6b49944 --- /dev/null +++ b/test/SemaCXX/warn-pessmizing-move.cpp @@ -0,0 +1,203 @@ +// RUN: %clang_cc1 -fsyntax-only -Wpessimizing-move -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wpessimizing-move -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +// definitions for std::move +namespace std { +inline namespace foo { +template <class T> struct remove_reference { typedef T type; }; +template <class T> struct remove_reference<T&> { typedef T type; }; +template <class T> struct remove_reference<T&&> { typedef T type; }; + +template <class T> typename remove_reference<T>::type &&move(T &&t); +} +} + +struct A {}; +struct B { + B() {} + B(A) {} +}; + +A test1(A a1) { + A a2; + return a1; + return a2; + return std::move(a1); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" + return std::move(a2); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" +} + +B test2(A a1, B b1) { + // Object is different than return type so don't warn. + A a2; + return a1; + return a2; + return std::move(a1); + return std::move(a2); + + B b2; + return b1; + return b2; + return std::move(b1); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" + return std::move(b2); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" +} + +A global_a; +A test3() { + // Don't warn when object is not local. + return global_a; + return std::move(global_a); + static A static_a; + return static_a; + return std::move(static_a); + +} + +A test4() { + return A(); + return test3(); + + return std::move(A()); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" + return std::move(test3()); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:27-[[@LINE-4]]:28}:"" +} + +void test5(A) { + test5(A()); + test5(test4()); + + test5(std::move(A())); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:19}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" + test5(std::move(test4())); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:19}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:26-[[@LINE-4]]:27}:"" +} + +void test6() { + A a1 = A(); + A a2 = test3(); + + A a3 = std::move(A()); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" + A a4 = std::move(test3()); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:27-[[@LINE-4]]:28}:"" +} + +A test7() { + A a1 = std::move(A()); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" + A a2 = std::move((A())); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:25-[[@LINE-4]]:26}:"" + A a3 = (std::move(A())); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:24-[[@LINE-4]]:25}:"" + A a4 = (std::move((A()))); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:26-[[@LINE-4]]:27}:"" + + return std::move(a1); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" + return std::move((a1)); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:24-[[@LINE-4]]:25}:"" + return (std::move(a1)); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" + return (std::move((a1))); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:25-[[@LINE-4]]:26}:"" +} + +#define wrap1(x) x +#define wrap2(x) x + +// Macro test. Since the std::move call is outside the macro, it is +// safe to suggest a fix-it. +A test8(A a) { + return std::move(a); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:21-[[@LINE-4]]:22}:"" + return std::move(wrap1(a)); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:28-[[@LINE-4]]:29}:"" + return std::move(wrap1(wrap2(a))); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:35-[[@LINE-4]]:36}:"" +} + +#define test9 \ + A test9(A a) { \ + return std::move(a); \ + } + +// Macro test. The std::call is inside the macro, so no fix-it is suggested. +test9 +// expected-warning@-1{{prevents copy elision}} +// CHECK-NOT: fix-it + +#define return_a return std::move(a) + +// Macro test. The std::call is inside the macro, so no fix-it is suggested. +A test10(A a) { + return_a; + // expected-warning@-1{{prevents copy elision}} + // CHECK-NOT: fix-it +} diff --git a/test/SemaCXX/warn-range-loop-analysis.cpp b/test/SemaCXX/warn-range-loop-analysis.cpp new file mode 100644 index 0000000..91756b9 --- /dev/null +++ b/test/SemaCXX/warn-range-loop-analysis.cpp @@ -0,0 +1,299 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wloop-analysis -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wrange-loop-analysis -verify %s + +template <typename return_type> +struct Iterator { + return_type operator*(); + Iterator operator++(); + bool operator!=(const Iterator); +}; + +template <typename T> +struct Container { + typedef Iterator<T> I; + + I begin(); + I end(); +}; + +struct Foo {}; +struct Bar { + Bar(Foo); + Bar(int); + operator int(); +}; + +// Testing notes: +// test0 checks that the full text of the warnings and notes is correct. The +// rest of the tests checks a smaller portion of the text. +// test1-6 are set in pairs, the odd numbers are the non-reference returning +// versions of the even numbers. +// test7-9 use an array instead of a range object +// tests use all four versions of the loop varaible, const &T, const T, T&, and +// T. Versions producing errors and are commented out. +// +// Conversion chart: +// double <=> int +// int <=> Bar +// double => Bar +// Foo => Bar +// +// Conversions during tests: +// test1-2 +// int => int +// int => double +// int => Bar +// test3-4 +// Bar => Bar +// Bar => int +// test5-6 +// Foo => Bar +// test7 +// double => double +// double => int +// double => Bar +// test8 +// Foo => Foo +// Foo => Bar +// test9 +// Bar => Bar +// Bar => int + +void test0() { + Container<int> int_non_ref_container; + Container<int&> int_container; + Container<Bar&> bar_container; + + for (const int &x : int_non_ref_container) {} + // expected-warning@-1 {{loop variable 'x' is always a copy because the range of type 'Container<int>' does not return a reference}} + // expected-note@-2 {{use non-reference type 'int'}} + + for (const double &x : int_container) {} + // expected-warning@-1 {{loop variable 'x' has type 'const double &' but is initialized with type 'int' resulting in a copy}} + // expected-note@-2 {{use non-reference type 'double' to keep the copy or type 'const int &' to prevent copying}} + + for (const Bar x : bar_container) {} + // expected-warning@-1 {{loop variable 'x' of type 'const Bar' creates a copy from type 'const Bar'}} + // expected-note@-2 {{use reference type 'const Bar &' to prevent copying}} +} + +void test1() { + Container<int> A; + + for (const int &x : A) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'int'}} + for (const int x : A) {} + // No warning, non-reference type indicates copy is made + //for (int &x : A) {} + // Binding error + for (int x : A) {} + // No warning, non-reference type indicates copy is made + + for (const double &x : A) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'double'}} + for (const double x : A) {} + // No warning, non-reference type indicates copy is made + //for (double &x : A) {} + // Binding error + for (double x : A) {} + // No warning, non-reference type indicates copy is made + + for (const Bar &x : A) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'Bar'}} + for (const Bar x : A) {} + // No warning, non-reference type indicates copy is made + //for (Bar &x : A) {} + // Binding error + for (Bar x : A) {} + // No warning, non-reference type indicates copy is made +} + +void test2() { + Container<int&> B; + + for (const int &x : B) {} + // No warning, this reference is not a temporary + for (const int x : B) {} + // No warning on POD copy + for (int &x : B) {} + // No warning + for (int x : B) {} + // No warning + + for (const double &x : B) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'double'{{.*}}'const int &'}} + for (const double x : B) {} + //for (double &x : B) {} + // Binding error + for (double x : B) {} + // No warning + + for (const Bar &x : B) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note@-2 {{'Bar'}} + for (const Bar x : B) {} + //for (Bar &x : B) {} + // Binding error + for (Bar x : B) {} + // No warning +} + +void test3() { + Container<Bar> C; + + for (const Bar &x : C) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'Bar'}} + for (const Bar x : C) {} + // No warning, non-reference type indicates copy is made + //for (Bar &x : C) {} + // Binding error + for (Bar x : C) {} + // No warning, non-reference type indicates copy is made + + for (const int &x : C) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'int'}} + for (const int x : C) {} + // No warning, copy made + //for (int &x : C) {} + // Binding error + for (int x : C) {} + // No warning, copy made +} + +void test4() { + Container<Bar&> D; + + for (const Bar &x : D) {} + // No warning, this reference is not a temporary + for (const Bar x : D) {} + // expected-warning@-1 {{creates a copy}} + // expected-note@-2 {{'const Bar &'}} + for (Bar &x : D) {} + // No warning + for (Bar x : D) {} + // No warning + + for (const int &x : D) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} + for (const int x : D) {} + // No warning + //for (int &x : D) {} + // Binding error + for (int x : D) {} + // No warning +} + +void test5() { + Container<Foo> E; + + for (const Bar &x : E) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'Bar'}} + for (const Bar x : E) {} + // No warning, non-reference type indicates copy is made + //for (Bar &x : E) {} + // Binding error + for (Bar x : E) {} + // No warning, non-reference type indicates copy is made +} + +void test6() { + Container<Foo&> F; + + for (const Bar &x : F) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} + for (const Bar x : F) {} + // No warning. + //for (Bar &x : F) {} + // Binding error + for (Bar x : F) {} + // No warning +} + +void test7() { + double G[2]; + + for (const double &x : G) {} + // No warning + for (const double x : G) {} + // No warning on POD copy + for (double &x : G) {} + // No warning + for (double x : G) {} + // No warning + + for (const int &x : G) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'int'{{.*}}'const double &'}} + for (const int x : G) {} + // No warning + //for (int &x : G) {} + // Binding error + for (int x : G) {} + // No warning + + for (const Bar &x : G) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}} + for (const Bar x : G) {} + // No warning + //for (int &Bar : G) {} + // Binding error + for (int Bar : G) {} + // No warning +} + +void test8() { + Foo H[2]; + + for (const Foo &x : H) {} + // No warning + for (const Foo x : H) {} + // No warning on POD copy + for (Foo &x : H) {} + // No warning + for (Foo x : H) {} + // No warning + + for (const Bar &x : H) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} + for (const Bar x : H) {} + // No warning + //for (Bar &x: H) {} + // Binding error + for (Bar x: H) {} + // No warning +} + +void test9() { + Bar I[2] = {1,2}; + + for (const Bar &x : I) {} + // No warning + for (const Bar x : I) {} + // expected-warning@-1 {{creates a copy}} + // expected-note@-2 {{'const Bar &'}} + for (Bar &x : I) {} + // No warning + for (Bar x : I) {} + // No warning + + for (const int &x : I) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} + for (const int x : I) {} + // No warning + //for (int &x : I) {} + // Binding error + for (int x : I) {} + // No warning +} diff --git a/test/SemaCXX/warn-redundant-move.cpp b/test/SemaCXX/warn-redundant-move.cpp new file mode 100644 index 0000000..feb9e6f --- /dev/null +++ b/test/SemaCXX/warn-redundant-move.cpp @@ -0,0 +1,92 @@ +// RUN: %clang_cc1 -fsyntax-only -Wredundant-move -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wredundant-move -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +// definitions for std::move +namespace std { +inline namespace foo { +template <class T> struct remove_reference { typedef T type; }; +template <class T> struct remove_reference<T&> { typedef T type; }; +template <class T> struct remove_reference<T&&> { typedef T type; }; + +template <class T> typename remove_reference<T>::type &&move(T &&t); +} +} + +struct A {}; +struct B : public A {}; + +A test1(B b1) { + B b2; + return b1; + return b2; + return std::move(b1); + // expected-warning@-1{{redundant move}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" + return std::move(b2); + // expected-warning@-1{{redundant move}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" +} + +struct C { + C() {} + C(A) {} +}; + +C test2(A a1, B b1) { + A a2; + B b2; + + return a1; + return a2; + return b1; + return b2; + + return std::move(a1); + // expected-warning@-1{{redundant move}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" + return std::move(a2); + // expected-warning@-1{{redundant move}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" + return std::move(b1); + // expected-warning@-1{{redundant move}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" + return std::move(b2); + // expected-warning@-1{{redundant move}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" +} + +// Copy of tests above with types changed to reference types. +A test3(B& b1) { + B& b2 = b1; + return b1; + return b2; + return std::move(b1); + return std::move(b2); +} + +C test4(A& a1, B& b1) { + A& a2 = a1; + B& b2 = b1; + + return a1; + return a2; + return b1; + return b2; + + return std::move(a1); + return std::move(a2); + return std::move(b1); + return std::move(b2); +} diff --git a/test/SemaCXX/warn-reinterpret-base-class.cpp b/test/SemaCXX/warn-reinterpret-base-class.cpp index 0231f19..d73b487 100644 --- a/test/SemaCXX/warn-reinterpret-base-class.cpp +++ b/test/SemaCXX/warn-reinterpret-base-class.cpp @@ -20,7 +20,7 @@ class DVA : public virtual A { }; class DDVA : public virtual DA { }; -class DMA : public virtual A, public virtual DA { +class DMA : public virtual A, public virtual DA { //expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n class DMA -> class A\n class DMA -> class DA -> class A}} }; class B; diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp index 091e473..4f31d40 100644 --- a/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -3,31 +3,31 @@ // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s -#define LOCKABLE __attribute__ ((lockable)) -#define SCOPED_LOCKABLE __attribute__ ((scoped_lockable)) -#define GUARDED_BY(x) __attribute__ ((guarded_by(x))) -#define GUARDED_VAR __attribute__ ((guarded_var)) -#define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x))) -#define PT_GUARDED_VAR __attribute__ ((pt_guarded_var)) -#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__))) -#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__))) -#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__))) -#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__))) -#define ASSERT_EXCLUSIVE_LOCK(...) __attribute__ ((assert_exclusive_lock(__VA_ARGS__))) -#define ASSERT_SHARED_LOCK(...) __attribute__ ((assert_shared_lock(__VA_ARGS__))) -#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__))) -#define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__))) -#define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__))) -#define LOCK_RETURNED(x) __attribute__ ((lock_returned(x))) -#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__))) -#define EXCLUSIVE_LOCKS_REQUIRED(...) \ - __attribute__ ((exclusive_locks_required(__VA_ARGS__))) -#define SHARED_LOCKS_REQUIRED(...) \ - __attribute__ ((shared_locks_required(__VA_ARGS__))) -#define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis)) - - -class __attribute__((lockable)) Mutex { +#define LOCKABLE __attribute__((lockable)) +#define SCOPED_LOCKABLE __attribute__((scoped_lockable)) +#define GUARDED_BY(x) __attribute__((guarded_by(x))) +#define GUARDED_VAR __attribute__((guarded_var)) +#define PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x))) +#define PT_GUARDED_VAR __attribute__((pt_guarded_var)) +#define ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__))) +#define ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__))) +#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((exclusive_lock_function(__VA_ARGS__))) +#define SHARED_LOCK_FUNCTION(...) __attribute__((shared_lock_function(__VA_ARGS__))) +#define ASSERT_EXCLUSIVE_LOCK(...) __attribute__((assert_exclusive_lock(__VA_ARGS__))) +#define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_lock(__VA_ARGS__))) +#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__))) +#define SHARED_TRYLOCK_FUNCTION(...) __attribute__((shared_trylock_function(__VA_ARGS__))) +#define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) +#define EXCLUSIVE_UNLOCK_FUNCTION(...) __attribute__((release_capability(__VA_ARGS__))) +#define SHARED_UNLOCK_FUNCTION(...) __attribute__((release_shared_capability(__VA_ARGS__))) +#define LOCK_RETURNED(x) __attribute__((lock_returned(x))) +#define LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__))) +#define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((exclusive_locks_required(__VA_ARGS__))) +#define SHARED_LOCKS_REQUIRED(...) __attribute__((shared_locks_required(__VA_ARGS__))) +#define NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) + + +class LOCKABLE Mutex { public: void Lock() __attribute__((exclusive_lock_function)); void ReaderLock() __attribute__((shared_lock_function)); @@ -43,16 +43,18 @@ class __attribute__((lockable)) Mutex { void AssertReaderHeld() ASSERT_SHARED_LOCK(); }; -class __attribute__((scoped_lockable)) MutexLock { +class SCOPED_LOCKABLE MutexLock { public: - MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu))); - ~MutexLock() __attribute__((unlock_function)); + MutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu); + MutexLock(Mutex *mu, bool adopt) EXCLUSIVE_LOCKS_REQUIRED(mu); + ~MutexLock() UNLOCK_FUNCTION(); }; -class __attribute__((scoped_lockable)) ReaderMutexLock { +class SCOPED_LOCKABLE ReaderMutexLock { public: - ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu))); - ~ReaderMutexLock() __attribute__((unlock_function)); + ReaderMutexLock(Mutex *mu) SHARED_LOCK_FUNCTION(mu); + ReaderMutexLock(Mutex *mu, bool adopt) SHARED_LOCKS_REQUIRED(mu); + ~ReaderMutexLock() UNLOCK_FUNCTION(); }; class SCOPED_LOCKABLE ReleasableMutexLock { @@ -4835,7 +4837,7 @@ public: read2(10, *foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}} destroy(mymove(*foosp)); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}} - // TODO -- these requires better smart pointer handling. + // TODO -- these require better smart pointer handling. copy(*foosp.get()); write1(*foosp.get()); write2(10, *foosp.get()); @@ -4848,3 +4850,244 @@ public: } // end namespace PassByRefTest + +namespace AcquiredBeforeAfterText { + +class Foo { + Mutex mu1 ACQUIRED_BEFORE(mu2, mu3); + Mutex mu2; + Mutex mu3; + + void test1() { + mu1.Lock(); + mu2.Lock(); + mu3.Lock(); + + mu3.Unlock(); + mu2.Unlock(); + mu1.Unlock(); + } + + void test2() { + mu2.Lock(); + mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}} + mu1.Unlock(); + mu2.Unlock(); + } + + void test3() { + mu3.Lock(); + mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}} + mu1.Unlock(); + mu3.Unlock(); + } + + void test4() EXCLUSIVE_LOCKS_REQUIRED(mu1) { + mu2.Lock(); + mu2.Unlock(); + } + + void test5() EXCLUSIVE_LOCKS_REQUIRED(mu2) { + mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}} + mu1.Unlock(); + } + + void test6() EXCLUSIVE_LOCKS_REQUIRED(mu2) { + mu1.AssertHeld(); + } + + void test7() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2, mu3) { } + + void test8() EXCLUSIVE_LOCKS_REQUIRED(mu3, mu2, mu1) { } +}; + + +class Foo2 { + Mutex mu1; + Mutex mu2 ACQUIRED_AFTER(mu1); + Mutex mu3 ACQUIRED_AFTER(mu1); + + void test1() { + mu1.Lock(); + mu2.Lock(); + mu3.Lock(); + + mu3.Unlock(); + mu2.Unlock(); + mu1.Unlock(); + } + + void test2() { + mu2.Lock(); + mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}} + mu1.Unlock(); + mu2.Unlock(); + } + + void test3() { + mu3.Lock(); + mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}} + mu1.Unlock(); + mu3.Unlock(); + } +}; + + +class Foo3 { + Mutex mu1 ACQUIRED_BEFORE(mu2); + Mutex mu2; + Mutex mu3 ACQUIRED_AFTER(mu2) ACQUIRED_BEFORE(mu4); + Mutex mu4; + + void test1() { + mu1.Lock(); + mu2.Lock(); + mu3.Lock(); + mu4.Lock(); + + mu4.Unlock(); + mu3.Unlock(); + mu2.Unlock(); + mu1.Unlock(); + } + + void test2() { + mu4.Lock(); + mu2.Lock(); // expected-warning {{mutex 'mu2' must be acquired before 'mu4'}} + + mu2.Unlock(); + mu4.Unlock(); + } + + void test3() { + mu4.Lock(); + mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu4'}} + + mu1.Unlock(); + mu4.Unlock(); + } + + void test4() { + mu3.Lock(); + mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}} + + mu1.Unlock(); + mu3.Unlock(); + } +}; + + +// Test transitive DAG traversal with AFTER +class Foo4 { + Mutex mu1; + Mutex mu2 ACQUIRED_AFTER(mu1); + Mutex mu3 ACQUIRED_AFTER(mu1); + Mutex mu4 ACQUIRED_AFTER(mu2, mu3); + Mutex mu5 ACQUIRED_AFTER(mu4); + Mutex mu6 ACQUIRED_AFTER(mu4); + Mutex mu7 ACQUIRED_AFTER(mu5, mu6); + Mutex mu8 ACQUIRED_AFTER(mu7); + + void test() { + mu8.Lock(); + mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}} + mu1.Unlock(); + mu8.Unlock(); + } +}; + + +// Test transitive DAG traversal with BEFORE +class Foo5 { + Mutex mu1 ACQUIRED_BEFORE(mu2, mu3); + Mutex mu2 ACQUIRED_BEFORE(mu4); + Mutex mu3 ACQUIRED_BEFORE(mu4); + Mutex mu4 ACQUIRED_BEFORE(mu5, mu6); + Mutex mu5 ACQUIRED_BEFORE(mu7); + Mutex mu6 ACQUIRED_BEFORE(mu7); + Mutex mu7 ACQUIRED_BEFORE(mu8); + Mutex mu8; + + void test() { + mu8.Lock(); + mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}} + mu1.Unlock(); + mu8.Unlock(); + } +}; + + +class Foo6 { + Mutex mu1 ACQUIRED_AFTER(mu3); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu1'}} + Mutex mu2 ACQUIRED_AFTER(mu1); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu2'}} + Mutex mu3 ACQUIRED_AFTER(mu2); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu3'}} + + Mutex mu_b ACQUIRED_BEFORE(mu_b); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_b'}} + Mutex mu_a ACQUIRED_AFTER(mu_a); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_a'}} + + void test0() { + mu_a.Lock(); + mu_b.Lock(); + mu_b.Unlock(); + mu_a.Unlock(); + } + + void test1a() { + mu1.Lock(); + mu1.Unlock(); + } + + void test1b() { + mu1.Lock(); + mu_a.Lock(); + mu_b.Lock(); + mu_b.Unlock(); + mu_a.Unlock(); + mu1.Unlock(); + } + + void test() { + mu2.Lock(); + mu2.Unlock(); + } + + void test3() { + mu3.Lock(); + mu3.Unlock(); + } +}; + +} // end namespace AcquiredBeforeAfterTest + + +namespace ScopedAdoptTest { + +class Foo { + Mutex mu; + int a GUARDED_BY(mu); + int b; + + void test1() EXCLUSIVE_UNLOCK_FUNCTION(mu) { + MutexLock slock(&mu, true); + a = 0; + } + + void test2() SHARED_UNLOCK_FUNCTION(mu) { + ReaderMutexLock slock(&mu, true); + b = a; + } + + void test3() EXCLUSIVE_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}} + MutexLock slock(&mu, true); + a = 0; + } // expected-warning {{expecting mutex 'mu' to be held at the end of function}} + + void test4() SHARED_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}} + ReaderMutexLock slock(&mu, true); + b = a; + } // expected-warning {{expecting mutex 'mu' to be held at the end of function}} + +}; + +} // end namespace ScopedAdoptTest + diff --git a/test/SemaCXX/warn-unused-local-typedef-serialize.cpp b/test/SemaCXX/warn-unused-local-typedef-serialize.cpp index aa2c48b..ccb5a09 100644 --- a/test/SemaCXX/warn-unused-local-typedef-serialize.cpp +++ b/test/SemaCXX/warn-unused-local-typedef-serialize.cpp @@ -1,3 +1,4 @@ +// XFAIL: hexagon // RUN: %clang -x c++-header -c -Wunused-local-typedef %s -o %t.gch -Werror // RUN: %clang -DBE_THE_SOURCE -c -Wunused-local-typedef -include %t %s -o /dev/null 2>&1 | FileCheck %s // RUN: %clang -DBE_THE_SOURCE -c -Wunused-local-typedef -include %t %s -o /dev/null 2>&1 | FileCheck %s diff --git a/test/SemaCXX/warn-unused-result.cpp b/test/SemaCXX/warn-unused-result.cpp index 7bdb424..01bc457 100644 --- a/test/SemaCXX/warn-unused-result.cpp +++ b/test/SemaCXX/warn-unused-result.cpp @@ -44,6 +44,12 @@ void bah() { } namespace warn_unused_CXX11 { +class Status; +class Foo { + public: + Status doStuff(); +}; + struct [[clang::warn_unused_result]] Status { bool ok() const; Status& operator=(const Status& x); @@ -73,10 +79,23 @@ void lazy() { (void)DoYetAnotherThing(); DoSomething(); // expected-warning {{ignoring return value}} - DoSomethingElse(); // expected-warning {{ignoring return value}} - DoAnotherThing(); // expected-warning {{ignoring return value}} + DoSomethingElse(); + DoAnotherThing(); DoYetAnotherThing(); } + +template <typename T> +class [[clang::warn_unused_result]] StatusOr { +}; +StatusOr<int> doit(); +void test() { + Foo f; + f.doStuff(); // expected-warning {{ignoring return value}} + doit(); // expected-warning {{ignoring return value}} + + auto func = []() { return Status(); }; + func(); // expected-warning {{ignoring return value}} +} } namespace PR17587 { diff --git a/test/SemaCXX/warn-weak-vtables.cpp b/test/SemaCXX/warn-weak-vtables.cpp index 671ff29..d306653 100644 --- a/test/SemaCXX/warn-weak-vtables.cpp +++ b/test/SemaCXX/warn-weak-vtables.cpp @@ -20,15 +20,14 @@ void f() { virtual void f() { } }; - A *a; - a->f(); + A a; } // Use the vtables -void uses(A &a, B<int> &b, C &c) { - a.f(); - b.f(); - c.f(); +void uses_abc() { + A a; + B<int> b; + C c; } // <rdar://problem/9979458> @@ -52,10 +51,9 @@ public: Parent::~Parent() {} -void uses(Parent &p, Derived &d, VeryDerived &vd) { - p.getFoo(); - d.getFoo(); - vd.getFoo(); +void uses_derived() { + Derived d; + VeryDerived vd; } template<typename T> struct TemplVirt { @@ -72,8 +70,8 @@ template<> struct TemplVirt<long> { // expected-warning{{'TemplVirt<long>' has n virtual void f() {} }; -void uses(TemplVirt<float>& f, TemplVirt<bool>& b, TemplVirt<long>& l) { - f.f(); - b.f(); - l.f(); +void uses_templ() { + TemplVirt<float> f; + TemplVirt<bool> b; + TemplVirt<long> l; } |