diff options
Diffstat (limited to 'test/SemaCXX')
100 files changed, 3181 insertions, 184 deletions
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp index 6b43ea205af3..449e24b03b68 100644 --- a/test/SemaCXX/MicrosoftExtensions.cpp +++ b/test/SemaCXX/MicrosoftExtensions.cpp @@ -204,3 +204,7 @@ struct PR11150 { void f() { int __except = 0; } void ::f(); // expected-warning{{extra qualification on member 'f'}} + +class C { + C::C(); // expected-warning{{extra qualification on member 'C'}} +}; diff --git a/test/SemaCXX/address-of-temporary.cpp b/test/SemaCXX/address-of-temporary.cpp index bb6cba3187f5..5eef1c5521c4 100644 --- a/test/SemaCXX/address-of-temporary.cpp +++ b/test/SemaCXX/address-of-temporary.cpp @@ -15,8 +15,13 @@ namespace PointerToArrayDecay { struct Y { int a[4]; }; + struct Z { + int n; + ~Z(); + }; typedef int A[4]; + typedef Z AZ[4]; template<typename T> void consume(T); struct S { int *p; }; @@ -25,11 +30,13 @@ namespace PointerToArrayDecay { void g1() { int *p = Y{}.a; } // expected-warning{{pointer is initialized by a temporary array}} void g2() { int *p = A{}; } // expected-warning{{pointer is initialized by a temporary array}} void g3() { int *p = (A){}; } // expected-warning{{pointer is initialized by a temporary array}} + void g4() { Z *p = AZ{}; } // expected-warning{{pointer is initialized by a temporary array}} void h0() { consume(Y().a); } void h1() { consume(Y{}.a); } void h2() { consume(A{}); } void h3() { consume((A){}); } + void h4() { consume(AZ{}); } void i0() { S s = { Y().a }; } // expected-warning{{pointer is initialized by a temporary array}} void i1() { S s = { Y{}.a }; } // expected-warning{{pointer is initialized by a temporary array}} diff --git a/test/SemaCXX/address-of.cpp b/test/SemaCXX/address-of.cpp index 69fcaff8f1ed..373e44c17eda 100644 --- a/test/SemaCXX/address-of.cpp +++ b/test/SemaCXX/address-of.cpp @@ -22,12 +22,12 @@ enum E { }; void test() { - (void)&Enumerator; // expected-error{{address expression must be an lvalue or a function designator}} + (void)&Enumerator; // expected-error{{cannot take the address of an rvalue of type 'E'}} } template<int N> void test2() { - (void)&N; // expected-error{{address expression must be an lvalue or a function designator}} + (void)&N; // expected-error{{cannot take the address of an rvalue of type 'int'}} } // PR clang/3222 @@ -41,6 +41,14 @@ struct PR11066 { }; void PR11066::test() { - int (PR11066::*ptr)(int) = & &PR11066::foo; // expected-error{{address expression must be an lvalue or a function designator}} + int (PR11066::*ptr)(int) = & &PR11066::foo; // expected-error{{extra '&' taking address of overloaded function}} } +namespace test3 { + // emit no error + template<typename T> struct S { + virtual void f() = 0; + }; + template<typename T> void S<T>::f() { T::error; } + void (S<int>::*p)() = &S<int>::f; +} diff --git a/test/SemaCXX/address-space-initialize.cpp b/test/SemaCXX/address-space-initialize.cpp new file mode 100644 index 000000000000..50913384c5cf --- /dev/null +++ b/test/SemaCXX/address-space-initialize.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +__attribute__((address_space(42))) +const float withc = 1.0f; + +__attribute__((address_space(42))) +volatile float withv = 1.0f; + +__attribute__((address_space(42))) +float nocv = 1.0f; + +__attribute__((address_space(42))) +float nocv_array[10] = { 1.0f }; + +__attribute__((address_space(42))) +int nocv_iarray[10] = { 4 }; + + +__attribute__((address_space(9999))) +int* as_ptr = nocv_iarray; // expected-error{{cannot initialize a variable of type '__attribute__((address_space(9999))) int *' with an lvalue of type '__attribute__((address_space(42))) int [10]'}} + + +__attribute__((address_space(42))) int* __attribute__((address_space(42))) ptr_in_same_addr_space = nocv_iarray; +__attribute__((address_space(42))) int* __attribute__((address_space(999))) ptr_in_different_addr_space = nocv_iarray; + diff --git a/test/SemaCXX/alias-template.cpp b/test/SemaCXX/alias-template.cpp index 4bf79f851e0b..db9c82afd598 100644 --- a/test/SemaCXX/alias-template.cpp +++ b/test/SemaCXX/alias-template.cpp @@ -105,9 +105,7 @@ namespace TagName { template<typename Z> using S = struct { int n; }; // expected-error {{can not be defined}} template<typename Z> using T = class { int n; }; // expected-error {{can not be defined}} template<typename Z> using U = enum { a, b, c }; // expected-error {{can not be defined}} - template<typename Z> using V = struct V { int n; }; // expected-error {{redefinition of 'V' as different kind of symbol}} \ - expected-error {{'TagName::V' can not be defined in a type alias template}} \ - expected-note {{previous definition is here}} + template<typename Z> using V = struct V { int n; }; // expected-error {{'TagName::V' can not be defined in a type alias template}} } namespace StdExample { diff --git a/test/SemaCXX/alignof-sizeof-reference.cpp b/test/SemaCXX/alignof-sizeof-reference.cpp index ccdf45e52dd7..d76fcf55c2d8 100644 --- a/test/SemaCXX/alignof-sizeof-reference.cpp +++ b/test/SemaCXX/alignof-sizeof-reference.cpp @@ -4,8 +4,10 @@ struct s0; // expected-note {{forward declaration}} char ar[sizeof(s0&)]; // expected-error {{invalid application of 'sizeof' to an incomplete type}} void test() { char &r = ar[0]; - static_assert(alignof(r) == 1, "bad alignment"); + static_assert(alignof(r) == 1, "bad alignment"); // expected-warning {{GNU extension}} + static_assert(alignof(char&) == 1, "bad alignment"); static_assert(sizeof(r) == 1, "bad size"); + static_assert(sizeof(char&) == 1, "bad size"); } void f(); // expected-note{{possible target for call}} @@ -18,5 +20,5 @@ void g() { template<typename T> void f_template(); // expected-note{{possible target for call}} template<typename T> void f_template(T*); // expected-note{{possible target for call}} void rdar9659191() { - (void)alignof(f_template<int>); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}} + (void)alignof(f_template<int>); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}} expected-warning {{GNU extension}} } diff --git a/test/SemaCXX/altivec.cpp b/test/SemaCXX/altivec.cpp index 9de1f04b697c..351746617757 100644 --- a/test/SemaCXX/altivec.cpp +++ b/test/SemaCXX/altivec.cpp @@ -62,7 +62,7 @@ void test2() vector float vf; vf++; - ++vi=vi; + ++vi=vi; // expected-warning {{unsequenced}} (++vi)[1]=1; template_f(vi); } diff --git a/test/SemaCXX/anonymous-struct.cpp b/test/SemaCXX/anonymous-struct.cpp index 19a88d739acd..8a61041463ba 100644 --- a/test/SemaCXX/anonymous-struct.cpp +++ b/test/SemaCXX/anonymous-struct.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s struct S { - S(); // expected-note {{because type 'S' has a user-declared constructor}} + S(); // expected-note {{because type 'S' has a user-provided default constructor}} }; struct { // expected-error {{anonymous structs and classes must be class members}} @@ -9,7 +9,7 @@ struct { // expected-error {{anonymous structs and classes must be class members struct E { struct { - S x; // expected-error {{anonymous struct member 'x' has a non-trivial constructor}} + S x; // expected-error {{anonymous struct member 'x' has a non-trivial constructor}} }; static struct { }; diff --git a/test/SemaCXX/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp index 2dd7ab86a88d..9c2cf24a83fc 100644 --- a/test/SemaCXX/anonymous-union.cpp +++ b/test/SemaCXX/anonymous-union.cpp @@ -9,7 +9,7 @@ struct X { int i; float f; - union { + union { // expected-warning{{anonymous types declared in an anonymous union are an extension}} float f2; mutable double d; }; @@ -101,7 +101,7 @@ void g() { struct BadMembers { union { struct X { }; // expected-error {{types cannot be declared in an anonymous union}} - struct { int x; int y; } y; + struct { int x; int y; } y; // expected-warning{{anonymous types declared in an anonymous union are an extension}} void f(); // expected-error{{functions cannot be declared in an anonymous union}} private: int x1; // expected-error{{anonymous union cannot contain a private data member}} @@ -110,7 +110,7 @@ struct BadMembers { }; // <rdar://problem/6481130> -typedef union { }; // expected-warning{{declaration does not declare anything}} +typedef union { }; // expected-warning{{typedef requires a name}} // <rdar://problem/7562438> typedef struct objc_module *Foo ; @@ -128,7 +128,7 @@ namespace test4 { struct { // expected-warning{{anonymous structs are a GNU extension}} int s0; // expected-note {{declared private here}} double s1; // expected-note {{declared private here}} - union { + union { // expected-warning{{anonymous types declared in an anonymous struct are an extension}} int su0; // expected-note {{declared private here}} double su1; // expected-note {{declared private here}} }; @@ -136,7 +136,7 @@ namespace test4 { union { int u0; // expected-note {{declared private here}} double u1; // expected-note {{declared private here}} - struct { // expected-warning{{anonymous structs are a GNU extension}} + struct { // expected-warning{{anonymous structs are a GNU extension}} expected-warning{{anonymous types declared in an anonymous union are an extension}} int us0; // expected-note {{declared private here}} double us1; // expected-note {{declared private here}} }; @@ -187,7 +187,7 @@ namespace PR8326 { private: const union { // expected-warning{{anonymous union cannot be 'const'}} - struct { // expected-warning{{anonymous structs are a GNU extension}} + struct { // expected-warning{{anonymous structs are a GNU extension}} expected-warning{{declared in an anonymous union}} T x; T y; }; diff --git a/test/SemaCXX/array-bound-merge.cpp b/test/SemaCXX/array-bound-merge.cpp index 8fb2ec52a9ee..c6085fb0a965 100644 --- a/test/SemaCXX/array-bound-merge.cpp +++ b/test/SemaCXX/array-bound-merge.cpp @@ -9,3 +9,6 @@ extern int c[1]; int c[] = {1,2}; // expected-error {{excess elements in array initializer}} int d[1][]; // expected-error {{array has incomplete element type 'int []'}} + +extern const int e[2]; // expected-note {{previous definition is here}} +int e[] = { 1 }; // expected-error {{redefinition of 'e' with a different type: 'int []' vs 'const int [2]'}} diff --git a/test/SemaCXX/array-bounds.cpp b/test/SemaCXX/array-bounds.cpp index 57a9e3de6a29..80b3ee428944 100644 --- a/test/SemaCXX/array-bounds.cpp +++ b/test/SemaCXX/array-bounds.cpp @@ -74,11 +74,11 @@ void test() { } template <int I> struct S { - char arr[I]; // expected-note 2 {{declared here}} + char arr[I]; // expected-note 3 {{declared here}} }; template <int I> void f() { S<3> s; - s.arr[4] = 0; // expected-warning {{array index 4 is past the end of the array (which contains 3 elements)}} + s.arr[4] = 0; // expected-warning 2 {{array index 4 is past the end of the array (which contains 3 elements)}} s.arr[I] = 0; // expected-warning {{array index 5 is past the end of the array (which contains 3 elements)}} } diff --git a/test/SemaCXX/ast-print.cpp b/test/SemaCXX/ast-print.cpp index aeb4039d597d..5de8c4b51b90 100644 --- a/test/SemaCXX/ast-print.cpp +++ b/test/SemaCXX/ast-print.cpp @@ -81,3 +81,59 @@ struct test9 E a = A; } }; + +namespace test10 { + namespace M { + template<typename T> + struct X { + enum { value }; + }; + } +} + +typedef int INT; + +// CHECK: test11 +// CHECK-NEXT: return test10::M::X<INT>::value; +int test11() { + return test10::M::X<INT>::value; +} + + +struct DefaultArgClass +{ + DefaultArgClass(int a = 1) {} +}; + +struct NoArgClass +{ + NoArgClass() {} +}; + +struct VirualDestrClass +{ + VirualDestrClass(int arg); + virtual ~VirualDestrClass(); +}; + +struct ConstrWithCleanupsClass +{ + ConstrWithCleanupsClass(const VirualDestrClass& cplx = VirualDestrClass(42)); +}; + +// CHECK: test12 +// CHECK-NEXT: DefaultArgClass useDefaultArg; +// CHECK-NEXT: DefaultArgClass overrideDefaultArg(1); +// CHECK-NEXT: NoArgClass noArg; +// CHECK-NEXT: ConstrWithCleanupsClass cwcNoArg; +// CHECK-NEXT: ConstrWithCleanupsClass cwcOverrideArg(48); +// CHECK-NEXT: ConstrWithCleanupsClass cwcExplicitArg(VirualDestrClass(56)); +void test12() { + DefaultArgClass useDefaultArg; + DefaultArgClass overrideDefaultArg(1); + NoArgClass noArg; + ConstrWithCleanupsClass cwcNoArg; + ConstrWithCleanupsClass cwcOverrideArg(48); + ConstrWithCleanupsClass cwcExplicitArg(VirualDestrClass(56)); +} + diff --git a/test/SemaCXX/atomic-type.cxx b/test/SemaCXX/atomic-type.cxx index 18707eb8c5ca..947bb3c5f406 100644 --- a/test/SemaCXX/atomic-type.cxx +++ b/test/SemaCXX/atomic-type.cxx @@ -1,7 +1,9 @@ -// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -verify -pedantic %s template<typename T> struct atomic { _Atomic(T) value; + + void f() _Atomic; // expected-error {{expected ';' at end of declaration list}} }; template<typename T> struct user { @@ -15,9 +17,11 @@ user<int> u; struct A { }; int &ovl1(_Atomic(int)); +int &ovl1(_Atomic int); // ok, redeclaration long &ovl1(_Atomic(long)); float &ovl1(_Atomic(float)); double &ovl1(_Atomic(A const *const *)); +double &ovl1(A const *const *_Atomic); short &ovl1(_Atomic(A **)); void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af, @@ -33,3 +37,22 @@ void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af, double &dr2 = ovl1(ac); short &sr1 = ovl1(a); } + +typedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}} + +typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int; +typedef int(A::*_Atomic atomic_mem_ptr_to_int); + +typedef _Atomic(int)(A::*mem_ptr_to_atomic_int); +typedef _Atomic int(A::*mem_ptr_to_atomic_int); + +typedef _Atomic(int)&atomic_int_ref; +typedef _Atomic int &atomic_int_ref; +typedef _Atomic atomic_int_ref atomic_int_ref; // ok, qualifiers on references ignored in this case. + +typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}} +typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}} + +struct S { + _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}} +}; diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp index 4281895f40ed..e9276cd2d9ee 100644 --- a/test/SemaCXX/attr-cxx0x.cpp +++ b/test/SemaCXX/attr-cxx0x.cpp @@ -1,32 +1,47 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -pedantic -std=c++11 %s int align_illegal alignas(3); //expected-error {{requested alignment is not a power of 2}} char align_big alignas(int); -int align_small alignas(1); // FIXME: this should be rejected +int align_small alignas(1); // expected-error {{requested alignment is less than minimum}} int align_multiple alignas(1) alignas(8) alignas(1); +alignas(4) int align_before; struct align_member { int member alignas(8); + int bitfield alignas(1) : 1; // expected-error {{}} }; +void f(alignas(1) char c) { // expected-error {{'alignas' attribute cannot be applied to a function parameter}} + alignas(1) register char k; // expected-error {{'alignas' attribute cannot be applied to a variable with 'register' storage class}} + try { + } catch (alignas(4) int n) { // expected-error {{'alignas' attribute cannot be applied to a 'catch' variable}} + } +} + + template <unsigned A> struct alignas(A) align_class_template {}; -// FIXME: these should not error -template <typename... T> alignas(T...) struct align_class_temp_pack_type {}; // expected-error{{pack expansions in alignment specifiers are not supported yet}} -template <unsigned... A> alignas(A...) struct align_class_temp_pack_expr {}; // expected-error{{pack expansions in alignment specifiers are not supported yet}} +template <typename... T> struct alignas(T...) align_class_temp_pack_type {}; +template <unsigned... A> struct alignas(A...) align_class_temp_pack_expr {}; +struct alignas(int...) alignas_expansion_no_packs {}; // expected-error {{pack expansion does not contain any unexpanded parameter packs}} +template <typename... A> struct outer { + template <typename... B> struct alignas(alignof(A) * alignof(B)...) inner {}; + // expected-error@-1 {{pack expansion contains parameter packs 'A' and 'B' that have different lengths (1 vs. 2)}} +}; +outer<int>::inner<short, double> mismatched_packs; // expected-note {{in instantiation of}} -typedef char align_typedef alignas(8); -template<typename T> using align_alias_template = align_typedef; +typedef char align_typedef alignas(8); // expected-error {{'alignas' attribute only applies to variables, data members and tag types}} +template<typename T> using align_alias_template = align_typedef alignas(8); // expected-error {{'alignas' attribute cannot be applied to types}} -static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong"); -static_assert(alignof(align_small) == 1, "j's alignment is wrong"); -static_assert(alignof(align_multiple) == 8, "l's alignment is wrong"); +static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong"); // expected-warning{{'alignof' applied to an expression is a GNU extension}} +static_assert(alignof(align_small) == 1, "j's alignment is wrong"); // expected-warning{{'alignof' applied to an expression is a GNU extension}} +static_assert(alignof(align_multiple) == 8, "l's alignment is wrong"); // expected-warning{{'alignof' applied to an expression is a GNU extension}} static_assert(alignof(align_member) == 8, "quuux's alignment is wrong"); static_assert(sizeof(align_member) == 8, "quuux's size is wrong"); -static_assert(alignof(align_typedef) == 8, "typedef's alignment is wrong"); static_assert(alignof(align_class_template<8>) == 8, "template's alignment is wrong"); static_assert(alignof(align_class_template<16>) == 16, "template's alignment is wrong"); -// FIXME: enable these tests -// static_assert(alignof(align_class_temp_pack_type<short, int, long>) == alignof(long), "template's alignment is wrong"); -// static_assert(alignof(align_class_temp_pack_expr<8, 16, 32>) == 32, "template's alignment is wrong"); -static_assert(alignof(align_alias_template<int>) == 8, "alias template's alignment is wrong"); +static_assert(alignof(align_class_temp_pack_type<short, int, long>) == alignof(long), "template's alignment is wrong"); +static_assert(alignof(align_class_temp_pack_expr<8, 16, 32>) == 32, "template's alignment is wrong"); +static_assert(alignof(outer<int,char>::inner<double,short>) == alignof(int) * alignof(double), "template's alignment is wrong"); + +static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-warning{{invalid application of 'alignof' to a function type}} diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp index f3d818a75f35..d09faf34d7a5 100644 --- a/test/SemaCXX/attr-deprecated.cpp +++ b/test/SemaCXX/attr-deprecated.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -verify -fsyntax-only +// RUN: %clang_cc1 %s -verify -fexceptions class A { void f() __attribute__((deprecated)); // expected-note 2 {{declared here}} void g(A* a); @@ -233,3 +233,14 @@ namespace test6 { x = D<int>::d1; // expected-warning {{'d1' is deprecated}} } } + +namespace test7 { + struct X { + void* operator new(typeof(sizeof(void*))) __attribute__((deprecated)); // expected-note{{'operator new' declared here}} + void operator delete(void *) __attribute__((deprecated)); // expected-note{{'operator delete' declared here}} + }; + + void test() { + X *x = new X; // expected-warning{{'operator new' is deprecated}} expected-warning{{'operator delete' is deprecated}} + } +} diff --git a/test/SemaCXX/attr-no-sanitize-address.cpp b/test/SemaCXX/attr-no-sanitize-address.cpp new file mode 100644 index 000000000000..dc4d79758c16 --- /dev/null +++ b/test/SemaCXX/attr-no-sanitize-address.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#define NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) + +#if !__has_attribute(no_sanitize_address) +#error "Should support no_sanitize_address" +#endif + +void noanal_fun() NO_SANITIZE_ADDRESS; + +void noanal_fun_args() __attribute__((no_sanitize_address(1))); // \ + // expected-error {{attribute takes no arguments}} + +int noanal_testfn(int y) NO_SANITIZE_ADDRESS; + +int noanal_testfn(int y) { + int x NO_SANITIZE_ADDRESS = y; // \ + // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}} + return x; +} + +int noanal_test_var NO_SANITIZE_ADDRESS; // \ + // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}} + +class NoanalFoo { + private: + int test_field NO_SANITIZE_ADDRESS; // \ + // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}} + void test_method() NO_SANITIZE_ADDRESS; +}; + +class NO_SANITIZE_ADDRESS NoanalTestClass { // \ + // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}} +}; + +void noanal_fun_params(int lvar NO_SANITIZE_ADDRESS); // \ + // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}} diff --git a/test/SemaCXX/attr-no-sanitize-memory.cpp b/test/SemaCXX/attr-no-sanitize-memory.cpp new file mode 100644 index 000000000000..84acdaca838f --- /dev/null +++ b/test/SemaCXX/attr-no-sanitize-memory.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#define NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) + +#if !__has_attribute(no_sanitize_memory) +#error "Should support no_sanitize_memory" +#endif + +void noanal_fun() NO_SANITIZE_MEMORY; + +void noanal_fun_args() __attribute__((no_sanitize_memory(1))); // \ + // expected-error {{attribute takes no arguments}} + +int noanal_testfn(int y) NO_SANITIZE_MEMORY; + +int noanal_testfn(int y) { + int x NO_SANITIZE_MEMORY = y; // \ + // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}} + return x; +} + +int noanal_test_var NO_SANITIZE_MEMORY; // \ + // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}} + +class NoanalFoo { + private: + int test_field NO_SANITIZE_MEMORY; // \ + // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}} + void test_method() NO_SANITIZE_MEMORY; +}; + +class NO_SANITIZE_MEMORY NoanalTestClass { // \ + // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}} +}; + +void noanal_fun_params(int lvar NO_SANITIZE_MEMORY); // \ + // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}} diff --git a/test/SemaCXX/attr-no-sanitize-thread.cpp b/test/SemaCXX/attr-no-sanitize-thread.cpp new file mode 100644 index 000000000000..50960c42b931 --- /dev/null +++ b/test/SemaCXX/attr-no-sanitize-thread.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#define NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) + +#if !__has_attribute(no_sanitize_thread) +#error "Should support no_sanitize_thread" +#endif + +void noanal_fun() NO_SANITIZE_THREAD; + +void noanal_fun_args() __attribute__((no_sanitize_thread(1))); // \ + // expected-error {{attribute takes no arguments}} + +int noanal_testfn(int y) NO_SANITIZE_THREAD; + +int noanal_testfn(int y) { + int x NO_SANITIZE_THREAD = y; // \ + // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}} + return x; +} + +int noanal_test_var NO_SANITIZE_THREAD; // \ + // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}} + +class NoanalFoo { + private: + int test_field NO_SANITIZE_THREAD; // \ + // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}} + void test_method() NO_SANITIZE_THREAD; +}; + +class NO_SANITIZE_THREAD NoanalTestClass { // \ + // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}} +}; + +void noanal_fun_params(int lvar NO_SANITIZE_THREAD); // \ + // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}} diff --git a/test/SemaCXX/attr-nonnull.cpp b/test/SemaCXX/attr-nonnull.cpp index 09c054c19770..8af49d9d29e6 100644 --- a/test/SemaCXX/attr-nonnull.cpp +++ b/test/SemaCXX/attr-nonnull.cpp @@ -31,3 +31,24 @@ namespace rdar8769025 { f2(0, 0); // expected-warning{{null passed to a callee which requires a non-null argument}} } } + +namespace test3 { +__attribute__((nonnull(1))) void f(void *ptr); + +void g() { + f(static_cast<char*>((void*)0)); // expected-warning{{null passed}} + f(static_cast<char*>(0)); // expected-warning{{null passed}} +} +} + +namespace test4 { +struct X { + bool operator!=(const void *) const __attribute__((nonnull(2))); +}; +bool operator==(const X&, const void *) __attribute__((nonnull(2))); + +void test(const X& x) { + (void)(x == 0); // expected-warning{{null passed}} + (void)(x != 0); // expected-warning{{null passed}} +} +} diff --git a/test/SemaCXX/attr-print.cpp b/test/SemaCXX/attr-print.cpp new file mode 100644 index 000000000000..2e7478904f12 --- /dev/null +++ b/test/SemaCXX/attr-print.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -ast-print -fms-extensions | FileCheck %s + +// CHECK: int x __attribute__((aligned(4))); +int x __attribute__((aligned(4))); + +// FIXME: Print this at a valid location for a __declspec attr. +// CHECK: int y __declspec(align(4)); +__declspec(align(4)) int y; + +// CHECK: void foo() __attribute__((const)); +void foo() __attribute__((const)); + +// CHECK: void bar() __attribute__((__const)); +void bar() __attribute__((__const)); + +// FIXME: Print this with correct format and order. +// CHECK: void foo1() __attribute__((pure)) __attribute__((noinline)); +void foo1() __attribute__((noinline, pure)); diff --git a/test/SemaCXX/attr-regparm.cpp b/test/SemaCXX/attr-regparm.cpp index 91ee613be186..92e651bd5eeb 100644 --- a/test/SemaCXX/attr-regparm.cpp +++ b/test/SemaCXX/attr-regparm.cpp @@ -11,5 +11,5 @@ struct X0 { void X0::f0() { } void __attribute__((regparm(3))) X0::f1() { } -void __attribute__((regparm(2))) X0::f2() { } // expected-error{{function declared with with regparm(2) attribute was previously declared with the regparm(3) attribute}} -void __attribute__((regparm(2))) X0::f3() { } // expected-error{{function declared with with regparm(2) attribute was previously declared without the regparm attribute}} +void __attribute__((regparm(2))) X0::f2() { } // expected-error{{function declared with regparm(2) attribute was previously declared with the regparm(3) attribute}} +void __attribute__((regparm(2))) X0::f3() { } // expected-error{{function declared with regparm(2) attribute was previously declared without the regparm attribute}} diff --git a/test/SemaCXX/attr-weak.cpp b/test/SemaCXX/attr-weak.cpp index b6a9e0aa840c..8939a28d75e1 100644 --- a/test/SemaCXX/attr-weak.cpp +++ b/test/SemaCXX/attr-weak.cpp @@ -21,9 +21,16 @@ namespace { }; } +// GCC rejects the instantiation with the internal type, but some existing +// code expects it. It is also not that different from giving hidden visibility +// to parts of a template that have explicit default visibility, so we accept +// this. template <class T> struct Test7 { void test7() __attribute__((weak)) {} + static int var __attribute__((weak)); }; +template <class T> +int Test7<T>::var; namespace { class Internal; } template struct Test7<Internal>; template struct Test7<int>; diff --git a/test/SemaCXX/attr-weakref.cpp b/test/SemaCXX/attr-weakref.cpp index a34579198fef..f3d7a6241c91 100644 --- a/test/SemaCXX/attr-weakref.cpp +++ b/test/SemaCXX/attr-weakref.cpp @@ -28,4 +28,7 @@ int a7() __attribute__((weakref ("f1"))); // expected-error {{weakref declaratio int a8 __attribute__((weakref ("v1"))); // expected-error {{weakref declaration must have internal linkage}} // gcc accepts this -int a9 __attribute__((weakref)); // expected-error {{weakref declaration must have internal linkage}} +int a9 __attribute__((weakref)); // expected-error {{weakref declaration of 'a9' must also have an alias attribute}} + +static int a10(); +int a10() __attribute__((weakref ("foo"))); diff --git a/test/SemaCXX/auto-pragma.cpp b/test/SemaCXX/auto-pragma.cpp new file mode 100644 index 000000000000..1cd0781fe9a7 --- /dev/null +++ b/test/SemaCXX/auto-pragma.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -ast-dump -ast-dump-filter AutoVar | FileCheck %s + +namespace { + class foo { + }; +} + +#pragma GCC visibility push(hidden) +auto AutoVar = foo(); + +// CHECK: VarDecl {{.*}} AutoVar +// CHECK-NOT: VisibilityAttr diff --git a/test/SemaCXX/blocks.cpp b/test/SemaCXX/blocks.cpp index 3f81c274d04f..a2672d13b72d 100644 --- a/test/SemaCXX/blocks.cpp +++ b/test/SemaCXX/blocks.cpp @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks -// expected-no-diagnostics +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fblocks void tovoid(void*); @@ -69,3 +68,35 @@ namespace radar8382559 { return hasProperty = 1; } } + +// Move __block variables to the heap when possible. +class MoveOnly { +public: + MoveOnly(); + MoveOnly(const MoveOnly&) = delete; + MoveOnly(MoveOnly&&); +}; + +void move_block() { + __block MoveOnly mo; +} + +// Don't crash after failing to build a block due to a capture of an +// invalid declaration. +namespace test5 { + struct B { // expected-note 2 {{candidate constructor}} + void *p; + B(int); // expected-note {{candidate constructor}} + }; + + void use_block(void (^)()); + void use_block_2(void (^)(), const B &a); + + void test() { + B x; // expected-error {{no matching constructor for initialization}} + use_block(^{ + int y; + use_block_2(^{ (void) y; }, x); + }); + } +} diff --git a/test/SemaCXX/borland-extensions.cpp b/test/SemaCXX/borland-extensions.cpp index 1e4bd45612fd..d214473031e0 100644 --- a/test/SemaCXX/borland-extensions.cpp +++ b/test/SemaCXX/borland-extensions.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -fborland-extensions -// expected-no-diagnostics +// RUN: %clang_cc1 %s -fsyntax-only -fborland-extensions -triple x86_64-linux-gnu -verify +// RUN: %clang_cc1 %s -fsyntax-only -fborland-extensions -triple i686-linux-gnu -Werror // Borland extensions @@ -7,15 +7,21 @@ int dummy_function() { return 0; } // 2. test __pascal +// expected-warning@+1 {{calling convention '_pascal' ignored for this target}} int _pascal f2(); +// expected-warning@+1 {{calling convention '__pascal' ignored for this target}} float __pascal gi2(int, int); +// expected-warning@+1 {{calling convention '__pascal' ignored for this target}} template<typename T> T g2(T (__pascal * const )(int, int)) { return 0; } struct M { + // expected-warning@+1 {{calling convention '__pascal' ignored for this target}} int __pascal addP(); + // expected-warning@+1 {{calling convention '__pascal' ignored for this target}} float __pascal subtractP(); }; +// expected-warning@+1 {{calling convention '__pascal' ignored for this target}} template<typename T> int h2(T (__pascal M::* const )()) { return 0; } void m2() { int i; float f; @@ -28,7 +34,9 @@ void m2() { // 3. test other calling conventions int _cdecl fa3(); +// expected-warning@+1 {{calling convention '_fastcall' ignored for this target}} int _fastcall fc3(); +// expected-warning@+1 {{calling convention '_stdcall' ignored for this target}} int _stdcall fd3(); // 4. test __uuidof() diff --git a/test/SemaCXX/builtins.cpp b/test/SemaCXX/builtins.cpp index 6b055cff640d..5d61690c16e5 100644 --- a/test/SemaCXX/builtins.cpp +++ b/test/SemaCXX/builtins.cpp @@ -20,3 +20,7 @@ template int equal<&__builtin_strcmp>(const char*, const char*); // expected-err void f2() { __builtin_isnan; // expected-error {{builtin functions must be directly called}} } + +// pr14895 +typedef __typeof(sizeof(int)) size_t; +extern "C" void *__builtin_alloca (size_t); diff --git a/test/SemaCXX/c99-variable-length-array-cxx11.cpp b/test/SemaCXX/c99-variable-length-array-cxx11.cpp new file mode 100644 index 000000000000..03cf28388d98 --- /dev/null +++ b/test/SemaCXX/c99-variable-length-array-cxx11.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wvla-extension %s +struct StillPOD { + StillPOD() = default; +}; + +struct StillPOD2 { + StillPOD np; +}; + +struct NonPOD { + NonPOD(int) {} +}; + +struct POD { + int x; + int y; +}; + +// We allow VLAs of POD types, only. +void vla(int N) { + int array1[N]; // expected-warning{{variable length arrays are a C99 feature}} + POD array2[N]; // expected-warning{{variable length arrays are a C99 feature}} + StillPOD array3[N]; // expected-warning{{variable length arrays are a C99 feature}} + StillPOD2 array4[N][3]; // expected-warning{{variable length arrays are a C99 feature}} + NonPOD array5[N]; // expected-error{{variable length array of non-POD element type 'NonPOD'}} +} diff --git a/test/SemaCXX/c99-variable-length-array.cpp b/test/SemaCXX/c99-variable-length-array.cpp index 7773c0849b4a..bb620c71fa07 100644 --- a/test/SemaCXX/c99-variable-length-array.cpp +++ b/test/SemaCXX/c99-variable-length-array.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wvla %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wvla-extension %s struct NonPOD { NonPOD(); }; @@ -64,8 +64,9 @@ X1<HasConstantValue> x1a; X1<HasNonConstantValue> x1b; // expected-note{{in instantiation of}} // Template argument deduction does not allow deducing a size from a VLA. +// FIXME: This diagnostic should make it clear that the two 'N's are different entities! template<typename T, unsigned N> -void accept_array(T (&array)[N]); // expected-note{{candidate template ignored: failed template argument deduction}} +void accept_array(T (&array)[N]); // expected-note{{candidate template ignored: could not match 'T [N]' against 'int [N]'}} void test_accept_array(int N) { int array[N]; // expected-warning{{variable length arrays are a C99 feature}} diff --git a/test/SemaCXX/class-base-member-init.cpp b/test/SemaCXX/class-base-member-init.cpp index e84e57b7471b..2cdca829ffb9 100644 --- a/test/SemaCXX/class-base-member-init.cpp +++ b/test/SemaCXX/class-base-member-init.cpp @@ -90,3 +90,11 @@ namespace test5 { } }; } + +namespace rdar13185264 { + class X { + X() : a(), // expected-note{{previous initialization is here}} + a() { } // expected-error{{multiple initializations given for non-static member 'a'}} + union { void *a; }; + }; +} diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp index 432069f60cc0..feb1ccb9a20d 100644 --- a/test/SemaCXX/compare.cpp +++ b/test/SemaCXX/compare.cpp @@ -1,7 +1,7 @@ // Force x86-64 because some of our heuristics are actually based // on integer sizes. -// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -pedantic -verify -Wsign-compare %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -pedantic -verify -Wsign-compare -std=c++11 %s int test0(long a, unsigned long b) { enum EnumA {A}; @@ -89,8 +89,8 @@ int test0(long a, unsigned long b) { // (C,b) (C == (unsigned long) b) + (C == (unsigned int) b) + - (C == (unsigned short) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned short' is always false}} - (C == (unsigned char) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned char' is always false}} + (C == (unsigned short) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always false}} + (C == (unsigned char) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always false}} ((long) C == b) + ((int) C == b) + ((short) C == b) + @@ -101,8 +101,8 @@ int test0(long a, unsigned long b) { ((signed char) C == (unsigned char) b) + (C < (unsigned long) b) + (C < (unsigned int) b) + - (C < (unsigned short) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned short' is always false}} - (C < (unsigned char) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned char' is always false}} + (C < (unsigned short) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always false}} + (C < (unsigned char) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always false}} ((long) C < b) + ((int) C < b) + ((short) C < b) + @@ -119,8 +119,8 @@ int test0(long a, unsigned long b) { (a == (unsigned char) C) + ((long) a == C) + ((int) a == C) + - ((short) a == C) + // expected-warning {{comparison of constant 65536 with expression of type 'short' is always false}} - ((signed char) a == C) + // expected-warning {{comparison of constant 65536 with expression of type 'signed char' is always false}} + ((short) a == C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always false}} + ((signed char) a == C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always false}} ((long) a == (unsigned long) C) + ((int) a == (unsigned int) C) + ((short) a == (unsigned short) C) + @@ -131,8 +131,8 @@ int test0(long a, unsigned long b) { (a < (unsigned char) C) + ((long) a < C) + ((int) a < C) + - ((short) a < C) + // expected-warning {{comparison of constant 65536 with expression of type 'short' is always true}} - ((signed char) a < C) + // expected-warning {{comparison of constant 65536 with expression of type 'signed char' is always true}} + ((short) a < C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always true}} + ((signed char) a < C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always true}} ((long) a < (unsigned long) C) + // expected-warning {{comparison of integers of different signs}} ((int) a < (unsigned int) C) + // expected-warning {{comparison of integers of different signs}} ((short) a < (unsigned short) C) + @@ -223,3 +223,135 @@ void test3() { (void) (true ? b : a); (void) (true ? (unsigned char)b : (signed char)a); } + +// Test comparison of short to unsigned. If tautological compare does not +// trigger, then the signed comparision warning will. +void test4(short s) { + // A is max short plus 1. All zero and positive shorts are smaller than it. + // All negative shorts are cast towards the max unsigned range. Relation + // comparisons are possible, but equality comparisons are tautological. + const unsigned A = 32768; + void (s < A); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}} + void (s > A); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}} + void (s <= A); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}} + void (s >= A); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}} + + void (s == A); // expected-warning{{comparison of constant 32768 with expression of type 'short' is always false}} + void (s != A); // expected-warning{{comparison of constant 32768 with expression of type 'short' is always true}} + + // When negative one is converted to an unsigned value, it becomes the max + // unsigned. Likewise, a negative one short can also be converted to max + // unsigned. + const unsigned B = -1; + void (s < B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}} + void (s > B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}} + void (s <= B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}} + void (s >= B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}} + void (s == B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}} + void (s != B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}} + +} + +void test5(bool b) { + (void) (b < -1); // expected-warning{{comparison of constant -1 with expression of type 'bool' is always false}} + (void) (b > -1); // expected-warning{{comparison of constant -1 with expression of type 'bool' is always true}} + (void) (b == -1); // expected-warning{{comparison of constant -1 with expression of type 'bool' is always false}} + (void) (b != -1); // expected-warning{{comparison of constant -1 with expression of type 'bool' is always true}} + (void) (b <= -1); // expected-warning{{comparison of constant -1 with expression of type 'bool' is always false}} + (void) (b >= -1); // expected-warning{{comparison of constant -1 with expression of type 'bool' is always true}} + + (void) (b < -10); // expected-warning{{comparison of constant -10 with expression of type 'bool' is always false}} + (void) (b > -10); // expected-warning{{comparison of constant -10 with expression of type 'bool' is always true}} + (void) (b == -10); // expected-warning{{comparison of constant -10 with expression of type 'bool' is always false}} + (void) (b != -10); // expected-warning{{comparison of constant -10 with expression of type 'bool' is always true}} + (void) (b <= -10); // expected-warning{{comparison of constant -10 with expression of type 'bool' is always false}} + (void) (b >= -10); // expected-warning{{comparison of constant -10 with expression of type 'bool' is always true}} + + (void) (b < 2); // expected-warning{{comparison of constant 2 with expression of type 'bool' is always true}} + (void) (b > 2); // expected-warning{{comparison of constant 2 with expression of type 'bool' is always false}} + (void) (b == 2); // expected-warning{{comparison of constant 2 with expression of type 'bool' is always false}} + (void) (b != 2); // expected-warning{{comparison of constant 2 with expression of type 'bool' is always true}} + (void) (b <= 2); // expected-warning{{comparison of constant 2 with expression of type 'bool' is always true}} + (void) (b >= 2); // expected-warning{{comparison of constant 2 with expression of type 'bool' is always false}} + + (void) (b < 10); // expected-warning{{comparison of constant 10 with expression of type 'bool' is always true}} + (void) (b > 10); // expected-warning{{comparison of constant 10 with expression of type 'bool' is always false}} + (void) (b == 10); // expected-warning{{comparison of constant 10 with expression of type 'bool' is always false}} + (void) (b != 10); // expected-warning{{comparison of constant 10 with expression of type 'bool' is always true}} + (void) (b <= 10); // expected-warning{{comparison of constant 10 with expression of type 'bool' is always true}} + (void) (b >= 10); // expected-warning{{comparison of constant 10 with expression of type 'bool' is always false}} +} + +void test6(signed char sc) { + (void)(sc < 200); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always true}} + (void)(sc > 200); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always false}} + (void)(sc <= 200); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always true}} + (void)(sc >= 200); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always false}} + (void)(sc == 200); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always false}} + (void)(sc != 200); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always true}} + + (void)(200 < sc); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always false}} + (void)(200 > sc); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always true}} + (void)(200 <= sc); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always false}} + (void)(200 >= sc); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always true}} + (void)(200 == sc); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always false}} + (void)(200 != sc); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always true}} +} + +// Test many signedness combinations. +void test7(unsigned long other) { + // Common unsigned, other unsigned, constant unsigned + (void)((unsigned)other != (unsigned long)(0x1ffffffff)); // expected-warning{{true}} + (void)((unsigned)other != (unsigned long)(0xffffffff)); + (void)((unsigned long)other != (unsigned)(0x1ffffffff)); + (void)((unsigned long)other != (unsigned)(0xffffffff)); + + // Common unsigned, other signed, constant unsigned + (void)((int)other != (unsigned long)(0xffffffffffffffff)); // expected-warning{{different signs}} + (void)((int)other != (unsigned long)(0x00000000ffffffff)); // expected-warning{{true}} + (void)((int)other != (unsigned long)(0x000000000fffffff)); + (void)((int)other < (unsigned long)(0x00000000ffffffff)); // expected-warning{{different signs}} + (void)((int)other == (unsigned)(0x800000000)); + + // Common unsigned, other unsigned, constant signed + (void)((unsigned long)other != (int)(0xffffffff)); // expected-warning{{different signs}} + + // Common unsigned, other signed, constant signed + // Should not be possible as the common type should also be signed. + + // Common signed, other signed, constant signed + (void)((int)other != (long)(0xffffffff)); // expected-warning{{true}} + (void)((int)other != (long)(0xffffffff00000000)); // expected-warning{{true}} + (void)((int)other != (long)(0xfffffff)); + (void)((int)other != (long)(0xfffffffff0000000)); + + // Common signed, other signed, constant unsigned + (void)((int)other != (unsigned char)(0xffff)); + (void)((int)other != (unsigned char)(0xff)); + + // Common signed, other unsigned, constant signed + (void)((unsigned char)other != (int)(0xff)); + (void)((unsigned char)other != (int)(0xffff)); // expected-warning{{true}} + + // Common signed, other unsigned, constant unsigned + (void)((unsigned char)other != (unsigned short)(0xff)); + (void)((unsigned char)other != (unsigned short)(0x100)); // expected-warning{{true}} + (void)((unsigned short)other != (unsigned char)(0xff)); +} + +void test8(int x) { + enum E { + Negative = -1, + Positive = 1 + }; + + (void)((E)x == 1); + (void)((E)x == -1); +} + +void test9(int x) { + enum E : int { + Positive = 1 + }; + (void)((E)x == 1); +} diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp index ec5eb17b08f3..d8058811948d 100644 --- a/test/SemaCXX/condition.cpp +++ b/test/SemaCXX/condition.cpp @@ -19,7 +19,7 @@ void test() { while (struct NewS *x=0) ; while (struct S {} *x=0) ; // expected-error {{types may not be defined in conditions}} while (struct {} *x=0) ; // expected-error {{types may not be defined in conditions}} - switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}} \ + switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} \ // expected-warning{{enumeration value 'E' not handled in switch}} expected-warning {{switch statement has empty body}} \ // expected-note{{put the semicolon on a separate line}} @@ -58,3 +58,12 @@ void test3() { void test4(bool (&x)(void)) { while (x); } + +template <class> +void test5() { + if (struct S {}* p = 0) // expected-error {{types may not be defined in conditions}} + ; +} +void test5_inst() { + test5<int>(); +} diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp index 7595f1dfa1c0..692aaefc9d54 100644 --- a/test/SemaCXX/conditional-expr.cpp +++ b/test/SemaCXX/conditional-expr.cpp @@ -146,7 +146,7 @@ void test() (void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}} (void)(i1 ? Ambig() : 1); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}} // By the way, this isn't an lvalue: - &(i1 ? i1 : i2); // expected-error {{address expression must be an lvalue or a function designator}} + &(i1 ? i1 : i2); // expected-error {{cannot take the address of an rvalue}} // p4 (lvalue, same type) Fields flds; @@ -183,7 +183,7 @@ void test() i1 ? &MixedFields::ci : &MixedFields::cvi; (void)(i1 ? &MixedFields::ci : &MixedFields::vi); // Conversion of primitives does not result in an lvalue. - &(i1 ? i1 : d1); // expected-error {{address expression must be an lvalue or a function designator}} + &(i1 ? i1 : d1); // expected-error {{cannot take the address of an rvalue}} (void)&(i1 ? flds.b1 : flds.i1); // expected-error {{address of bit-field requested}} (void)&(i1 ? flds.i1 : flds.b1); // expected-error {{address of bit-field requested}} diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index f504eb621f6c..30aa7d7b0b3a 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -1153,8 +1153,8 @@ namespace ConvertedConstantExpr { namespace IndirectField { struct S { struct { // expected-warning {{GNU extension}} - union { - struct { // expected-warning {{GNU extension}} + union { // expected-warning {{declared in an anonymous struct}} + struct { // expected-warning {{GNU extension}} expected-warning {{declared in an anonymous union}} int a; int b; }; diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp index ecbe7bf5b9ed..17576328c11b 100644 --- a/test/SemaCXX/constructor-initializer.cpp +++ b/test/SemaCXX/constructor-initializer.cpp @@ -232,13 +232,15 @@ namespace PR7402 { // <rdar://problem/8308215>: don't crash. // Lots of questionable recovery here; errors can change. namespace test3 { - class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 2 {{candidate}} + class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 4 {{candidate}} class B : public A { public: B(const String& s, int e=0) // expected-error {{unknown type name}} : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}} B(const B& e) - : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} expected-error {{no member named 'm_String' in 'test3::B'}} + : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} \ + // expected-error {{no member named 'm_String' in 'test3::B'}} \ + // expected-error {{no matching}} } }; } @@ -283,3 +285,9 @@ namespace PR12049 { int member; // expected-error {{expected ')'}} }; } + +namespace PR14073 { + struct S1 { union { int n; }; S1() : n(n) {} }; // expected-warning {{field 'n' is uninitialized when used here}} + struct S2 { union { union { int n; }; char c; }; S2() : n(n) {} }; // expected-warning {{field 'n' is uninitialized when used here}} + struct S3 { struct { int n; }; S3() : n(n) {} }; // expected-warning {{field 'n' is uninitialized when used here}} +} diff --git a/test/SemaCXX/conversion.cpp b/test/SemaCXX/conversion.cpp index ac235cc7feaf..852bbba7efa1 100644 --- a/test/SemaCXX/conversion.cpp +++ b/test/SemaCXX/conversion.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion -verify %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion -std=c++11 -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion -std=c++11 %s 2>&1 | FileCheck %s #include <stddef.h> @@ -131,3 +131,9 @@ namespace test5 { template void func<3>(); } + +namespace test6 { + decltype(nullptr) func() { + return NULL; + } +} diff --git a/test/SemaCXX/copy-constructor-error.cpp b/test/SemaCXX/copy-constructor-error.cpp index 64a7d58e19ef..6ffed9bf222a 100644 --- a/test/SemaCXX/copy-constructor-error.cpp +++ b/test/SemaCXX/copy-constructor-error.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s struct S { S (S); // expected-error {{copy constructor must pass its first argument by reference}} @@ -10,16 +10,50 @@ void g() { S a( f() ); } +class foo { + foo(foo&, int); // expected-note {{previous}} + foo(int); // expected-note {{previous}} + foo(const foo&); // expected-note {{previous}} +}; + +foo::foo(foo&, int = 0) { } // expected-error {{makes this constructor a copy constructor}} +foo::foo(int = 0) { } // expected-error {{makes this constructor a default constructor}} +foo::foo(const foo& = 0) { } //expected-error {{makes this constructor a default constructor}} + namespace PR6064 { struct A { A() { } - inline A(A&, int); // expected-note {{was not a special member function}} + inline A(A&, int); // expected-note {{previous}} }; - A::A(A&, int = 0) { } // expected-warning {{makes this constructor a copy constructor}} + A::A(A&, int = 0) { } // expected-error {{makes this constructor a copy constructor}} void f() { A const a; A b(a); } } + +namespace PR10618 { + struct A { + A(int, int, int); // expected-note {{previous}} + }; + A::A(int a = 0, // expected-error {{makes this constructor a default constructor}} + int b = 0, + int c = 0) {} + + struct B { + B(int); + B(const B&, int); // expected-note {{previous}} + }; + B::B(const B& = B(0), // expected-error {{makes this constructor a default constructor}} + int = 0) { + } + + struct C { + C(const C&, int); // expected-note {{previous}} + }; + C::C(const C&, + int = 0) { // expected-error {{makes this constructor a copy constructor}} + } +} diff --git a/test/SemaCXX/crash-lambda-12645424.cpp b/test/SemaCXX/crash-lambda-12645424.cpp new file mode 100644 index 000000000000..8317e7c0dbc6 --- /dev/null +++ b/test/SemaCXX/crash-lambda-12645424.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify + +// rdar://12645424, crash due to a double-free + +template<typename _Tp> struct __add_lvalue_reference_helper {}; +template<typename _Tp> struct add_lvalue_reference : __add_lvalue_reference_helper<_Tp> { + typedef _Tp type; +}; + +template<typename... Types> struct type_list; +template<typename , template<typename> class... Funs> struct C; + +template<typename T> struct C<T> { + typedef T type; +}; + +template<typename T, template<typename> class Fun0, template<typename> class... Funs> struct C<T, Fun0, Funs...> { + typedef typename C<typename Fun0<T>::type, Funs...>::type type; +}; + +template<class , template<typename> class... Funs> struct tl_map; +template<typename... Ts, template<typename> class... Funs> struct tl_map<type_list<Ts...>, Funs...> { + typedef type_list<typename C<Ts, Funs...>::type...> type; +}; + +template< class Pattern> struct F { + typedef Pattern filtered_pattern; + tl_map< filtered_pattern, add_lvalue_reference > type; +}; + +template<class, class Pattern> struct get_case { + F<Pattern> type; +}; + +template<class Pattern> struct rvalue_builder { + template<typename Expr> typename get_case<Expr, Pattern>::type operator>>(Expr ); // expected-note {{candidate template ignored}} +}; + +template<typename Arg0> rvalue_builder< type_list<Arg0> > on(const Arg0& ) ; + +class Z { + int empty = on(0) >> [] {}; // expected-error {{invalid operands to binary expression}} +}; diff --git a/test/SemaCXX/cxx0x-class.cpp b/test/SemaCXX/cxx0x-class.cpp index 41b0a5ce9589..074591e7063c 100644 --- a/test/SemaCXX/cxx0x-class.cpp +++ b/test/SemaCXX/cxx0x-class.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-error=static-float-init %s int vs = 0; @@ -20,8 +20,8 @@ namespace rdar8367341 { float foo(); // expected-note {{here}} struct A { - static const float x = 5.0f; // expected-warning {{GNU extension}} expected-note {{use 'constexpr' specifier to silence this warning}} - static const float y = foo(); // expected-warning {{GNU extension}} expected-note {{use 'constexpr' specifier to silence this warning}} expected-error {{in-class initializer for static data member is not a constant expression}} + static const float x = 5.0f; // expected-warning {{requires 'constexpr'}} expected-note {{add 'constexpr'}} + static const float y = foo(); // expected-warning {{requires 'constexpr'}} expected-note {{add 'constexpr'}} static constexpr float x2 = 5.0f; static constexpr float y2 = foo(); // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr function 'foo'}} }; diff --git a/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 641760e7e540..b1078dc404b1 100644 --- a/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -36,9 +36,9 @@ struct non_const_derived : non_const_copy { }; struct bad_decls { - bad_decls(volatile bad_decls&) = default; // expected-error {{may not be volatile}} expected-error {{must be defaulted outside the class}} + bad_decls(volatile bad_decls&) = default; // expected-error {{may not be volatile}} bad_decls&& operator = (bad_decls) = default; // expected-error {{lvalue reference}} expected-error {{must return 'bad_decls &'}} - bad_decls& operator = (volatile bad_decls&) = default; // expected-error {{may not be volatile}} expected-error {{must be defaulted outside the class}} + bad_decls& operator = (volatile bad_decls&) = default; // expected-error {{may not be volatile}} bad_decls& operator = (const bad_decls&) const = default; // expected-error {{may not have 'const', 'constexpr' or 'volatile' qualifiers}} }; @@ -57,14 +57,18 @@ struct except_spec_d_good : except_spec_a, except_spec_b { ~except_spec_d_good(); }; except_spec_d_good::~except_spec_d_good() = default; -// FIXME: This should error in the virtual override check. -// It doesn't because we generate the implicit specification later than -// appropriate. +struct except_spec_d_good2 : except_spec_a, except_spec_b { + ~except_spec_d_good2() = default; +}; struct except_spec_d_bad : except_spec_a, except_spec_b { - ~except_spec_d_bad() = default; + ~except_spec_d_bad() noexcept; }; +// FIXME: This should error because this exception spec is not +// compatible with the implicit exception spec. +except_spec_d_bad::~except_spec_d_bad() noexcept = default; -// FIXME: This should error because the exceptions spec doesn't match. +// FIXME: This should error because this exception spec is not +// compatible with the implicit exception spec. struct except_spec_d_mismatch : except_spec_a, except_spec_b { except_spec_d_mismatch() throw(A) = default; }; diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp index ce7ee672ea19..bc03bcd2a137 100644 --- a/test/SemaCXX/cxx0x-defaulted-functions.cpp +++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fcxx-exceptions %s void fn() = default; // expected-error {{only special member}} struct foo { @@ -149,3 +149,42 @@ namespace PR13527 { Y &Y::operator=(Y&&) = default; // expected-error {{definition of explicitly defaulted}} Y::~Y() = default; // expected-error {{definition of explicitly defaulted}} } + +namespace PR14577 { + template<typename T> + struct Outer { + template<typename U> + struct Inner1 { + ~Inner1(); + }; + + template<typename U> + struct Inner2 { + ~Inner2(); + }; + }; + + template<typename T> + Outer<T>::Inner1<T>::~Inner1() = delete; // expected-error {{nested name specifier 'Outer<T>::Inner1<T>::' for declaration does not refer into a class, class template or class template partial specialization}} expected-error {{only functions can have deleted definitions}} + + template<typename T> + Outer<T>::Inner2<T>::~Inner2() = default; // expected-error {{nested name specifier 'Outer<T>::Inner2<T>::' for declaration does not refer into a class, class template or class template partial specialization}} expected-error {{only special member functions may be defaulted}} +} + +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}} +} + +namespace PR15597 { + template<typename T> struct A { + A() noexcept(true) = default; + ~A() noexcept(true) = default; + }; + template<typename T> struct B { + B() noexcept(false) = default; // expected-error {{does not match the calculated one}} + ~B() noexcept(false) = default; // expected-error {{does not match the calculated one}} + }; + A<int> a; + B<int> b; // expected-note {{here}} +} diff --git a/test/SemaCXX/cxx0x-initializer-aggregates.cpp b/test/SemaCXX/cxx0x-initializer-aggregates.cpp index c83058a5e196..f53ac6dff930 100644 --- a/test/SemaCXX/cxx0x-initializer-aggregates.cpp +++ b/test/SemaCXX/cxx0x-initializer-aggregates.cpp @@ -115,4 +115,18 @@ namespace sub_constructor { Aggr invalid { {} , {&ok1} , {0,0} }; // expected-error {{no matching constructor for initialization}} NoDefaultConstructor2 array_ok[] = { {0,0} , {0,1} }; NoDefaultConstructor2 array_error[] = { {0,0} , {0} }; // expected-error {{no matching constructor for initialization}} -}
\ No newline at end of file +} + +namespace multidimensional_array { + void g(const int (&)[2][2]) {} + void g(const int (&)[2][2][2]) = delete; + + void h() { + g({{1,2},{3,4}}); + } +} + +namespace array_addressof { + using T = int[5]; + T *p = &T{1,2,3,4,5}; // expected-error {{taking the address of a temporary object of type 'T' (aka 'int [5]')}} +} diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp index a657ec81a140..dc179f81bd35 100644 --- a/test/SemaCXX/cxx0x-initializer-constructor.cpp +++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp @@ -75,9 +75,8 @@ namespace objects { { F<0> f = {}; } // Narrowing conversions don't affect viability. The next two choose // the initializer_list constructor. - // FIXME: Emit narrowing conversion errors. - { F<3> f{1, 1.0}; } // xpected-error {{narrowing conversion}} - { F<3> f = {1, 1.0}; } // xpected-error {{narrowing conversion}} + { F<3> f{1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} + { F<3> f = {1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; } { F<3> f = {1, 2, 3, 4, 5, 6, 7, 8}; } { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; } @@ -306,17 +305,63 @@ namespace init_list_default { } -// <rdar://problem/11974632> -namespace rdar11974632 { +// PR13470, <rdar://problem/11974632> +namespace PR13470 { + struct W { + explicit W(int); // expected-note {{here}} + }; + struct X { - X(const X&) = delete; + X(const X&) = delete; // expected-note 3 {{here}} X(int); }; + template<typename T, typename Fn> void call(Fn f) { + f({1}); // expected-error {{constructor is explicit}} + f(T{1}); // expected-error {{call to deleted constructor}} + } + + void ref_w(const W &); // expected-note 2 {{not viable}} + void call_ref_w() { + ref_w({1}); // expected-error {{no matching function}} + ref_w(W{1}); + call<W>(ref_w); // expected-note {{instantiation of}} + } + + void ref_x(const X &); + void call_ref_x() { + ref_x({1}); + ref_x(X{1}); + call<X>(ref_x); // ok + } + + void val_x(X); // expected-note 2 {{parameter}} + void call_val_x() { + val_x({1}); + val_x(X{1}); // expected-error {{call to deleted constructor}} + call<X>(val_x); // expected-note {{instantiation of}} + } + template<typename T> - struct Y { + struct Y { X x{1}; + void f() { X x{1}; } + void h() { + ref_w({1}); // expected-error {{no matching function}} + ref_w(W{1}); + ref_x({1}); + ref_x(X{1}); + val_x({1}); + val_x(X{1}); // expected-error {{call to deleted constructor}} + } + Y() {} + Y(int) : x{1} {} }; Y<int> yi; + Y<int> yi2(0); + void g() { + yi.f(); + yi.h(); // ok, all diagnostics produced in template definition + } } diff --git a/test/SemaCXX/cxx0x-initializer-references.cpp b/test/SemaCXX/cxx0x-initializer-references.cpp index c4e9c907a37a..283c32ac2efc 100644 --- a/test/SemaCXX/cxx0x-initializer-references.cpp +++ b/test/SemaCXX/cxx0x-initializer-references.cpp @@ -90,3 +90,10 @@ namespace PR12660 { const int &i { 1 }; struct S { S(int); } const &s { 2 }; } + +namespace b7891773 { + typedef void (*ptr)(); + template <class T> void f(); + int g(const ptr &); + int k = g({ f<int> }); +} diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp index 0962253b988c..88571d671b07 100644 --- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -191,3 +191,20 @@ namespace rdar11948732 { namespace PR14272 { auto x { { 0, 0 } }; // expected-error {{cannot deduce actual type for variable 'x' with type 'auto' from initializer list}} } + +namespace initlist_of_array { + void f(std::initializer_list<int[2]>) {} + void f(std::initializer_list<int[2][2]>) = delete; + void h() { + f({{1,2},{3,4}}); + } +} + +namespace init_list_deduction_failure { + void f(); + void f(int); + template<typename T> void g(std::initializer_list<T>); + // expected-note@-1 {{candidate template ignored: couldn't resolve reference to overloaded function 'f'}} + void h() { g({f}); } + // expected-error@-1 {{no matching function for call to 'g'}} +} diff --git a/test/SemaCXX/cxx11-ast-print.cpp b/test/SemaCXX/cxx11-ast-print.cpp index afabf88bd5a7..f95eeb50fefb 100644 --- a/test/SemaCXX/cxx11-ast-print.cpp +++ b/test/SemaCXX/cxx11-ast-print.cpp @@ -1,7 +1,6 @@ // RUN: %clang_cc1 -std=c++11 -ast-print %s | FileCheck %s -// FIXME: Print the trailing-return-type properly. -// CHECK: decltype(nullptr) operator "" _foo(const char *p, decltype(sizeof(int))); +// CHECK: auto operator "" _foo(const char *p, decltype(sizeof(int))) -> decltype(nullptr); auto operator"" _foo(const char *p, decltype(sizeof(int))) -> decltype(nullptr); // CHECK: decltype(""_foo) operator "" _bar(unsigned long long); @@ -39,3 +38,6 @@ 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; +// CHECK: ; +; +// CHECK-NOT: ; diff --git a/test/SemaCXX/cxx11-attr-print.cpp b/test/SemaCXX/cxx11-attr-print.cpp new file mode 100644 index 000000000000..19de5b5a640b --- /dev/null +++ b/test/SemaCXX/cxx11-attr-print.cpp @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -std=c++11 -ast-print -fms-extensions %s | FileCheck %s +// +// CHECK: int x __attribute__((aligned(4))); +int x __attribute__((aligned(4))); + +// FIXME: Print this at a valid location for a __declspec attr. +// CHECK: int y __declspec(align(4)); +__declspec(align(4)) int y; + +// CHECK: int z {{\[}}[gnu::aligned(4)]]; +int z [[gnu::aligned(4)]]; + +// CHECK: __attribute__((deprecated("warning"))); +int a __attribute__((deprecated("warning"))); + +// CHECK: int b {{\[}}[gnu::deprecated("warning")]]; +int b [[gnu::deprecated("warning")]]; + +// CHECK: int cxx11_alignas alignas(4); +alignas(4) int cxx11_alignas; + +// CHECK: int c11_alignas _Alignas(alignof(int)); +_Alignas(int) int c11_alignas; + +// CHECK: void foo() __attribute__((const)); +void foo() __attribute__((const)); + +// CHECK: void bar() __attribute__((__const)); +void bar() __attribute__((__const)); + +// CHECK: int f1() __attribute__((warn_unused_result)); +int f1() __attribute__((warn_unused_result)); + +// CHECK: {{\[}}[clang::warn_unused_result]]; +int f2 [[clang::warn_unused_result]] (); + +// CHECK: {{\[}}[gnu::warn_unused_result]]; +int f3 [[gnu::warn_unused_result]] (); + +// FIXME: ast-print need to print C++11 +// attribute after function declare-id. +// CHECK: {{\[}}[noreturn]]; +void f4 [[noreturn]] (); + +// CHECK: {{\[}}[std::noreturn]]; +void f5 [[std::noreturn]] (); + +// CHECK: __attribute__((gnu_inline)); +inline void f6() __attribute__((gnu_inline)); + +// CHECK: {{\[}}[gnu::gnu_inline]]; +inline void f7 [[gnu::gnu_inline]] (); + +// arguments printing +// CHECK: __attribute__((format("printf", 2, 3))); +void f8 (void *, const char *, ...) __attribute__ ((format (printf, 2, 3))); + +// CHECK: int m __attribute__((aligned(4 +// CHECK: int n alignas(4 +// CHECK: static int f() __attribute__((pure)) +// CHECK: static int g() {{\[}}[gnu::pure]] +template <typename T> struct S { + __attribute__((aligned(4))) int m; + alignas(4) int n; + __attribute__((pure)) static int f() { + return 0; + } + [[gnu::pure]] static int g() { + return 1; + } +}; + +// CHECK: int m __attribute__((aligned(4 +// CHECK: int n alignas(4 +// CHECK: static int f() __attribute__((pure)) +// CHECK: static int g() {{\[}}[gnu::pure]] +template struct S<int>; diff --git a/test/SemaCXX/cxx11-gnu-attrs.cpp b/test/SemaCXX/cxx11-gnu-attrs.cpp new file mode 100644 index 000000000000..def83a94ea2b --- /dev/null +++ b/test/SemaCXX/cxx11-gnu-attrs.cpp @@ -0,0 +1,55 @@ +// RUN: %clang -cc1 -triple x86_64-unknown-unknown -std=c++11 -verify %s + +// Error cases. + +[[gnu::this_attribute_does_not_exist]] int unknown_attr; +// expected-warning@-1 {{unknown attribute 'this_attribute_does_not_exist' ignored}} +int [[gnu::unused]] attr_on_type; +// expected-error@-1 {{'unused' attribute cannot be applied to types}} +int *[[gnu::unused]] attr_on_ptr; +// expected-warning@-1 {{attribute 'unused' ignored, because it cannot be applied to a type}} + +// Valid cases. + +void alias1() {} +void alias2 [[gnu::alias("_Z6alias1v")]] (); + +[[gnu::aligned(8)]] int aligned; +void aligned_fn [[gnu::aligned(32)]] (); +struct [[gnu::aligned(8)]] aligned_struct {}; + +[[gnu::malloc, gnu::alloc_size(1,2)]] void *alloc_size(int a, int b); + +void always_inline [[gnu::always_inline]] (); + +__thread int tls_model [[gnu::tls_model("local-exec")]]; + +void cleanup(int *p) { + int n [[gnu::cleanup(cleanup)]]; +} + +void deprecated1 [[gnu::deprecated]] (); // expected-note {{here}} +[[gnu::deprecated("custom message")]] void deprecated2(); // expected-note {{here}} +void deprecated3() { + deprecated1(); // expected-warning {{deprecated}} + deprecated2(); // expected-warning {{custom message}} +} + +[[gnu::naked(1,2,3)]] void naked(); // expected-error {{takes no arguments}} + +void nonnull [[gnu::nonnull]] (); // expected-warning {{applied to function with no pointer arguments}} + +// [[gnu::noreturn]] appertains to a declaration, and marks the innermost +// function declarator in that declaration as being noreturn. +int noreturn [[gnu::noreturn]]; // expected-warning {{'noreturn' only applies to function types}} +int noreturn_fn_1(); +int noreturn_fn_2() [[gnu::noreturn]]; // expected-warning {{cannot be applied to a type}} +int noreturn_fn_3 [[gnu::noreturn]] (); +[[gnu::noreturn]] int noreturn_fn_4(); +int (*noreturn_fn_ptr_1 [[gnu::noreturn]])() = &noreturn_fn_1; // expected-error {{cannot initialize}} +int (*noreturn_fn_ptr_2 [[gnu::noreturn]])() = &noreturn_fn_3; +[[gnu::noreturn]] int (*noreturn_fn_ptr_3)() = &noreturn_fn_1; // expected-error {{cannot initialize}} +[[gnu::noreturn]] int (*noreturn_fn_ptr_4)() = &noreturn_fn_3; + +struct [[gnu::packed]] packed { char c; int n; }; +static_assert(sizeof(packed) == sizeof(char) + sizeof(int), "not packed"); diff --git a/test/SemaCXX/cxx11-user-defined-literals.cpp b/test/SemaCXX/cxx11-user-defined-literals.cpp index 4bbecdb5b8e4..f8bbcd960fd3 100644 --- a/test/SemaCXX/cxx11-user-defined-literals.cpp +++ b/test/SemaCXX/cxx11-user-defined-literals.cpp @@ -135,3 +135,9 @@ namespace Namespace { int _y(unsigned long long); int k2 = 123_y; // expected-error {{no matching literal operator for call to 'operator "" _y'}} } + +namespace PR14950 { + template<...> // expected-error {{expected template parameter}} + int operator"" _b(); // expected-error {{no function template matches function template specialization}} + int main() { return 0_b; } // expected-error {{no matching literal operator for call to 'operator "" _b'}} +} diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp index d497d45c3e35..7d36770f5d20 100644 --- a/test/SemaCXX/cxx98-compat.cpp +++ b/test/SemaCXX/cxx98-compat.cpp @@ -8,6 +8,8 @@ namespace std { initializer_list(T*, size_t); T *p; size_t n; + T *begin(); + T *end(); }; } @@ -103,6 +105,13 @@ void RangeFor() { int xs[] = {1, 2, 3}; for (int &a : xs) { // expected-warning {{range-based for loop is incompatible with C++98}} } + for (auto &b : {1, 2, 3}) { + // expected-warning@-1 {{range-based for loop is incompatible with C++98}} + // expected-warning@-2 {{'auto' type specifier is incompatible with C++98}} + // expected-warning@-3 {{initialization of initializer_list object is incompatible with C++98}} + // expected-warning@-4 {{reference initialized from initializer list is incompatible with C++98}} + } + struct Agg { int a, b; } const &agg = { 1, 2 }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}} } struct InClassInit { @@ -254,13 +263,13 @@ namespace CopyCtorIssues { namespace UnionOrAnonStructMembers { struct NonTrivCtor { - NonTrivCtor(); // expected-note 2{{user-declared constructor}} + NonTrivCtor(); // expected-note 2{{user-provided default constructor}} }; struct NonTrivCopy { - NonTrivCopy(const NonTrivCopy&); // expected-note 2{{user-declared copy constructor}} + NonTrivCopy(const NonTrivCopy&); // expected-note 2{{user-provided copy constructor}} }; struct NonTrivDtor { - ~NonTrivDtor(); // expected-note 2{{user-declared destructor}} + ~NonTrivDtor(); // expected-note 2{{user-provided destructor}} }; union BadUnion { NonTrivCtor ntc; // expected-warning {{union member 'ntc' with a non-trivial constructor is incompatible with C++98}} @@ -338,8 +347,8 @@ namespace NullPointerTemplateArg { namespace PR13480 { struct basic_iterator { - basic_iterator(const basic_iterator &it) {} - basic_iterator(basic_iterator &it) {} // expected-note {{because type 'PR13480::basic_iterator' has a user-declared copy constructor}} + basic_iterator(const basic_iterator &it) {} // expected-note {{because type 'PR13480::basic_iterator' has a user-provided copy constructor}} + basic_iterator(basic_iterator &it) {} }; union test { @@ -349,12 +358,12 @@ namespace PR13480 { namespace AssignOpUnion { struct a { - void operator=(const a &it) {} - void operator=(a &it) {} // expected-note {{because type 'AssignOpUnion::a' has a user-declared copy assignment operator}} + void operator=(const a &it) {} // expected-note {{because type 'AssignOpUnion::a' has a user-provided copy assignment operator}} + void operator=(a &it) {} }; struct b { - void operator=(const b &it) {} // expected-note {{because type 'AssignOpUnion::b' has a user-declared copy assignment operator}} + void operator=(const b &it) {} // expected-note {{because type 'AssignOpUnion::b' has a user-provided copy assignment operator}} }; union test1 { @@ -364,9 +373,9 @@ namespace AssignOpUnion { } namespace rdar11736429 { - struct X { + struct X { // expected-note {{because type 'rdar11736429::X' has no default constructor}} X(const X&) = delete; // expected-warning{{deleted function definitions are incompatible with C++98}} \ - // expected-note{{because type 'rdar11736429::X' has a user-declared constructor}} + // expected-note {{implicit default constructor suppressed by user-declared constructor}} }; union S { diff --git a/test/SemaCXX/decl-microsoft-call-conv.cpp b/test/SemaCXX/decl-microsoft-call-conv.cpp new file mode 100644 index 000000000000..3175af7f1b07 --- /dev/null +++ b/test/SemaCXX/decl-microsoft-call-conv.cpp @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -fms-extensions -verify %s + +// Pointers to free functions +void free_func_default(); +void __cdecl free_func_cdecl(); +void __stdcall free_func_stdcall(); // expected-note {{previous declaration is here}} +void __fastcall free_func_fastcall(); // expected-note 2 {{previous declaration is here}} + +void __cdecl free_func_default(); // expected-note 2 {{previous declaration is here}} +void __stdcall free_func_default(); // expected-error {{function declared 'stdcall' here was previously declared without calling convention}} +void __fastcall free_func_default(); // expected-error {{function declared 'fastcall' here was previously declared without calling convention}} + +void free_func_cdecl(); // expected-note 2 {{previous declaration is here}} +void __stdcall free_func_cdecl(); // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}} +void __fastcall free_func_cdecl(); // expected-error {{function declared 'fastcall' here was previously declared 'cdecl'}} + +void __cdecl free_func_stdcall(); // expected-error {{function declared 'cdecl' here was previously declared 'stdcall'}} +void free_func_stdcall(); // expected-note {{previous declaration is here}} +void __fastcall free_func_stdcall(); // expected-error {{function declared 'fastcall' here was previously declared 'stdcall'}} + +void __cdecl free_func_fastcall(); // expected-error {{function declared 'cdecl' here was previously declared 'fastcall'}} +void __stdcall free_func_fastcall(); // expected-error {{function declared 'stdcall' here was previously declared 'fastcall'}} +void free_func_fastcall(); + +// Overloaded functions may have different calling conventions +void __fastcall free_func_default(int); +void __cdecl free_func_default(int *); + +void __thiscall free_func_cdecl(char *); +void __cdecl free_func_cdecl(double); + + +// Pointers to member functions +struct S { + void member_default1(); // expected-note {{previous declaration is here}} + void member_default2(); + void __cdecl member_cdecl1(); + void __cdecl member_cdecl2(); // expected-note {{previous declaration is here}} + void __thiscall member_thiscall1(); + void __thiscall member_thiscall2(); // expected-note {{previous declaration is here}} + + // Static member functions can't be __thiscall + static void static_member_default1(); + static void static_member_default2(); // expected-note {{previous declaration is here}} + static void __cdecl static_member_cdecl1(); + static void __cdecl static_member_cdecl2(); // expected-note {{previous declaration is here}} + static void __stdcall static_member_stdcall1(); + static void __stdcall static_member_stdcall2(); + + // Variadic functions can't be other than default or __cdecl + void member_variadic_default(int x, ...); + void __cdecl member_variadic_cdecl(int x, ...); + + static void static_member_variadic_default(int x, ...); + static void __cdecl static_member_variadic_cdecl(int x, ...); +}; + +void __cdecl S::member_default1() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}} +void __thiscall S::member_default2() {} + +void S::member_cdecl1() {} +void __thiscall S::member_cdecl2() {} // expected-error {{function declared 'thiscall' here was previously declared 'cdecl'}} + +void S::member_thiscall1() {} +void __cdecl S::member_thiscall2() {} // expected-error {{function declared 'cdecl' here was previously declared 'thiscall'}} + +void __cdecl S::static_member_default1() {} +void __stdcall S::static_member_default2() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}} + +void S::static_member_cdecl1() {} +void __stdcall S::static_member_cdecl2() {} // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}} + +void __cdecl S::member_variadic_default(int x, ...) { + (void)x; +} +void S::member_variadic_cdecl(int x, ...) { + (void)x; +} + +void __cdecl S::static_member_variadic_default(int x, ...) { + (void)x; +} +void S::static_member_variadic_cdecl(int x, ...) { + (void)x; +} + diff --git a/test/SemaCXX/default-arg-special-member.cpp b/test/SemaCXX/default-arg-special-member.cpp deleted file mode 100644 index 8402d3829d7a..000000000000 --- a/test/SemaCXX/default-arg-special-member.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -Wno-default-arg-special-member -Werror -fsyntax-only %s - -class foo { - foo(foo&, int); // expected-note {{was not a special member function}} - foo(int); // expected-note {{was not a special member function}} - foo(const foo&); // expected-note {{was a copy constructor}} -}; - -foo::foo(foo&, int = 0) { } // expected-warning {{makes this constructor a copy constructor}} -foo::foo(int = 0) { } // expected-warning {{makes this constructor a default constructor}} -foo::foo(const foo& = 0) { } //expected-warning {{makes this constructor a default constructor}} diff --git a/test/SemaCXX/empty-class-layout.cpp b/test/SemaCXX/empty-class-layout.cpp index 951f16c1b0c5..3cfc491ef664 100644 --- a/test/SemaCXX/empty-class-layout.cpp +++ b/test/SemaCXX/empty-class-layout.cpp @@ -156,3 +156,18 @@ namespace Test7 { }; SA(0, sizeof(Test) == 2); } + +namespace Test8 { + // Test that type sugar doesn't make us incorrectly determine the size of an + // array of empty classes. + struct Empty1 {}; + struct Empty2 {}; + struct Empties : Empty1, Empty2 {}; + typedef Empty1 Sugar[4]; + struct A : Empty2, Empties { + // This must go at offset 2, because if it were at offset 0, + // V[0][1] would overlap Empties::Empty1. + Sugar V[1]; + }; + SA(0, sizeof(A) == 6); +} diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp index a1f911d79d39..d01000d22bb4 100644 --- a/test/SemaCXX/enum-scoped.cpp +++ b/test/SemaCXX/enum-scoped.cpp @@ -252,3 +252,17 @@ namespace pr13128 { enum class E { C }; }; } + +namespace PR15633 { + template<typename T> struct A { + struct B { + enum class E : T; + enum class E2 : T; + }; + }; + template<typename T> enum class A<T>::B::E { e }; + template class A<int>; + + struct B { enum class E; }; + template<typename T> enum class B::E { e }; // expected-error {{enumeration cannot be a template}} +} diff --git a/test/SemaCXX/exceptions.cpp b/test/SemaCXX/exceptions.cpp index 486d88eab7be..c2ca9f952b22 100644 --- a/test/SemaCXX/exceptions.cpp +++ b/test/SemaCXX/exceptions.cpp @@ -120,3 +120,28 @@ namespace PR6831 { } } } + +namespace Decay { + struct A { + void f() throw (A[10]); + }; + + template<typename T> struct B { + void f() throw (B[10]); + }; + template struct B<int>; + + void f() throw (int[10], int(*)()); + void f() throw (int*, int()); + + template<typename T> struct C { + void f() throw (T); // expected-error {{pointer to incomplete type 'Decay::E' is not allowed in exception specification}} + }; + struct D { + C<D[10]> c; + }; + struct E; // expected-note {{forward declaration}} + C<E[10]> e; // expected-note {{in instantiation of}} +} + +void rval_ref() throw (int &&); // expected-error {{rvalue reference type 'int &&' is not allowed in exception specification}} expected-warning {{C++11}} diff --git a/test/SemaCXX/extern-c.cpp b/test/SemaCXX/extern-c.cpp new file mode 100644 index 000000000000..c55b10d9d6e3 --- /dev/null +++ b/test/SemaCXX/extern-c.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace test1 { + extern "C" { + void f() { + void test1_g(int); // expected-note {{previous declaration is here}} + } + } +} +int test1_g(int); // expected-error {{functions that differ only in their return type cannot be overloaded}} + +namespace test2 { + extern "C" { + void f() { + extern int test2_x; // expected-note {{previous definition is here}} + } + } +} +float test2_x; // expected-error {{redefinition of 'test2_x' with a different type: 'float' vs 'int'}} + +namespace test3 { + extern "C" { + void f() { + extern int test3_b; // expected-note {{previous definition is here}} + } + } + extern "C" { + float test3_b; // expected-error {{redefinition of 'test3_b' with a different type: 'float' vs 'int'}} + } +} + +extern "C" { + void test4_f() { + extern int test4_b; // expected-note {{previous definition is here}} + } +} +static float test4_b; // expected-error {{redefinition of 'test4_b' with a different type: 'float' vs 'int'}} + +extern "C" { + void test5_f() { + extern int test5_b; // expected-note {{previous definition is here}} + } +} +extern "C" { + static float test5_b; // expected-error {{redefinition of 'test5_b' with a different type: 'float' vs 'int'}} +} + +extern "C" { + void f() { + extern int test6_b; + } +} +namespace foo { + extern "C" { + static float test6_b; + extern float test6_b; + } +} diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp index c5b11eb5a338..b401a06a7ecf 100644 --- a/test/SemaCXX/friend.cpp +++ b/test/SemaCXX/friend.cpp @@ -138,3 +138,19 @@ namespace test7 { }; } } + +// PR15485 +namespace test8 { + namespace ns1 { + namespace ns2 { + template<class T> void f(T t); // expected-note {{target of using declaration}} + } + using ns2::f; // expected-note {{using declaration}} + } + struct A { void f(); }; // expected-note {{target of using declaration}} + struct B : public A { using A::f; }; // expected-note {{using declaration}} + struct X { + template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}} + friend void B::f(); // expected-error {{cannot befriend target of using declaration}} + }; +} diff --git a/test/SemaCXX/function-extern-c.cpp b/test/SemaCXX/function-extern-c.cpp index 16dbbb26fc66..6ab965735065 100644 --- a/test/SemaCXX/function-extern-c.cpp +++ b/test/SemaCXX/function-extern-c.cpp @@ -38,3 +38,61 @@ extern "C" long long f11( void ); extern "C" A *f10( void ); extern "C" struct mypodstruct f12(); // expected-warning {{'f12' has C-linkage specified, but returns incomplete type 'struct mypodstruct' which could be incompatible with C}} + +namespace test2 { + // FIXME: we should probably suppress the first warning as the second one + // is more precise. + // For now this tests that a second 'extern "C"' is not necessary to trigger + // the warning. + struct A; + extern "C" A f(void); // expected-warning {{'f' has C-linkage specified, but returns incomplete type 'test2::A' which could be incompatible with C}} + struct A { + A(const A&); + }; + A f(void); // no warning. warning is already issued on first declaration. +} + +namespace test3 { + struct A { + A(const A&); + }; + extern "C" { + // Don't warn for static functions. + static A f(void); + } +} + +// rdar://13364028 +namespace rdar13364028 { +class A { +public: + virtual int x(); +}; + +extern "C" { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +A xyzzy(); +#pragma clang diagnostic pop +A bbb(); // expected-warning {{'bbb' has C-linkage specified, but returns user-defined type 'rdar13364028::A' which is incompatible with C}} +A ccc() { // expected-warning {{'ccc' has C-linkage specified, but returns user-defined type 'rdar13364028::A' which is incompatible with C}} + return A(); +}; +} + +A xyzzy(); + +A xyzzy() +{ + return A(); +} + +A bbb() +{ + return A(); +} + +A bbb(); + +A ccc(); +} diff --git a/test/SemaCXX/implicit-member-functions.cpp b/test/SemaCXX/implicit-member-functions.cpp index 845173934219..b5f7fe1016b9 100644 --- a/test/SemaCXX/implicit-member-functions.cpp +++ b/test/SemaCXX/implicit-member-functions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s struct A { }; A::A() { } // expected-error {{definition of implicitly declared default constructor}} @@ -50,3 +50,70 @@ namespace PR7594 { }; C *C::c = new C(); } + +namespace Recursion { + template<typename T> struct InvokeCopyConstructor { + static const T &get(); + typedef decltype(T(get())) type; // expected-error {{no matching conver}} + }; + struct B; + struct A { + typedef B type; + template<typename T, + typename = typename InvokeCopyConstructor<typename T::type>::type> + // expected-note@-1 {{in instantiation of template class}} + A(const T &); + // expected-note@-1 {{in instantiation of default argument}} + // expected-note@-2 {{while substituting deduced template arguments}} + }; + struct B { // expected-note {{candidate constructor (the implicit move }} + B(); // expected-note {{candidate constructor not viable}} + A a; + }; + // Triggering the declaration of B's copy constructor causes overload + // resolution to occur for A's copying constructor, which instantiates + // InvokeCopyConstructor<B>, which triggers the declaration of B's copy + // constructor. Notionally, this happens when we get to the end of the + // definition of 'struct B', so there is no declared copy constructor yet. + // + // This behavior is g++-compatible, but isn't exactly right; the class is + // supposed to be incomplete when we implicitly declare its special members. + B b = B(); + + + // Another case, which isn't ill-formed under our rules. This is inspired by + // a problem which occurs when combining CGAL with libstdc++-4.7. + + template<typename T> T &&declval(); + template<typename T, typename U> struct pair { + pair(); + template<typename V, typename W, + typename = decltype(T(declval<const V&>())), + typename = decltype(U(declval<const W&>()))> + pair(const pair<V,W> &); + }; + + template<typename K> struct Line; + + template<typename K> struct Vector { + Vector(const Line<K> &l); + }; + + template<typename K> struct Point { + Vector<K> v; + }; + + template<typename K> struct Line { + pair<Point<K>, Vector<K>> x; + }; + + // Trigger declaration of Line copy ctor, which causes substitution into + // pair's templated constructor, which triggers instantiation of the + // definition of Point's copy constructor, which performs overload resolution + // on Vector's constructors, which requires declaring all of Line's + // constructors. That should not find a copy constructor (because we've not + // declared it yet), but by the time we get all the way back here, we should + // find the copy constructor. + Line<void> L1; + Line<void> L2(L1); +} diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp index 6f92373a6954..a333f38530b3 100644 --- a/test/SemaCXX/lambda-expressions.cpp +++ b/test/SemaCXX/lambda-expressions.cpp @@ -236,3 +236,7 @@ namespace PR13860 { namespace PR13854 { auto l = [](void){}; } + +namespace PR14518 { + auto f = [](void) { return __func__; }; // no-warning +} diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp index cb7e32c05d88..0ba950812457 100644 --- a/test/SemaCXX/linkage-spec.cpp +++ b/test/SemaCXX/linkage-spec.cpp @@ -90,6 +90,10 @@ extern "C++" using N::value; // PR7076 extern "C" const char *Version_string = "2.9"; +extern "C" { + extern const char *Version_string2 = "2.9"; +} + namespace PR9162 { extern "C" { typedef struct _ArtsSink ArtsSink; diff --git a/test/SemaCXX/linkage2.cpp b/test/SemaCXX/linkage2.cpp new file mode 100644 index 000000000000..ddf4064215d7 --- /dev/null +++ b/test/SemaCXX/linkage2.cpp @@ -0,0 +1,154 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -fmodules %s + +namespace test1 { + int x; // expected-note {{previous definition is here}} + static int y; + void f() {} // expected-note {{previous definition is here}} + + extern "C" { + extern int x; // expected-error {{declaration of 'x' has a different language linkage}} + extern int y; // OK, has internal linkage, so no language linkage. + void f(); // expected-error {{declaration of 'f' has a different language linkage}} + } +} + +// This is OK. Both test2_f don't have language linkage since they have +// internal linkage. +extern "C" { + static void test2_f() { + } + static void test2_f(int x) { + } +} + +namespace test3 { + extern "C" { + namespace { + extern int x2; + void f2(); + } + } + namespace { + int x2; + void f2() {} + } +} + +namespace test4 { + void dummy() { + void Bar(); + class A { + friend void Bar(); + }; + } +} + +namespace test5 { + static void g(); + void f() + { + void g(); + } +} + +// pr14898 +namespace test6 { + template <class _Rp> + class __attribute__ ((__visibility__("default"))) shared_future; + template <class _Rp> + class future { + template <class> friend class shared_future; + shared_future<_Rp> share(); + }; + template <class _Rp> future<_Rp> + get_future(); + template <class _Rp> + struct shared_future<_Rp&> { + shared_future(future<_Rp&>&& __f); // expected-warning {{rvalue references are a C++11 extension}} + }; + void f() { + typedef int T; + get_future<int>(); + typedef int& U; + shared_future<int&> f1 = get_future<int&>(); + } +} + +// This is OK. The variables have internal linkage and therefore no language +// linkage. +extern "C" { + static int test7_x; +} +extern "C++" { + extern int test7_x; +} +extern "C++" { + static int test7_y; +} +extern "C" { + extern int test7_y; +} +extern "C" { typedef int test7_F(); static test7_F test7_f; } +extern "C++" { extern test7_F test7_f; } + +// FIXME: This should be invalid. The function has no language linkage, but +// the function type has, so this is redeclaring the function with a different +// type. +extern "C++" { + static void test8_f(); +} +extern "C" { + extern void test8_f(); +} +extern "C" { + static void test8_g(); +} +extern "C++" { + extern void test8_g(); +} + +extern "C" { + void __attribute__((overloadable)) test9_f(int c); // expected-note {{previous declaration is here}} +} +extern "C++" { + void __attribute__((overloadable)) test9_f(int c); // expected-error {{declaration of 'test9_f' has a different language linkage}} +} + +extern "C" { + void __attribute__((overloadable)) test10_f(int); + void __attribute__((overloadable)) test10_f(double); +} + +extern "C" { + void test11_f() { + void __attribute__((overloadable)) test11_g(int); + void __attribute__((overloadable)) test11_g(double); + } +} + +namespace test12 { + const int n = 0; + extern const int n; + void f() { + extern const int n; + } +} + +namespace test13 { + static void a(void); + extern void a(); + static void a(void) {} +} + +namespace test14 { + namespace { + void a(void); // expected-note {{previous declaration is here}} + static void a(void) {} // expected-error {{static declaration of 'a' follows non-static declaration}} + } +} + +namespace test15 { + const int a = 5; // expected-note {{previous definition is here}} + static const int a; // expected-error {{redefinition of 'a'}} +} diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp index 763f9c754c1e..515bcd43b2c0 100644 --- a/test/SemaCXX/member-expr.cpp +++ b/test/SemaCXX/member-expr.cpp @@ -111,8 +111,13 @@ namespace rdar8231724 { struct X { }; struct Y : X { }; + template<typename T> struct Z { int n; }; + void f(Y *y) { y->N::X1<int>; // expected-error{{'rdar8231724::N::X1' is not a member of class 'rdar8231724::Y'}} + y->Z<int>::n; // expected-error{{'rdar8231724::Z<int>::n' is not a member of class 'rdar8231724::Y'}} + y->template Z<int>::n; // expected-error{{'rdar8231724::Z<int>::n' is not a member of class 'rdar8231724::Y'}} \ + // expected-warning{{'template' keyword outside of a template}} } } diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp index a13941fce5d8..19e8e7597e85 100644 --- a/test/SemaCXX/member-init.cpp +++ b/test/SemaCXX/member-init.cpp @@ -73,3 +73,19 @@ namespace PR10578 { } catch(...) { } } + +namespace PR14838 { + struct base { ~base() {} }; + class function : base { + ~function() {} // expected-note {{implicitly declared private here}} + public: + function(...) {} + }; + struct thing {}; + struct another { + another() : r(thing()) {} + // expected-error@-1 {{temporary of type 'const PR14838::function' has private destructor}} + // expected-warning@-2 {{binding reference member 'r' to a temporary value}} + const function &r; // expected-note {{reference member declared here}} + } af; +} diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp index 3b2d0fceb978..7dca12190584 100644 --- a/test/SemaCXX/member-pointer-ms.cpp +++ b/test/SemaCXX/member-pointer-ms.cpp @@ -1,14 +1,167 @@ -// RUN: %clang_cc1 -cxx-abi microsoft -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify %s +// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify %s +// +// This file should also give no diagnostics when run through cl.exe from MSVS +// 2012, which supports C++11 and static_assert. It should pass for both 64-bit +// and 32-bit x86. +// +// expected-no-diagnostics -// Test that we reject pointers to members of incomplete classes (for now) -struct A; //expected-note{{forward declaration of 'A'}} -int A::*pai1; //expected-error{{incomplete type 'A'}} +// Test the size of various member pointer combinations: +// - complete and incomplete +// - single, multiple, and virtual inheritance (and unspecified for incomplete) +// - data and function pointers +// - templated with declared specializations with annotations +// - template that can be instantiated -// Test that we don't allow reinterpret_casts from pointers of one size to -// pointers of a different size. -struct A {}; -struct B {}; -struct C: A, B {}; +// http://llvm.org/PR12070 +struct Foo { + typedef int Foo::*FooInt; + int f; +}; -void (A::*paf)(); -void (C::*pcf)() = reinterpret_cast<void (C::*)()>(paf); //expected-error{{cannot reinterpret_cast from member pointer type}} +enum { + kSingleDataSize = 1 * sizeof(int), + kSingleFunctionSize = 1 * sizeof(void *), + kMultipleDataSize = 1 * sizeof(int), + kMultipleFunctionSize = 2 * sizeof(void *), + kVirtualDataSize = 2 * sizeof(int), + kVirtualFunctionSize = 2 * sizeof(int) + 1 * sizeof(void *), + // Unspecified is weird, it's 1 more slot than virtual. + kUnspecifiedDataSize = kVirtualDataSize + 1 * sizeof(int), + kUnspecifiedFunctionSize = kVirtualFunctionSize + 1 * sizeof(void *), +}; + +// incomplete types +class __single_inheritance IncSingle; +class __multiple_inheritance IncMultiple; +class __virtual_inheritance IncVirtual; +static_assert(sizeof(int IncSingle::*) == kSingleDataSize, ""); +static_assert(sizeof(int IncMultiple::*) == kMultipleDataSize, ""); +static_assert(sizeof(int IncVirtual::*) == kVirtualDataSize, ""); +static_assert(sizeof(void (IncSingle::*)()) == kSingleFunctionSize, ""); +static_assert(sizeof(void (IncMultiple::*)()) == kMultipleFunctionSize, ""); +static_assert(sizeof(void (IncVirtual::*)()) == kVirtualFunctionSize, ""); + +// 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. +class IncUnspecified; +static_assert(sizeof(int IncUnspecified::*) == kUnspecifiedDataSize, ""); +static_assert(sizeof(void (IncUnspecified::*)()) == kUnspecifiedFunctionSize, ""); + +// complete types +struct B1 { }; +struct B2 { }; +struct Single { }; +struct Multiple : B1, B2 { }; +struct Virtual : virtual B1 { }; +static_assert(sizeof(int Single::*) == kSingleDataSize, ""); +static_assert(sizeof(int Multiple::*) == kMultipleDataSize, ""); +static_assert(sizeof(int Virtual::*) == kVirtualDataSize, ""); +static_assert(sizeof(void (Single::*)()) == kSingleFunctionSize, ""); +static_assert(sizeof(void (Multiple::*)()) == kMultipleFunctionSize, ""); +static_assert(sizeof(void (Virtual::*)()) == kVirtualFunctionSize, ""); + +// Test both declared and defined templates. +template <typename T> class X; +template <> class __single_inheritance X<IncSingle>; +template <> class __multiple_inheritance X<IncMultiple>; +template <> class __virtual_inheritance X<IncVirtual>; +// Don't declare X<IncUnspecified>. +static_assert(sizeof(int X<IncSingle>::*) == kSingleDataSize, ""); +static_assert(sizeof(int X<IncMultiple>::*) == kMultipleDataSize, ""); +static_assert(sizeof(int X<IncVirtual>::*) == kVirtualDataSize, ""); +static_assert(sizeof(int X<IncUnspecified>::*) == kUnspecifiedDataSize, ""); +static_assert(sizeof(void (X<IncSingle>::*)()) == kSingleFunctionSize, ""); +static_assert(sizeof(void (X<IncMultiple>::*)()) == kMultipleFunctionSize, ""); +static_assert(sizeof(void (X<IncVirtual>::*)()) == kVirtualFunctionSize, ""); +static_assert(sizeof(void (X<IncUnspecified>::*)()) == kUnspecifiedFunctionSize, ""); + +template <typename T> +struct Y : T { }; +static_assert(sizeof(int Y<Single>::*) == kSingleDataSize, ""); +static_assert(sizeof(int Y<Multiple>::*) == kMultipleDataSize, ""); +static_assert(sizeof(int Y<Virtual>::*) == kVirtualDataSize, ""); +static_assert(sizeof(void (Y<Single>::*)()) == kSingleFunctionSize, ""); +static_assert(sizeof(void (Y<Multiple>::*)()) == kMultipleFunctionSize, ""); +static_assert(sizeof(void (Y<Virtual>::*)()) == kVirtualFunctionSize, ""); + +struct A { int x; void bar(); }; +struct B : A { virtual void foo(); }; +static_assert(sizeof(int B::*) == kSingleDataSize, ""); +// A non-primary base class uses the multiple inheritance model for member +// pointers. +static_assert(sizeof(void (B::*)()) == kMultipleFunctionSize, ""); + +struct AA { int x; virtual void foo(); }; +struct BB : AA { void bar(); }; +struct CC : BB { virtual void baz(); }; +static_assert(sizeof(void (CC::*)()) == kSingleFunctionSize, ""); + +// We start out unspecified. +struct ForwardDecl1; +struct ForwardDecl2; + +// Re-declare to force us to iterate decls when adding attributes. +struct ForwardDecl1; +struct ForwardDecl2; + +typedef int ForwardDecl1::*MemPtr1; +typedef int ForwardDecl2::*MemPtr2; +MemPtr1 variable_forces_sizing; + +struct ForwardDecl1 : B { + virtual void foo(); +}; +struct ForwardDecl2 : B { + virtual void foo(); +}; + +static_assert(sizeof(variable_forces_sizing) == kUnspecifiedDataSize, ""); +static_assert(sizeof(MemPtr1) == kUnspecifiedDataSize, ""); +// FIXME: Clang fails this assert because it locks in the inheritance model at +// the point of the typedef instead of the first usage, while MSVC does not. +//static_assert(sizeof(MemPtr2) == kSingleDataSize, ""); + +struct MemPtrInBody { + typedef int MemPtrInBody::*MemPtr; + int a; + operator MemPtr() const { + return a ? &MemPtrInBody::a : 0; + } +}; + +static_assert(sizeof(MemPtrInBody::MemPtr) == kSingleDataSize, ""); + +// Passing a member pointer through a template should get the right size. +template<typename T> +struct SingleTemplate; +template<typename T> +struct SingleTemplate<void (T::*)(void)> { + static_assert(sizeof(int T::*) == kSingleDataSize, ""); + static_assert(sizeof(void (T::*)()) == kSingleFunctionSize, ""); +}; + +template<typename T> +struct UnspecTemplate; +template<typename T> +struct UnspecTemplate<void (T::*)(void)> { + static_assert(sizeof(int T::*) == kUnspecifiedDataSize, ""); + static_assert(sizeof(void (T::*)()) == kUnspecifiedFunctionSize, ""); +}; + +struct NewUnspecified; +SingleTemplate<void (IncSingle::*)()> tmpl_single; +UnspecTemplate<void (NewUnspecified::*)()> tmpl_unspec; + +struct NewUnspecified { }; + +static_assert(sizeof(void (NewUnspecified::*)()) == kUnspecifiedFunctionSize, ""); + +template <typename T> +struct MemPtrInTemplate { + // We can't require that the template arg be complete until we're + // instantiated. + int T::*data_ptr; + void (T::*func_ptr)(); +}; diff --git a/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp b/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp index 83f83951395c..40bcf45bca32 100644 --- a/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp +++ b/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp @@ -70,7 +70,7 @@ namespace llvm { struct S {}; void bar() { GraphWriter<S> x; //expected-error{{no template named 'GraphWriter'; did you mean 'llvm::GraphWriter'?}} - (void)new llvm::GraphWriter; // expected-error {{use of class template llvm::GraphWriter requires template arguments}} + (void)new llvm::GraphWriter; // expected-error {{use of class template 'llvm::GraphWriter' requires template arguments}} (void)new llvm::Graphwriter<S>; // expected-error {{no template named 'Graphwriter' in namespace 'llvm'; did you mean 'GraphWriter'?}} } diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp index e77e3d652f45..8b352954a331 100644 --- a/test/SemaCXX/new-delete.cpp +++ b/test/SemaCXX/new-delete.cpp @@ -499,3 +499,14 @@ namespace PR12061 { DeferredCookieTaskTest() {} }; } + +class DeletingPlaceholder { + int* f() { + delete f; // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}} + return 0; + } + int* g(int, int) { + delete g; // expected-error {{reference to non-static member function must be called}} + return 0; + } +}; diff --git a/test/SemaCXX/nullptr.cpp b/test/SemaCXX/nullptr.cpp index d148f76698ec..b49f63b98051 100644 --- a/test/SemaCXX/nullptr.cpp +++ b/test/SemaCXX/nullptr.cpp @@ -57,7 +57,7 @@ nullptr_t f(nullptr_t null) o2(nullptr); // expected-error {{ambiguous}} // nullptr is an rvalue, null is an lvalue - (void)&nullptr; // expected-error {{address expression must be an lvalue}} + (void)&nullptr; // expected-error {{cannot take the address of an rvalue of type 'nullptr_t'}} nullptr_t *pn = &null; // You can reinterpret_cast nullptr to an integer. diff --git a/test/SemaCXX/overload-decl.cpp b/test/SemaCXX/overload-decl.cpp index c610ff7ab064..9bba47adfdda 100644 --- a/test/SemaCXX/overload-decl.cpp +++ b/test/SemaCXX/overload-decl.cpp @@ -29,3 +29,6 @@ class X { static void g(float); static void g(int); // expected-error {{static and non-static member functions with the same parameter types cannot be overloaded}} }; + +int main() {} // expected-note {{previous definition is here}} +int main(int,char**) {} // expected-error {{conflicting types for 'main'}} diff --git a/test/SemaCXX/overload-member-call.cpp b/test/SemaCXX/overload-member-call.cpp index 09586201e561..e0f34d937f6f 100644 --- a/test/SemaCXX/overload-member-call.cpp +++ b/test/SemaCXX/overload-member-call.cpp @@ -105,3 +105,11 @@ namespace test1 { } } +namespace b7398190 { + struct S { + int f(); // expected-note {{'this' argument has type 'const b7398190::S', but method is not marked const}} + void f(int); // expected-note {{requires 1 argument, but 0 were provided}} + }; + const S *p; + int k = p->f(); // expected-error {{no matching member function for call to 'f'}} +} diff --git a/test/SemaCXX/overloaded-builtin-operators.cpp b/test/SemaCXX/overloaded-builtin-operators.cpp index 19dc33871630..7899403e2ce3 100644 --- a/test/SemaCXX/overloaded-builtin-operators.cpp +++ b/test/SemaCXX/overloaded-builtin-operators.cpp @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -verify %s -// REQUIRES: LP64 +// RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -verify -triple x86_64-linux-gnu %s struct yes; struct no; diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp index 8ecb54dde6da..e5b3fab33c8c 100644 --- a/test/SemaCXX/overloaded-operator.cpp +++ b/test/SemaCXX/overloaded-operator.cpp @@ -415,3 +415,28 @@ namespace PR11784 { void f(int); void g() { A x; x = f; } } + +namespace test10 { + struct A { + void operator[](float (*fn)(int)); // expected-note 2 {{not viable: no overload of 'bar' matching 'float (*)(int)'}} + }; + + float foo(int); + float foo(float); + + template <class T> T bar(T); + template <class T, class U> T bar(U); + + void test(A &a) { + a[&foo]; + a[foo]; + + a[&bar<int>]; // expected-error {{no viable overloaded operator[]}} + a[bar<int>]; // expected-error {{no viable overloaded operator[]}} + + // If these fail, it's because we're not letting the overload + // resolution for operator| resolve the overload of 'bar'. + a[&bar<float>]; + a[bar<float>]; + } +} diff --git a/test/SemaCXX/pragma-weak.cpp b/test/SemaCXX/pragma-weak.cpp new file mode 100644 index 000000000000..057cf6b463f3 --- /dev/null +++ b/test/SemaCXX/pragma-weak.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s + +#pragma weak foo +static void foo(); +extern "C" { + void foo() { + }; +} diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp index a8f6683ced00..95363e5f6bae 100644 --- a/test/SemaCXX/pseudo-destructors.cpp +++ b/test/SemaCXX/pseudo-destructors.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s struct A {}; enum Foo { F }; @@ -80,3 +80,8 @@ namespace PR11339 { template void destroy(int*); // expected-note{{in instantiation of function template specialization}} } + +template<typename T> using Id = T; +void AliasTemplate(int *p) { + p->~Id<int>(); +} diff --git a/test/SemaCXX/qualified-names-print.cpp b/test/SemaCXX/qualified-names-print.cpp deleted file mode 100644 index 2099268a1a92..000000000000 --- a/test/SemaCXX/qualified-names-print.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -ast-print %s 2>&1 | grep "N::M::X<INT>::value" -namespace N { - namespace M { - template<typename T> - struct X { - enum { value }; - }; - } -} - -typedef int INT; - -int test() { - return N::M::X<INT>::value; -} diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp index 2f98a277f638..580f0a7233e2 100644 --- a/test/SemaCXX/return.cpp +++ b/test/SemaCXX/return.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -Wignored-qualifiers -verify +// RUN: %clang_cc1 %s -std=c++11 -fcxx-exceptions -fexceptions -fsyntax-only -Wignored-qualifiers -verify int test1() { throw; @@ -45,6 +45,27 @@ const j(); const volatile int scalar_cv(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}} + +// FIXME: Maintain enough information that we can point the diagnostic at the 'volatile' keyword. +const +int S::* +volatile +mixed_ret(); // expected-warning {{'volatile' type qualifier on return type has no effect}} + +const int volatile // expected-warning {{'const volatile' type qualifiers on return type have no effect}} + (((parens()))); + +_Atomic(int) atomic(); + +_Atomic // expected-warning {{'_Atomic' type qualifier on return type has no effect}} + int + atomic(); + +auto + trailing_return_type() -> // expected-warning {{'const' type qualifier on return type has no effect}} + const int; + +const int ret_array()[4]; // expected-error {{cannot return array}} } namespace PR9328 { @@ -56,6 +77,7 @@ namespace PR9328 { } class foo { + operator const int (); operator int * const (); }; diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp index 8fd23f4efe91..de276ae3d3d6 100644 --- a/test/SemaCXX/scope-check.cpp +++ b/test/SemaCXX/scope-check.cpp @@ -274,3 +274,15 @@ namespace test15 { goto x; // expected-error {{goto into protected scope}} } } + +namespace test16 { +Invalid inv; // expected-error {{unknown type name}} +// Make sure this doesn't assert. +void fn() +{ + int c = 0; + if (inv) +Here: ; + goto Here; +} +} diff --git a/test/SemaCXX/sourceranges.cpp b/test/SemaCXX/sourceranges.cpp index 0537aa20d5e9..1f25d5bce93c 100644 --- a/test/SemaCXX/sourceranges.cpp +++ b/test/SemaCXX/sourceranges.cpp @@ -7,11 +7,14 @@ class P { }; namespace foo { -class A {}; +class A { public: A() {} }; enum B {}; typedef int C; } +// CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:16:1, col:36> ImplicitConstrArray 'foo::A [2]' +static foo::A ImplicitConstrArray[2]; + int main() { // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::A *' P<foo::A> p14 = new foo::A; diff --git a/test/SemaCXX/storage-class.cpp b/test/SemaCXX/storage-class.cpp index 01cfbfc51faa..74121843e5e4 100644 --- a/test/SemaCXX/storage-class.cpp +++ b/test/SemaCXX/storage-class.cpp @@ -3,5 +3,5 @@ extern const int PR6495a = 42; extern int PR6495b = 42; // expected-warning{{'extern' variable has an initializer}} extern const int PR6495c[] = {42,43,44}; -extern struct Test1 {}; // expected-warning {{'extern' ignored on this declaration}} +extern struct Test1 {}; // expected-warning {{'extern' is not permitted on a declaration of a type}} extern "C" struct Test0 {}; // no warning diff --git a/test/SemaCXX/switch-implicit-fallthrough.cpp b/test/SemaCXX/switch-implicit-fallthrough.cpp index cfc29c237c2d..d7959238c6b3 100644 --- a/test/SemaCXX/switch-implicit-fallthrough.cpp +++ b/test/SemaCXX/switch-implicit-fallthrough.cpp @@ -10,7 +10,7 @@ int fallthrough(int n) { } else if (n - 3) { n = 102; } - case -1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} + case -1: // no warning here, ignore fall-through from unreachable code ; case 0: {// expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} } @@ -34,6 +34,19 @@ int fallthrough(int n) { case 6: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} n += 300; case 66: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}} + case 67: + case 68: + break; + } + switch (n / 15) { +label_default: + default: + n += 333; + if (n % 10) + goto label_default; + break; + case 70: + n += 335; break; } switch (n / 20) { @@ -116,6 +129,22 @@ void fallthrough2(int n) { } } +void fallthrough3(int n) { + switch (n) { + case 1: + do { + return; + } while (0); + case 2: + do { + ClassWithDtor temp; + return; + } while (0); + case 3: + break; + } +} + #define MY_SWITCH(X, Y, Z, U, V) switch (X) { case Y: Z; case U: V; } #define MY_SWITCH2(X, Y, Z) switch (X) { Y; Z; } #define MY_CASE(X, Y) case X: Y @@ -143,40 +172,63 @@ int fallthrough_macro1(int n) { return n; } +void fallthrough_cfgblock_with_null_successor(int x) { + (x && "") ? (void)(0) : (void)(1); + switch (x) {} +} + int fallthrough_position(int n) { switch (n) { + [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} + n += 300; [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}} case 221: - [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} + [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} return 1; [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}} case 222: - [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} + [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} n += 400; case 223: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} } - // TODO: uncomment this test after CFG gets more options to deal with - // unreachable code: - // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20120507/057370.html -#if 0 long p = static_cast<long>(n) * n; switch (sizeof(p)) { - case 9: // this test will not work on compilers with 72-bit long + case 9: n += static_cast<int>(p >> 32); [[clang::fallthrough]]; // no warning here - case 5: // it is not intended to work on compilers with 40-bit long as well + case 5: n += static_cast<int>(p); - break; + [[clang::fallthrough]]; // no warning here default: - break; + n += 1; + break; } -#endif return n; } +enum Enum { + Value1, Value2 +}; + +int fallthrough_covered_enums(Enum e) { + int n = 0; + switch (e) { + default: + n += 17; + [[clang::fallthrough]]; // no warning here, this shouldn't be treated as unreachable code + case Value1: + n += 19; + break; + case Value2: + n += 21; + break; + } + return n; +} + int fallthrough_targets(int n) { [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}} @@ -195,3 +247,21 @@ int fallthrough_targets(int n) { } return n; } + +// Fallthrough annotations in local classes used to generate "fallthrough +// annotation does not directly precede switch label" warning. +void fallthrough_in_local_class() { + class C { + void f(int x) { + switch (x) { + case 0: + x++; + [[clang::fallthrough]]; // no diagnostics + case 1: + x++; + break; + } + } + }; +} + diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index 54294bcbb8b1..aa18ff4e67af 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -39,9 +39,34 @@ struct DerivesEmpty : Empty {}; struct HasCons { HasCons(int); }; struct HasCopyAssign { HasCopyAssign operator =(const HasCopyAssign&); }; struct HasMoveAssign { HasMoveAssign operator =(const HasMoveAssign&&); }; +struct HasNoThrowMoveAssign { + HasNoThrowMoveAssign& operator=( + const HasNoThrowMoveAssign&&) throw(); }; +struct HasNoExceptNoThrowMoveAssign { + HasNoExceptNoThrowMoveAssign& operator=( + const HasNoExceptNoThrowMoveAssign&&) noexcept; +}; +struct HasThrowMoveAssign { + HasThrowMoveAssign& operator=( + const HasThrowMoveAssign&&) throw(POD); }; +struct HasNoExceptFalseMoveAssign { + HasNoExceptFalseMoveAssign& operator=( + const HasNoExceptFalseMoveAssign&&) noexcept(false); }; +struct HasMoveCtor { HasMoveCtor(const HasMoveCtor&&); }; +struct HasMemberMoveCtor { HasMoveCtor member; }; +struct HasMemberMoveAssign { HasMoveAssign member; }; +struct HasStaticMemberMoveCtor { static HasMoveCtor member; }; +struct HasStaticMemberMoveAssign { static HasMoveAssign member; }; +struct HasMemberThrowMoveAssign { HasThrowMoveAssign member; }; +struct HasMemberNoExceptFalseMoveAssign { + HasNoExceptFalseMoveAssign member; }; +struct HasMemberNoThrowMoveAssign { HasNoThrowMoveAssign member; }; +struct HasMemberNoExceptNoThrowMoveAssign { + HasNoExceptNoThrowMoveAssign member; }; + struct HasDefaultTrivialCopyAssign { - HasDefaultTrivialCopyAssign &operator =(const HasDefaultTrivialCopyAssign&) - = default; + HasDefaultTrivialCopyAssign &operator=( + const HasDefaultTrivialCopyAssign&) = default; }; struct TrivialMoveButNotCopy { TrivialMoveButNotCopy &operator=(TrivialMoveButNotCopy&&) = default; @@ -69,6 +94,7 @@ struct DerivesHasPriv : HasPriv {}; struct DerivesHasProt : HasProt {}; struct DerivesHasRef : HasRef {}; struct DerivesHasVirt : HasVirt {}; +struct DerivesHasMoveCtor : HasMoveCtor {}; struct HasNoThrowCopyAssign { void operator =(const HasNoThrowCopyAssign&) throw(); @@ -165,7 +191,7 @@ typedef Empty EmptyAr[10]; struct Bit0 { int : 0; }; struct Bit0Cons { int : 0; Bit0Cons(); }; struct BitOnly { int x : 3; }; -//struct DerivesVirt : virtual POD {}; +struct DerivesVirt : virtual POD {}; void is_empty() { @@ -941,6 +967,19 @@ struct AllDefaulted { ~AllDefaulted() = default; }; +struct NoDefaultMoveAssignDueToUDCopyCtor { + NoDefaultMoveAssignDueToUDCopyCtor(const NoDefaultMoveAssignDueToUDCopyCtor&); +}; + +struct NoDefaultMoveAssignDueToUDCopyAssign { + NoDefaultMoveAssignDueToUDCopyAssign& operator=( + const NoDefaultMoveAssignDueToUDCopyAssign&); +}; + +struct NoDefaultMoveAssignDueToDtor { + ~NoDefaultMoveAssignDueToDtor(); +}; + struct AllDeleted { AllDeleted() = delete; AllDeleted(const AllDeleted &) = delete; @@ -1203,6 +1242,32 @@ void has_trivial_default_constructor() { { int arr[F(__has_trivial_constructor(ExtDefaulted))]; } } +void has_trivial_move_constructor() { + // n3376 12.8 [class.copy]/12 + // A copy/move constructor for class X is trivial if it is not + // user-provided, its declared parameter type is the same as + // if it had been implicitly declared, and if + // — class X has no virtual functions (10.3) and no virtual + // base classes (10.1), and + // — the constructor selected to copy/move each direct base + // class subobject is trivial, and + // — for each non-static data member of X that is of class + // type (or array thereof), the constructor selected + // to copy/move that member is trivial; + // otherwise the copy/move constructor is non-trivial. + { int arr[T(__has_trivial_move_constructor(POD))]; } + { int arr[T(__has_trivial_move_constructor(Union))]; } + { int arr[T(__has_trivial_move_constructor(HasCons))]; } + { int arr[T(__has_trivial_move_constructor(HasStaticMemberMoveCtor))]; } + { int arr[T(__has_trivial_move_constructor(AllDeleted))]; } + + { int arr[F(__has_trivial_move_constructor(HasVirt))]; } + { int arr[F(__has_trivial_move_constructor(DerivesVirt))]; } + { int arr[F(__has_trivial_move_constructor(HasMoveCtor))]; } + { int arr[F(__has_trivial_move_constructor(DerivesHasMoveCtor))]; } + { int arr[F(__has_trivial_move_constructor(HasMemberMoveCtor))]; } +} + void has_trivial_copy_constructor() { { int arr[T(__has_trivial_copy(Int))]; } { int arr[T(__has_trivial_copy(IntAr))]; } @@ -1224,6 +1289,7 @@ void has_trivial_copy_constructor() { { int arr[T(__has_trivial_copy(AllDefaulted))]; } { int arr[T(__has_trivial_copy(AllDeleted))]; } { int arr[T(__has_trivial_copy(DerivesAr))]; } + { int arr[T(__has_trivial_copy(DerivesHasRef))]; } { int arr[F(__has_trivial_copy(HasCopy))]; } { int arr[F(__has_trivial_copy(HasTemplateCons))]; } @@ -1251,6 +1317,7 @@ void has_trivial_copy_assignment() { { int arr[T(__has_trivial_assign(AllDefaulted))]; } { int arr[T(__has_trivial_assign(AllDeleted))]; } { int arr[T(__has_trivial_assign(DerivesAr))]; } + { int arr[T(__has_trivial_assign(DerivesHasRef))]; } { int arr[F(__has_trivial_assign(IntRef))]; } { int arr[F(__has_trivial_assign(HasCopyAssign))]; } @@ -1286,6 +1353,7 @@ void has_trivial_destructor() { { int arr[T(__has_trivial_destructor(VirtAr))]; } { int arr[T(__has_trivial_destructor(AllDefaulted))]; } { int arr[T(__has_trivial_destructor(AllDeleted))]; } + { int arr[T(__has_trivial_destructor(DerivesHasRef))]; } { int arr[F(__has_trivial_destructor(HasDest))]; } { int arr[F(__has_trivial_destructor(void))]; } @@ -1352,6 +1420,54 @@ void has_nothrow_assign() { { int arr[F(__has_nothrow_assign(PR11110))]; } } +void has_nothrow_move_assign() { + { int arr[T(__has_nothrow_move_assign(Int))]; } + { int arr[T(__has_nothrow_move_assign(Enum))]; } + { int arr[T(__has_nothrow_move_assign(Int*))]; } + { int arr[T(__has_nothrow_move_assign(Enum POD::*))]; } + { int arr[T(__has_nothrow_move_assign(POD))]; } + { int arr[T(__has_nothrow_move_assign(HasPriv))]; } + { int arr[T(__has_nothrow_move_assign(HasNoThrowMoveAssign))]; } + { int arr[T(__has_nothrow_move_assign(HasNoExceptNoThrowMoveAssign))]; } + { int arr[T(__has_nothrow_move_assign(HasMemberNoThrowMoveAssign))]; } + { int arr[T(__has_nothrow_move_assign(HasMemberNoExceptNoThrowMoveAssign))]; } + { int arr[T(__has_nothrow_move_assign(AllDeleted))]; } + + + { int arr[F(__has_nothrow_move_assign(HasThrowMoveAssign))]; } + { int arr[F(__has_nothrow_move_assign(HasNoExceptFalseMoveAssign))]; } + { int arr[F(__has_nothrow_move_assign(HasMemberThrowMoveAssign))]; } + { int arr[F(__has_nothrow_move_assign(HasMemberNoExceptFalseMoveAssign))]; } + { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyCtor))]; } + { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyAssign))]; } + { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToDtor))]; } +} + +void has_trivial_move_assign() { + // n3376 12.8 [class.copy]/25 + // A copy/move assignment operator for class X is trivial if it + // is not user-provided, its declared parameter type is the same + // as if it had been implicitly declared, and if: + // — class X has no virtual functions (10.3) and no virtual base + // classes (10.1), and + // — the assignment operator selected to copy/move each direct + // base class subobject is trivial, and + // — for each non-static data member of X that is of class type + // (or array thereof), the assignment operator + // selected to copy/move that member is trivial; + { int arr[T(__has_trivial_move_assign(Int))]; } + { int arr[T(__has_trivial_move_assign(HasStaticMemberMoveAssign))]; } + { int arr[T(__has_trivial_move_assign(AllDeleted))]; } + + { int arr[F(__has_trivial_move_assign(HasVirt))]; } + { int arr[F(__has_trivial_move_assign(DerivesVirt))]; } + { int arr[F(__has_trivial_move_assign(HasMoveAssign))]; } + { int arr[F(__has_trivial_move_assign(DerivesHasMoveAssign))]; } + { int arr[F(__has_trivial_move_assign(HasMemberMoveAssign))]; } + { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyCtor))]; } + { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyAssign))]; } +} + void has_nothrow_copy() { { int arr[T(__has_nothrow_copy(Int))]; } { int arr[T(__has_nothrow_copy(IntAr))]; } diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp index c21ef51a7da5..caa6355fe958 100644 --- a/test/SemaCXX/typo-correction.cpp +++ b/test/SemaCXX/typo-correction.cpp @@ -236,3 +236,27 @@ void test() { return status; // expected-error-re{{use of undeclared identifier 'status'$}} } } + +namespace PR13387 { +struct A { + void CreateFoo(float, float); // expected-note {{'CreateFoo' declared here}} + void CreateBar(float, float); +}; +struct B : A { + using A::CreateFoo; + void CreateFoo(int, int); +}; +void f(B &x) { + x.Createfoo(0,0); // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}} +} +} + +struct DataStruct {void foo();}; +struct T { + DataStruct data_struct; + void f(); +}; +// should be void T::f(); +void f() { + data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'$}} +} diff --git a/test/SemaCXX/undefined-inline.cpp b/test/SemaCXX/undefined-inline.cpp new file mode 100644 index 000000000000..ad719ae03abb --- /dev/null +++ b/test/SemaCXX/undefined-inline.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// PR14993 + +namespace test1 { + inline void f(); // expected-warning{{inline function 'test1::f' is not defined}} + void test() { f(); } // expected-note{{used here}} +} + +namespace test2 { + inline int f(); + void test() { (void)sizeof(f()); } +} + +namespace test3 { + void f(); // expected-warning{{inline function 'test3::f' is not defined}} + inline void f(); + void test() { f(); } // expected-note{{used here}} +} + +namespace test4 { + inline void error_on_zero(int); // expected-warning{{inline function 'test4::error_on_zero' is not defined}} + inline void error_on_zero(char*) {} + void test() { error_on_zero(0); } // expected-note{{used here}} +} + +namespace test5 { + struct X { void f(); }; + void test(X &x) { x.f(); } +} + +namespace test6 { + struct X { inline void f(); }; // expected-warning{{inline function 'test6::X::f' is not defined}} + void test(X &x) { x.f(); } // expected-note{{used here}} +} + +namespace test7 { + void f(); // expected-warning{{inline function 'test7::f' is not defined}} + void test() { f(); } // no used-here note. + inline void f(); +} + +namespace test8 { + inline void foo() __attribute__((gnu_inline)); + void test() { foo(); } +} + +namespace test9 { + void foo(); + void test() { foo(); } + inline void foo() __attribute__((gnu_inline)); +} + +namespace test10 { + inline void foo(); + void test() { foo(); } + inline void foo() __attribute__((gnu_inline)); +} diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp index 154172001e76..839fdafb3418 100644 --- a/test/SemaCXX/undefined-internal.cpp +++ b/test/SemaCXX/undefined-internal.cpp @@ -181,3 +181,145 @@ namespace OverloadUse { template<void x(int)> void t(long*) { x(10); } // expected-note {{used here}} void g() { long a; t<f>(&a); } } + +namespace test7 { + typedef struct { + void bar(); + void foo() { + bar(); + } + } A; +} + +namespace test8 { + typedef struct { + void bar(); // expected-warning {{function 'test8::<anonymous struct>::bar' has internal linkage but is not defined}} + void foo() { + bar(); // expected-note {{used here}} + } + } *A; +} + +namespace test9 { + namespace { + struct X { + virtual void notused() = 0; + virtual void used() = 0; // expected-warning {{function 'test9::<anonymous namespace>::X::used' has internal linkage but is not defined}} + }; + } + void test(X &x) { + x.notused(); + x.X::used(); // expected-note {{used here}} + } +} + +namespace test10 { + namespace { + struct X { + virtual void notused() = 0; + virtual void used() = 0; // expected-warning {{function 'test10::<anonymous namespace>::X::used' has internal linkage but is not defined}} + + void test() { + notused(); + (void)&X::notused; + (this->*&X::notused)(); + X::used(); // expected-note {{used here}} + } + }; + struct Y : X { + using X::notused; + }; + } +} + +namespace test11 { + namespace { + struct A { + virtual bool operator()() const = 0; + virtual void operator!() const = 0; + virtual bool operator+(const A&) const = 0; + virtual int operator[](int) const = 0; + virtual const A* operator->() const = 0; + int member; + }; + + struct B { + bool operator()() const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator()' has internal linkage but is not defined}} + void operator!() const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator!' has internal linkage but is not defined}} + bool operator+(const B&) const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator+' has internal linkage but is not defined}} + int operator[](int) const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator[]' has internal linkage but is not defined}} + const B* operator->() const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator->' has internal linkage but is not defined}} + int member; + }; + } + + void test1(A &a1, A &a2) { + a1(); + !a1; + a1 + a2; + a1[0]; + (void)a1->member; + } + + void test2(B &b1, B &b2) { + b1(); // expected-note {{used here}} + !b1; // expected-note {{used here}} + b1 + b2; // expected-note {{used here}} + b1[0]; // expected-note {{used here}} + (void)b1->member; // expected-note {{used here}} + } +} + +namespace test12 { + class T1 {}; class T2 {}; class T3 {}; class T4 {}; class T5 {}; class T6 {}; + class T7 {}; + + namespace { + struct Cls { + virtual void f(int) = 0; + virtual void f(int, double) = 0; + void g(int); // expected-warning {{function 'test12::<anonymous namespace>::Cls::g' has internal linkage but is not defined}} + void g(int, double); + virtual operator T1() = 0; + virtual operator T2() = 0; + virtual operator T3&() = 0; + operator T4(); // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T4' has internal linkage but is not defined}} + operator T5(); // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T5' has internal linkage but is not defined}} + operator T6&(); // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator class test12::T6 &' has internal linkage but is not defined}} + }; + + struct Cls2 { + Cls2(T7); // expected-warning {{function 'test12::<anonymous namespace>::Cls2::Cls2' has internal linkage but is not defined}} + }; + } + + void test(Cls &c) { + c.f(7); + c.g(7); // expected-note {{used here}} + (void)static_cast<T1>(c); + T2 t2 = c; + T3 &t3 = c; + (void)static_cast<T4>(c); // expected-note {{used here}} + T5 t5 = c; // expected-note {{used here}} + T6 &t6 = c; // expected-note {{used here}} + + Cls2 obj1((T7())); // expected-note {{used here}} + } +} + +namespace test13 { + namespace { + struct X { + virtual void f() { } + }; + + struct Y : public X { + virtual void f() = 0; + + virtual void g() { + X::f(); + } + }; + } +} + diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp index f55f10f7edaa..2aa56623f699 100644 --- a/test/SemaCXX/uninitialized.cpp +++ b/test/SemaCXX/uninitialized.cpp @@ -41,8 +41,8 @@ void test_stuff () { int j = far(j); int k = __alignof__(k); - int l = k ? l : l; // FIXME: warn here - int m = 1 + (k ? m : m); // FIXME: warn here + int l = k ? l : l; // expected-warning {{variable 'l' is uninitialized when used within its own initialization}} + int m = 1 + (k ? m : m); // expected-warning {{'m' is uninitialized when used within its own initialization}} int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}} for (;;) { @@ -61,8 +61,8 @@ void test_stuff () { int j = far(j); int k = __alignof__(k); - int l = k ? l : l; // FIXME: warn here - int m = 1 + (k ? m : m); // FIXME: warn here + int l = k ? l : l; // expected-warning {{variable 'l' is uninitialized when used within its own initialization}} + int m = 1 + (k ? m : m); // expected-warning {{'m' is uninitialized when used within its own initialization}} int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}} } } @@ -406,11 +406,11 @@ namespace statics { void test() { static int a = a; // no-warning: used to signal intended lack of initialization. - static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}} - static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}} - static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}} - static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}} - static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}} + static int b = b + 1; // expected-warning {{static variable 'b' is suspiciously used within its own initialization}} + static int c = (c + c); // expected-warning 2{{static variable 'c' is suspiciously used within its own initialization}} + static int d = ({ d + d ;}); // expected-warning 2{{static variable 'd' is suspiciously used within its own initialization}} + static int e = static_cast<long>(e) + 1; // expected-warning {{static variable 'e' is suspiciously used within its own initialization}} + static int f = foo(f); // expected-warning {{static variable 'f' is suspiciously used within its own initialization}} // Thes don't warn as they don't require the value. static int g = sizeof(g); @@ -420,16 +420,16 @@ namespace statics { static int j = far(j); static int k = __alignof__(k); - static int l = k ? l : l; // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}} - static int m = 1 + (k ? m : m); // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}} - static int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}} + static int l = k ? l : l; // expected-warning 2{{static variable 'l' is suspiciously used within its own initialization}} + static int m = 1 + (k ? m : m); // expected-warning 2{{static variable 'm' is suspiciously used within its own initialization}} + static int n = -n; // expected-warning {{static variable 'n' is suspiciously used within its own initialization}} for (;;) { static int a = a; // no-warning: used to signal intended lack of initialization. - static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}} - static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}} - static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}} - static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}} - static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}} + static int b = b + 1; // expected-warning {{static variable 'b' is suspiciously used within its own initialization}} + static int c = (c + c); // expected-warning 2{{static variable 'c' is suspiciously used within its own initialization}} + static int d = ({ d + d ;}); // expected-warning 2{{static variable 'd' is suspiciously used within its own initialization}} + static int e = static_cast<long>(e) + 1; // expected-warning {{static variable 'e' is suspiciously used within its own initialization}} + static int f = foo(f); // expected-warning {{static variable 'f' is suspiciously used within its own initialization}} // Thes don't warn as they don't require the value. static int g = sizeof(g); @@ -439,9 +439,9 @@ namespace statics { static int j = far(j); static int k = __alignof__(k); - static int l = k ? l : l; // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}} - static int m = 1 + (k ? m : m); // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}} - static int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}} + static int l = k ? l : l; // expected-warning 2{{static variable 'l' is suspiciously used within its own initialization}} + static int m = 1 + (k ? m : m); // expected-warning 2{{static variable 'm' is suspiciously used within its own initialization}} + static int n = -n; // expected-warning {{static variable 'n' is suspiciously used within its own initialization}} } } } @@ -496,3 +496,18 @@ namespace references { int &b; }; } + +namespace operators { + struct A { + A(bool); + bool operator==(A); + }; + + A makeA(); + + A a1 = a1 = makeA(); // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}} + A a2 = a2 == a1; // expected-warning{{variable 'a2' is uninitialized when used within its own initialization}} + A a3 = a2 == a3; // expected-warning{{variable 'a3' is uninitialized when used within its own initialization}} + + int x = x = 5; +} diff --git a/test/SemaCXX/virtual-override-x64.cpp b/test/SemaCXX/virtual-override-x64.cpp new file mode 100644 index 000000000000..8d5aad8889df --- /dev/null +++ b/test/SemaCXX/virtual-override-x64.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-unknown -fsyntax-only -verify %s + +// Non-x86 targets ignore the calling conventions by default (but will warn +// when one is encountered), so we want to make sure the virtual overrides +// continue to work. +namespace PR14339 { + class A { + public: + virtual void __attribute__((thiscall)) f(); // expected-warning {{calling convention 'thiscall' ignored for this target}} + }; + + class B : public A { + public: + void __attribute__((cdecl)) f(); + }; + + class C : public A { + public: + void __attribute__((thiscall)) f(); // expected-warning {{calling convention 'thiscall' ignored for this target}} + }; + + class D : public A { + public: + void f(); + }; + + class E { + public: + virtual void __attribute__((stdcall)) g(); // expected-warning {{calling convention 'stdcall' ignored for this target}} + }; + + class F : public E { + public: + void g(); + }; +} diff --git a/test/SemaCXX/virtual-override-x86.cpp b/test/SemaCXX/virtual-override-x86.cpp new file mode 100644 index 000000000000..ad70d3f22437 --- /dev/null +++ b/test/SemaCXX/virtual-override-x86.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple=i686-pc-unknown -fsyntax-only -verify %s -std=c++11 + +namespace PR14339 { + class A { + public: + virtual void __attribute__((thiscall)) f(); // expected-note{{overridden virtual function is here}} + }; + + class B : public A { + public: + void __attribute__((cdecl)) f(); // expected-error{{virtual function 'f' has different calling convention attributes ('void () __attribute__((cdecl))') than the function it overrides (which has calling convention 'void () __attribute__((thiscall))'}} + }; + + class C : public A { + public: + void __attribute__((thiscall)) f(); // This override is correct + }; + + class D : public A { + public: + void f(); // This override is correct because thiscall is the default calling convention for class members + }; + + class E { + public: + virtual void __attribute__((stdcall)) g(); // expected-note{{overridden virtual function is here}} + }; + + class F : public E { + public: + void g(); // expected-error{{virtual function 'g' has different calling convention attributes ('void ()') than the function it overrides (which has calling convention 'void () __attribute__((stdcall))'}} + }; +} diff --git a/test/SemaCXX/visibility.cpp b/test/SemaCXX/visibility.cpp new file mode 100644 index 000000000000..434b3c06c1c5 --- /dev/null +++ b/test/SemaCXX/visibility.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only %s + +namespace test1 { + template <class C> + struct C2 + { + static int p __attribute__((visibility("hidden"))); + }; + int f() { + return C2<int>::p; + } +} diff --git a/test/SemaCXX/warn-bad-memaccess.cpp b/test/SemaCXX/warn-bad-memaccess.cpp index 3a02c84e9fc4..7a7459acee1d 100644 --- a/test/SemaCXX/warn-bad-memaccess.cpp +++ b/test/SemaCXX/warn-bad-memaccess.cpp @@ -5,6 +5,11 @@ extern "C" void *memmove(void *s1, const void *s2, unsigned n); extern "C" void *memcpy(void *s1, const void *s2, unsigned n); extern "C" void *memcmp(void *s1, const void *s2, unsigned n); + +// Redeclare without the extern "C" to test that we still figure out that this +// is the "real" memset. +void *memset(void *, int, unsigned); + // Several types that should not warn. struct S1 {} s1; struct S2 { int x; } s2; diff --git a/test/SemaCXX/warn-enum-compare.cpp b/test/SemaCXX/warn-enum-compare.cpp index c68275e1a73e..0c287948cd09 100644 --- a/test/SemaCXX/warn-enum-compare.cpp +++ b/test/SemaCXX/warn-enum-compare.cpp @@ -39,8 +39,8 @@ void test () { while (b == c); while (B1 == name1::B2); while (B2 == name2::B1); - while (x == AnonAA); // expected-warning {{comparison of constant 42 with expression of type 'Foo' is always false}} - while (AnonBB == y); // expected-warning {{comparison of constant 45 with expression of type 'Bar' is always false}} + while (x == AnonAA); // expected-warning {{comparison of constant 'AnonAA' (42) with expression of type 'Foo' is always false}} + while (AnonBB == y); // expected-warning {{comparison of constant 'AnonBB' (45) with expression of type 'Bar' is always false}} while (AnonAA == AnonAB); while (AnonAB == AnonBA); while (AnonBB == AnonAA); diff --git a/test/SemaCXX/warn-func-not-needed.cpp b/test/SemaCXX/warn-func-not-needed.cpp new file mode 100644 index 000000000000..d51c17356632 --- /dev/null +++ b/test/SemaCXX/warn-func-not-needed.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wall %s + +namespace test1 { + static void f() {} // expected-warning {{is not needed and will not be emitted}} + static void f(); + template <typename T> + void foo() { + f(); + } +} + +namespace test2 { + static void f() {} + static void f(); + static void g() { f(); } + void h() { g(); } +} + +namespace test3 { + static void f(); + template<typename T> + static void g() { + f(); + } + static void f() { + } + void h() { + g<int>(); + } +} + +namespace test4 { + static void f(); + static void f(); + template<typename T> + static void g() { + f(); + } + static void f() { + } + void h() { + g<int>(); + } +} diff --git a/test/SemaCXX/warn-reinterpret-base-class.cpp b/test/SemaCXX/warn-reinterpret-base-class.cpp new file mode 100644 index 000000000000..67902f7a90d8 --- /dev/null +++ b/test/SemaCXX/warn-reinterpret-base-class.cpp @@ -0,0 +1,323 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s + +// PR 13824 +class A { +}; +class DA : public A { +}; +class DDA : public DA { +}; +class DAo : protected A { +}; +class DAi : private A { +}; + +class DVA : public virtual A { +}; +class DDVA : public virtual DA { +}; +class DMA : public virtual A, public virtual DA { +}; + +class B; + +struct C { + // Do not fail on incompletely-defined classes. + decltype(reinterpret_cast<C *>(0)) foo; + decltype(reinterpret_cast<A *>((C *) 0)) bar; + decltype(reinterpret_cast<C *>((A *) 0)) baz; +}; + +void reinterpret_not_defined_class(B *b, C *c) { + // Should not fail if class has no definition. + (void)*reinterpret_cast<C *>(b); + (void)*reinterpret_cast<B *>(c); + + (void)reinterpret_cast<C &>(*b); + (void)reinterpret_cast<B &>(*c); +} + +// Do not fail on erroneous classes with fields of incompletely-defined types. +// Base class is malformed. +namespace BaseMalformed { + struct A; // expected-note {{forward declaration of 'BaseMalformed::A'}} + struct B { + A a; // expected-error {{field has incomplete type 'BaseMalformed::A'}} + }; + struct C : public B {} c; + B *b = reinterpret_cast<B *>(&c); +} // end anonymous namespace + +// Child class is malformed. +namespace ChildMalformed { + struct A; // expected-note {{forward declaration of 'ChildMalformed::A'}} + struct B {}; + struct C : public B { + A a; // expected-error {{field has incomplete type 'ChildMalformed::A'}} + } c; + B *b = reinterpret_cast<B *>(&c); +} // end anonymous namespace + +// Base class outside upcast base-chain is malformed. +namespace BaseBaseMalformed { + struct A; // expected-note {{forward declaration of 'BaseBaseMalformed::A'}} + struct Y {}; + struct X { A a; }; // expected-error {{field has incomplete type 'BaseBaseMalformed::A'}} + struct B : Y, X {}; + struct C : B {} c; + B *p = reinterpret_cast<B*>(&c); +} + +namespace InheritanceMalformed { + struct A; // expected-note {{forward declaration of 'InheritanceMalformed::A'}} + struct B : A {}; // expected-error {{base class has incomplete type}} + struct C : B {} c; + B *p = reinterpret_cast<B*>(&c); +} + +// Virtual base class outside upcast base-chain is malformed. +namespace VBaseMalformed{ + struct A; // expected-note {{forward declaration of 'VBaseMalformed::A'}} + struct X { A a; }; // expected-error {{field has incomplete type 'VBaseMalformed::A'}} + struct B : public virtual X {}; + struct C : B {} c; + B *p = reinterpret_cast<B*>(&c); +} + +void reinterpret_not_updowncast(A *pa, const A *pca, A &a, const A &ca) { + (void)*reinterpret_cast<C *>(pa); + (void)*reinterpret_cast<const C *>(pa); + (void)*reinterpret_cast<volatile C *>(pa); + (void)*reinterpret_cast<const volatile C *>(pa); + + (void)*reinterpret_cast<const C *>(pca); + (void)*reinterpret_cast<const volatile C *>(pca); + + (void)reinterpret_cast<C &>(a); + (void)reinterpret_cast<const C &>(a); + (void)reinterpret_cast<volatile C &>(a); + (void)reinterpret_cast<const volatile C &>(a); + + (void)reinterpret_cast<const C &>(ca); + (void)reinterpret_cast<const volatile C &>(ca); +} + +void reinterpret_pointer_downcast(A *a, const A *ca) { + (void)*reinterpret_cast<DA *>(a); + (void)*reinterpret_cast<const DA *>(a); + (void)*reinterpret_cast<volatile DA *>(a); + (void)*reinterpret_cast<const volatile DA *>(a); + + (void)*reinterpret_cast<const DA *>(ca); + (void)*reinterpret_cast<const volatile DA *>(ca); + + (void)*reinterpret_cast<DDA *>(a); + (void)*reinterpret_cast<DAo *>(a); + (void)*reinterpret_cast<DAi *>(a); + // expected-warning@+2 {{'reinterpret_cast' to class 'DVA *' from its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)*reinterpret_cast<DVA *>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA *' from its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)*reinterpret_cast<DDVA *>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' to class 'DMA *' from its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)*reinterpret_cast<DMA *>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" +} + +void reinterpret_reference_downcast(A a, A &ra, const A &cra) { + (void)reinterpret_cast<DA &>(a); + (void)reinterpret_cast<const DA &>(a); + (void)reinterpret_cast<volatile DA &>(a); + (void)reinterpret_cast<const volatile DA &>(a); + + (void)reinterpret_cast<DA &>(ra); + (void)reinterpret_cast<const DA &>(ra); + (void)reinterpret_cast<volatile DA &>(ra); + (void)reinterpret_cast<const volatile DA &>(ra); + + (void)reinterpret_cast<const DA &>(cra); + (void)reinterpret_cast<const volatile DA &>(cra); + + (void)reinterpret_cast<DDA &>(a); + (void)reinterpret_cast<DAo &>(a); + (void)reinterpret_cast<DAi &>(a); + // expected-warning@+2 {{'reinterpret_cast' to class 'DVA &' from its virtual base 'A' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<DVA &>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA &' from its virtual base 'A' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<DDVA &>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' to class 'DMA &' from its virtual base 'A' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<DMA &>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" +} + +void reinterpret_pointer_upcast(DA *da, const DA *cda, DDA *dda, DAo *dao, + DAi *dai, DVA *dva, DDVA *ddva, DMA *dma) { + (void)*reinterpret_cast<A *>(da); + (void)*reinterpret_cast<const A *>(da); + (void)*reinterpret_cast<volatile A *>(da); + (void)*reinterpret_cast<const volatile A *>(da); + + (void)*reinterpret_cast<const A *>(cda); + (void)*reinterpret_cast<const volatile A *>(cda); + + (void)*reinterpret_cast<A *>(dda); + (void)*reinterpret_cast<DA *>(dda); + (void)*reinterpret_cast<A *>(dao); + (void)*reinterpret_cast<A *>(dai); + // expected-warning@+2 {{'reinterpret_cast' from class 'DVA *' to its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)*reinterpret_cast<A *>(dva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)*reinterpret_cast<A *>(ddva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'DA *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)*reinterpret_cast<DA *>(ddva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)*reinterpret_cast<A *>(dma); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'DA *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)*reinterpret_cast<DA *>(dma); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" +} + +void reinterpret_reference_upcast(DA &da, const DA &cda, DDA &dda, DAo &dao, + DAi &dai, DVA &dva, DDVA &ddva, DMA &dma) { + (void)reinterpret_cast<A &>(da); + (void)reinterpret_cast<const A &>(da); + (void)reinterpret_cast<volatile A &>(da); + (void)reinterpret_cast<const volatile A &>(da); + + (void)reinterpret_cast<const A &>(cda); + (void)reinterpret_cast<const volatile A &>(cda); + + (void)reinterpret_cast<A &>(dda); + (void)reinterpret_cast<DA &>(dda); + (void)reinterpret_cast<A &>(dao); + (void)reinterpret_cast<A &>(dai); + // expected-warning@+2 {{'reinterpret_cast' from class 'DVA' to its virtual base 'A &' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<A &>(dva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'A &' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<A &>(ddva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'DA &' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<DA &>(ddva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'A &' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<A &>(dma); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'DA &' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<DA &>(dma); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" +} + +struct E { + int x; +}; + +class F : public E { + virtual int foo() { return x; } +}; + +class G : public F { +}; + +class H : public E, public A { +}; + +class I : virtual public F { +}; + +typedef const F * K; +typedef volatile K L; + +void different_subobject_downcast(E *e, F *f, A *a) { + // expected-warning@+2 {{'reinterpret_cast' to class 'F *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<F *>(e); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' to class 'G *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<G *>(e); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + (void)reinterpret_cast<H *>(e); + // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<I *>(e); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + + (void)reinterpret_cast<G *>(f); + // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'F *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<I *>(f); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + (void)reinterpret_cast<H *>(a); + + // expected-warning@+2 {{'reinterpret_cast' to class 'L' (aka 'const F *volatile') from its base at non-zero offset 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<L>(e); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" +} + +void different_subobject_upcast(F *f, G *g, H *h, I *i) { + // expected-warning@+2 {{'reinterpret_cast' from class 'F *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<E *>(f); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + (void)reinterpret_cast<F *>(g); + // expected-warning@+2 {{'reinterpret_cast' from class 'G *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<E *>(g); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + (void)reinterpret_cast<E *>(h); + (void)reinterpret_cast<A *>(h); + + // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'F *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<F *>(i); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<E *>(i); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" +} diff --git a/test/SemaCXX/warn-reorder-ctor-initialization.cpp b/test/SemaCXX/warn-reorder-ctor-initialization.cpp index 8c254e5515bf..6d38ec95fbfb 100644 --- a/test/SemaCXX/warn-reorder-ctor-initialization.cpp +++ b/test/SemaCXX/warn-reorder-ctor-initialization.cpp @@ -130,3 +130,14 @@ namespace PR7179 { }; }; } + +namespace test3 { + struct foo { + struct { + int a; + int b; + }; + foo() : b(), a() { // expected-warning {{field 'b' will be initialized after field 'a'}} + } + }; +} diff --git a/test/SemaCXX/warn-static-const-float.cpp b/test/SemaCXX/warn-static-const-float.cpp new file mode 100644 index 000000000000..481a410489bb --- /dev/null +++ b/test/SemaCXX/warn-static-const-float.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -verify %s -std=c++98 -DEXT +// RUN: %clang_cc1 -verify %s -std=c++98 -Wno-gnu -DNONE +// RUN: %clang_cc1 -verify %s -std=c++98 -Wno-static-float-init -DNONE +// RUN: %clang_cc1 -verify %s -std=c++98 -Wno-gnu-static-float-init -DNONE +// RUN: %clang_cc1 -verify %s -std=c++11 -DERR +// RUN: %clang_cc1 -verify %s -std=c++11 -Wno-gnu -DERR +// RUN: %clang_cc1 -verify %s -std=c++11 -Wno-static-float-init -DNONE +// RUN: %clang_cc1 -verify %s -std=c++11 -Wno-gnu-static-float-init -DERR + +#if NONE +// expected-no-diagnostics +#elif ERR +// expected-error@20 {{in-class initializer for static data member of type 'const double' requires 'constexpr' specifier}} +// expected-note@20 {{add 'constexpr'}} +#elif EXT +// expected-warning@20 {{in-class initializer for static data member of type 'const double' is a GNU extension}} +#endif + +struct X { + static const double x = 0.0; +}; diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp index bd555ac56c36..3f41124d47ab 100644 --- a/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -fcxx-exceptions %s // 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 @@ -3712,3 +3712,206 @@ void Foo::test() { } // end namespace MultipleAttributeTest +namespace GuardedNonPrimitiveTypeTest { + + +class Data { +public: + Data(int i) : dat(i) { } + + int getValue() const { return dat; } + void setValue(int i) { dat = i; } + + int operator[](int i) const { return dat; } + int& operator[](int i) { return dat; } + + void operator()() { } + +private: + int dat; +}; + + +class DataCell { +public: + DataCell(const Data& d) : dat(d) { } + +private: + Data dat; +}; + + +void showDataCell(const DataCell& dc); + + +class Foo { +public: + // method call tests + void test() { + data_.setValue(0); // FIXME -- should be writing \ + // expected-warning {{reading variable 'data_' requires locking 'mu_'}} + int a = data_.getValue(); // \ + // expected-warning {{reading variable 'data_' requires locking 'mu_'}} + + datap1_->setValue(0); // FIXME -- should be writing \ + // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} + a = datap1_->getValue(); // \ + // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} + + datap2_->setValue(0); // FIXME -- should be writing \ + // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} + a = datap2_->getValue(); // \ + // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} + + (*datap2_).setValue(0); // FIXME -- should be writing \ + // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} + a = (*datap2_).getValue(); // \ + // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} + + mu_.Lock(); + data_.setValue(1); + datap1_->setValue(1); + datap2_->setValue(1); + mu_.Unlock(); + + mu_.ReaderLock(); + a = data_.getValue(); + datap1_->setValue(0); // reads datap1_, writes *datap1_ + a = datap1_->getValue(); + a = datap2_->getValue(); + mu_.Unlock(); + } + + // operator tests + void test2() { + data_ = Data(1); // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} + *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} \ + // expected-warning {{reading variable 'data_' requires locking 'mu_'}} + *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires locking 'mu_' exclusively}} \ + // expected-warning {{reading variable 'data_' requires locking 'mu_'}} + data_ = *datap1_; // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \ + // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} + data_ = *datap2_; // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \ + // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} + + data_[0] = 0; // expected-warning {{reading variable 'data_' requires locking 'mu_'}} + (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} + + data_(); // expected-warning {{reading variable 'data_' requires locking 'mu_'}} + } + + // const operator tests + void test3() const { + Data mydat(data_); // expected-warning {{reading variable 'data_' requires locking 'mu_'}} + + //FIXME + //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires locking 'mu_'}} + //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} + + int a = data_[0]; // expected-warning {{reading variable 'data_' requires locking 'mu_'}} + } + +private: + Mutex mu_; + Data data_ GUARDED_BY(mu_); + Data* datap1_ GUARDED_BY(mu_); + Data* datap2_ PT_GUARDED_BY(mu_); +}; + +} // end namespace GuardedNonPrimitiveTypeTest + + +namespace GuardedNonPrimitive_MemberAccess { + +class Cell { +public: + Cell(int i); + + void cellMethod(); + + int a; +}; + + +class Foo { +public: + int a; + Cell c GUARDED_BY(cell_mu_); + Cell* cp PT_GUARDED_BY(cell_mu_); + + void myMethod(); + + Mutex cell_mu_; +}; + + +class Bar { +private: + Mutex mu_; + Foo foo GUARDED_BY(mu_); + Foo* foop PT_GUARDED_BY(mu_); + + void test() { + foo.myMethod(); // expected-warning {{reading variable 'foo' requires locking 'mu_'}} + + int fa = foo.a; // expected-warning {{reading variable 'foo' requires locking 'mu_'}} + foo.a = fa; // expected-warning {{writing variable 'foo' requires locking 'mu_' exclusively}} + + fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} + foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}} + + fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} + (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}} + + foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires locking 'mu_'}} \ + // expected-warning {{writing variable 'c' requires locking 'foo.cell_mu_' exclusively}} + foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires locking 'mu_'}} \ + // expected-warning {{reading variable 'c' requires locking 'foo.cell_mu_'}} + + foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \ + // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}} + foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \ + // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}} + + (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \ + // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}} + (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \ + // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}} + }; +}; + +} // namespace GuardedNonPrimitive_MemberAccess + + +namespace TestThrowExpr { + +class Foo { + Mutex mu_; + + bool hasError(); + + void test() { + mu_.Lock(); + if (hasError()) { + throw "ugly"; + } + mu_.Unlock(); + } +}; + +} // end namespace TestThrowExpr + + +namespace UnevaluatedContextTest { + +// parse attribute expressions in an unevaluated context. + +static inline Mutex* getMutex1(); +static inline Mutex* getMutex2(); + +void bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1()); + +void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2()); + +} // end namespace UnevaluatedContextTest + diff --git a/test/SemaCXX/warn-unsequenced.cpp b/test/SemaCXX/warn-unsequenced.cpp new file mode 100644 index 000000000000..c7acfca6db31 --- /dev/null +++ b/test/SemaCXX/warn-unsequenced.cpp @@ -0,0 +1,103 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-unused %s + +int f(int, int); + +struct A { + int x, y; +}; +struct S { + S(int, int); +}; + +void test() { + int a; + int xs[10]; + ++a = 0; // ok + a + ++a; // expected-warning {{unsequenced modification and access to 'a'}} + a = ++a; // ok + a + a++; // expected-warning {{unsequenced modification and access to 'a'}} + a = a++; // expected-warning {{multiple unsequenced modifications to 'a'}} + ++ ++a; // ok + (a++, a++); // ok + ++a + ++a; // expected-warning {{multiple unsequenced modifications to 'a'}} + a++ + a++; // expected-warning {{multiple unsequenced modifications}} + (a++, a) = 0; // ok, increment is sequenced before value computation of LHS + a = xs[++a]; // ok + a = xs[a++]; // expected-warning {{multiple unsequenced modifications}} + (a ? xs[0] : xs[1]) = ++a; // expected-warning {{unsequenced modification and access}} + a = (++a, ++a); // ok + a = (a++, ++a); // ok + a = (a++, a++); // expected-warning {{multiple unsequenced modifications}} + f(a, a); // ok + f(a = 0, a); // expected-warning {{unsequenced modification and access}} + f(a, a += 0); // expected-warning {{unsequenced modification and access}} + f(a = 0, a = 0); // expected-warning {{multiple unsequenced modifications}} + + // Compound assignment "A OP= B" is equivalent to "A = A OP B" except that A + // is evaluated only once. + (++a, a) = 1; // ok + (++a, a) += 1; // ok + a = ++a; // ok + a += ++a; // expected-warning {{unsequenced modification and access}} + + A agg1 = { a++, a++ }; // ok + A agg2 = { a++ + a, a++ }; // expected-warning {{unsequenced modification and access}} + + S str1(a++, a++); // expected-warning {{multiple unsequenced modifications}} + S str2 = { a++, a++ }; // ok + S str3 = { a++ + a, a++ }; // expected-warning {{unsequenced modification and access}} + + (xs[2] && (a = 0)) + a; // ok + (0 && (a = 0)) + a; // ok + (1 && (a = 0)) + a; // expected-warning {{unsequenced modification and access}} + + (xs[3] || (a = 0)) + a; // ok + (0 || (a = 0)) + a; // expected-warning {{unsequenced modification and access}} + (1 || (a = 0)) + a; // ok + + (xs[4] ? a : ++a) + a; // ok + (0 ? a : ++a) + a; // expected-warning {{unsequenced modification and access}} + (1 ? a : ++a) + a; // ok + (xs[5] ? ++a : ++a) + a; // FIXME: warn here + + (++a, xs[6] ? ++a : 0) + a; // expected-warning {{unsequenced modification and access}} + + // Here, the read of the fourth 'a' might happen before or after the write to + // the second 'a'. + a += (a++, a) + a; // expected-warning {{unsequenced modification and access}} + + int *p = xs; + a = *(a++, p); // ok + a = a++ && a; // ok + + A *q = &agg1; + (q = &agg2)->y = q->x; // expected-warning {{unsequenced modification and access to 'q'}} + + // This has undefined behavior if a == 0; otherwise, the side-effect of the + // increment is sequenced before the value computation of 'f(a, a)', which is + // sequenced before the value computation of the '&&', which is sequenced + // before the assignment. We treat the sequencing in '&&' as being + // unconditional. + a = a++ && f(a, a); + + // This has undefined behavior if a != 0. FIXME: We should diagnose this. + (a && a++) + a; + + (xs[7] && ++a) * (!xs[7] && ++a); // ok + + xs[0] = (a = 1, a); // ok + (a -= 128) &= 128; // ok + ++a += 1; // ok + + xs[8] ? ++a + a++ : 0; // expected-warning {{multiple unsequenced modifications}} + xs[8] ? 0 : ++a + a++; // expected-warning {{multiple unsequenced modifications}} + xs[8] ? ++a : a++; // ok + + xs[8] && (++a + a++); // expected-warning {{multiple unsequenced modifications}} + xs[8] || (++a + a++); // expected-warning {{multiple unsequenced modifications}} + + (__builtin_classify_type(++a) ? 1 : 0) + ++a; // ok + (__builtin_constant_p(++a) ? 1 : 0) + ++a; // ok + (__builtin_object_size(&(++a, a), 0) ? 1 : 0) + ++a; // ok + (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // expected-warning {{multiple unsequenced modifications}} +} diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp index ad896b521204..e12668bf2a46 100644 --- a/test/SemaCXX/warn-unused-filescoped.cpp +++ b/test/SemaCXX/warn-unused-filescoped.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-member-function -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-member-function -Wno-c++11-extensions -std=c++98 %s // RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-member-function -std=c++11 %s static void f1(); // expected-warning{{unused}} @@ -101,3 +101,42 @@ namespace test5 { static const double d = 0.0; int y = sizeof(d); } + +namespace unused_nested { + class outer { + void func1(); + struct { + void func2() { + } + } x; + }; +} + +namespace unused { + struct { + void func() { // expected-warning {{unused member function}} + } + } x; // expected-warning {{unused variable}} +} + +namespace test6 { + typedef struct { + void bar(); + } A; + + typedef struct { + void bar(); // expected-warning {{unused member function 'bar'}} + } *B; + + struct C { + void bar(); + }; +} + +namespace pr14776 { + namespace { + struct X {}; + } + X a = X(); // expected-warning {{unused variable 'a'}} + auto b = X(); // expected-warning {{unused variable 'b'}} +} diff --git a/test/SemaCXX/warn-unused-result.cpp b/test/SemaCXX/warn-unused-result.cpp index d14fdf9833ff..b0bf61f38180 100644 --- a/test/SemaCXX/warn-unused-result.cpp +++ b/test/SemaCXX/warn-unused-result.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s int f() __attribute__((warn_unused_result)); @@ -42,3 +42,39 @@ void bah() { x.foo(); // expected-warning {{ignoring return value}} x2->foo(); // expected-warning {{ignoring return value}} } + +namespace warn_unused_CXX11 { +struct [[clang::warn_unused_result]] Status { + bool ok() const; + Status& operator=(const Status& x); + inline void Update(const Status& new_status) { + if (ok()) { + *this = new_status; //no-warning + } + } +}; +Status DoSomething(); +Status& DoSomethingElse(); +Status* DoAnotherThing(); +Status** DoYetAnotherThing(); +void lazy() { + Status s = DoSomething(); + if (!s.ok()) return; + Status &rs = DoSomethingElse(); + if (!rs.ok()) return; + Status *ps = DoAnotherThing(); + if (!ps->ok()) return; + Status **pps = DoYetAnotherThing(); + if (!(*pps)->ok()) return; + + (void)DoSomething(); + (void)DoSomethingElse(); + (void)DoAnotherThing(); + (void)DoYetAnotherThing(); + + DoSomething(); // expected-warning {{ignoring return value}} + DoSomethingElse(); // expected-warning {{ignoring return value}} + DoAnotherThing(); // expected-warning {{ignoring return value}} + DoYetAnotherThing(); +} +} diff --git a/test/SemaCXX/warn-variable-not-needed.cpp b/test/SemaCXX/warn-variable-not-needed.cpp new file mode 100644 index 000000000000..0fb0f8151b44 --- /dev/null +++ b/test/SemaCXX/warn-variable-not-needed.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wall %s + +namespace test1 { + static int abc = 42; // expected-warning {{variable 'abc' is not needed and will not be emitted}} + template <typename T> + int foo(void) { + return abc; + } +} + +namespace test2 { + struct bah { + }; + namespace { + struct foo : bah { + static char bar; + virtual void zed(); + }; + void foo::zed() { + bar++; + } + char foo::bar=0; + } + bah *getfoo() { + return new foo(); + } +} diff --git a/test/SemaCXX/warn-vla.cpp b/test/SemaCXX/warn-vla.cpp new file mode 100644 index 000000000000..081f1c7b21a8 --- /dev/null +++ b/test/SemaCXX/warn-vla.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wvla %s + +void test1(int n) { + int v[n]; // expected-warning {{variable length array used}} +} + +void test2(int n, int v[n]) { // expected-warning {{variable length array used}} +} + +void test3(int n, int v[n]); // expected-warning {{variable length array used}} + +template<typename T> +void test4(int n) { + int v[n]; // expected-warning {{variable length array used}} +} + +template<typename T> +void test5(int n, int v[n]) { // expected-warning {{variable length array used}} +} + +template<typename T> +void test6(int n, int v[n]); // expected-warning {{variable length array used}} + +template<typename T> +void test7(int n, T v[n]) { // expected-warning {{variable length array used}} +} + |