diff options
Diffstat (limited to 'test/SemaCXX')
98 files changed, 2496 insertions, 340 deletions
diff --git a/test/SemaCXX/Inputs/warn-zero-nullptr.h b/test/SemaCXX/Inputs/warn-zero-nullptr.h new file mode 100644 index 0000000000000..9b86c4b7b0ece --- /dev/null +++ b/test/SemaCXX/Inputs/warn-zero-nullptr.h @@ -0,0 +1,3 @@ +#define NULL (0) +#define SYSTEM_MACRO (0) +#define OTHER_SYSTEM_MACRO (NULL) diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp index 38949e11376d5..c605dcb912f6c 100644 --- a/test/SemaCXX/MicrosoftExtensions.cpp +++ b/test/SemaCXX/MicrosoftExtensions.cpp @@ -504,6 +504,20 @@ struct S { int S::fn() { return 0; } // expected-warning {{is missing exception specification}} } +class PR34109_class { + PR34109_class() {} + virtual ~PR34109_class() {} +}; + +void operator delete(void *) throw(); +// expected-note@-1 {{previous declaration is here}} +__declspec(dllexport) void operator delete(void *) throw(); +// expected-error@-1 {{redeclaration of 'operator delete' cannot add 'dllexport' attribute}} + +void PR34109(int* a) { + delete a; +} + #elif TEST2 // Check that __unaligned is not recognized if MS extensions are not enabled diff --git a/test/SemaCXX/accessible-base.cpp b/test/SemaCXX/accessible-base.cpp index 6bf06ce126022..27969858506d6 100644 --- a/test/SemaCXX/accessible-base.cpp +++ b/test/SemaCXX/accessible-base.cpp @@ -1,10 +1,11 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -DMS -fms-compatibility -Wmicrosoft-inaccessible-base -fsyntax-only -verify %s struct A { int a; }; -struct X1 : virtual A +struct X1 : virtual A {}; struct Y1 : X1, virtual A @@ -13,7 +14,7 @@ struct Y1 : X1, virtual A struct Y2 : X1, A // expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n struct Y2 -> struct X1 -> struct A\n struct Y2 -> struct A}} {}; -struct X2 : A +struct X2 : A {}; struct Z1 : X2, virtual A // expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n struct Z1 -> struct X2 -> struct A\n struct Z1 -> struct A}} @@ -21,3 +22,30 @@ struct Z1 : X2, virtual A // expected-warning{{direct base 'A' is inaccessible d struct Z2 : X2, A // expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n struct Z2 -> struct X2 -> struct A\n struct Z2 -> struct A}} {}; + +A *y2_to_a(Y2 *p) { +#ifdef MS + // expected-warning@+4 {{accessing inaccessible direct base 'A' of 'Y2' is a Microsoft extension}} +#else + // expected-error@+2 {{ambiguous conversion}} +#endif + return p; +} + +A *z1_to_a(Z1 *p) { +#ifdef MS + // expected-warning@+4 {{accessing inaccessible direct base 'A' of 'Z1' is a Microsoft extension}} +#else + // expected-error@+2 {{ambiguous conversion}} +#endif + return p; +} + +A *z1_to_a(Z2 *p) { +#ifdef MS + // expected-warning@+4 {{accessing inaccessible direct base 'A' of 'Z2' is a Microsoft extension}} +#else + // expected-error@+2 {{ambiguous conversion}} +#endif + return p; +} diff --git a/test/SemaCXX/address-packed.cpp b/test/SemaCXX/address-packed.cpp index 308c4858cd508..f0d1496fd8928 100644 --- a/test/SemaCXX/address-packed.cpp +++ b/test/SemaCXX/address-packed.cpp @@ -112,3 +112,12 @@ void g1() { S<float> s3; s3.get(); // expected-note {{in instantiation of member function 'S<float>::get'}} } + +// PR35509 +typedef long L1; +struct Incomplete; +struct S2 { + L1 d; + Incomplete *e() const; +} __attribute__((packed)); +Incomplete *S2::e() const { return (Incomplete *)&d; } // no-warning diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp index 7b6abd22acc73..514473f9bcb17 100644 --- a/test/SemaCXX/aggregate-initialization.cpp +++ b/test/SemaCXX/aggregate-initialization.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s // Verify that using an initializer list for a non-aggregate looks for // constructors.. @@ -150,3 +150,33 @@ namespace ProtectedBaseCtor { // expected-error@-5 {{protected constructor}} // expected-note@-30 {{here}} } + +namespace IdiomaticStdArrayInitDoesNotWarn { +#pragma clang diagnostic push +#pragma clang diagnostic warning "-Wmissing-braces" + template<typename T, int N> struct StdArray { + T contents[N]; + }; + StdArray<int, 3> x = {1, 2, 3}; + + template<typename T, int N> struct ArrayAndSomethingElse { + T contents[N]; + int something_else; + }; + ArrayAndSomethingElse<int, 3> y = {1, 2, 3}; // expected-warning {{suggest braces}} + +#if __cplusplus >= 201703L + template<typename T, int N> struct ArrayAndBaseClass : StdArray<int, 3> { + T contents[N]; + }; + ArrayAndBaseClass<int, 3> z = {1, 2, 3}; // expected-warning {{suggest braces}} + + // It's not clear whether we should be warning in this case. If this + // pattern becomes idiomatic, it would be reasonable to suppress the + // warning here too. + template<typename T, int N> struct JustABaseClass : StdArray<T, N> {}; + JustABaseClass<int, 3> w = {1, 2, 3}; // expected-warning {{suggest braces}} +#endif + +#pragma clang diagnostic pop +} diff --git a/test/SemaCXX/attr-cxx-disabled.cpp b/test/SemaCXX/attr-cxx-disabled.cpp new file mode 100644 index 0000000000000..a1a7533bd854a --- /dev/null +++ b/test/SemaCXX/attr-cxx-disabled.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -fno-double-square-bracket-attributes -verify -pedantic -std=c++11 -DERRORS %s +// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify -pedantic -std=c++11 %s + +struct [[]] S {}; + +#ifdef ERRORS +// expected-error@-3 {{declaration of anonymous struct must be a definition}} +// expected-warning@-4 {{declaration does not declare anything}} +#else +// expected-no-diagnostics +#endif + diff --git a/test/SemaCXX/attr-lto-visibility-public.cpp b/test/SemaCXX/attr-lto-visibility-public.cpp index 2f9ed87f6ee0a..42e0f79279d9b 100644 --- a/test/SemaCXX/attr-lto-visibility-public.cpp +++ b/test/SemaCXX/attr-lto-visibility-public.cpp @@ -1,13 +1,13 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}} -typedef int t [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}} -[[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}} +int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to structs, unions, and classes}} +typedef int t [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to}} +[[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to}} void f() [[clang::lto_visibility_public]]; // expected-error {{'lto_visibility_public' attribute cannot be applied to types}} struct [[clang::lto_visibility_public]] s1 { - int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}} - [[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}} + int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to}} + [[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to}} }; struct [[clang::lto_visibility_public(1)]] s2 { // expected-error {{'lto_visibility_public' attribute takes no arguments}} diff --git a/test/SemaCXX/attr-mode-tmpl.cpp b/test/SemaCXX/attr-mode-tmpl.cpp index d83bb39890508..f665b1ba49123 100644 --- a/test/SemaCXX/attr-mode-tmpl.cpp +++ b/test/SemaCXX/attr-mode-tmpl.cpp @@ -72,7 +72,7 @@ struct TemplatedStruct { // expected-warning@-1{{deprecated}} // Check attribute on methods - it is invalid. - __attribute__((mode(QI))) T g1() { return 0; } // expected-error{{'mode' attribute only applies to variables, enums, fields and typedefs}} + __attribute__((mode(QI))) T g1() { return 0; } // expected-error{{'mode' attribute only applies to variables, enums, typedefs, and non-static data members}} }; diff --git a/test/SemaCXX/attr-no-sanitize.cpp b/test/SemaCXX/attr-no-sanitize.cpp index 965def6f0254a..02bc9a9e7f8f4 100644 --- a/test/SemaCXX/attr-no-sanitize.cpp +++ b/test/SemaCXX/attr-no-sanitize.cpp @@ -16,10 +16,15 @@ int f3() __attribute__((no_sanitize("address"))); // PRINT: int f4() {{\[\[}}clang::no_sanitize("thread")]] [[clang::no_sanitize("thread")]] int f4(); +// DUMP-LABEL: FunctionDecl {{.*}} f4 +// DUMP: NoSanitizeAttr {{.*}} hwaddress +// PRINT: int f4() {{\[\[}}clang::no_sanitize("hwaddress")]] +[[clang::no_sanitize("hwaddress")]] int f4(); + // DUMP-LABEL: FunctionDecl {{.*}} f5 -// DUMP: NoSanitizeAttr {{.*}} address thread -// PRINT: int f5() __attribute__((no_sanitize("address", "thread"))) -int f5() __attribute__((no_sanitize("address", "thread"))); +// DUMP: NoSanitizeAttr {{.*}} address thread hwaddress +// PRINT: int f5() __attribute__((no_sanitize("address", "thread", "hwaddress"))) +int f5() __attribute__((no_sanitize("address", "thread", "hwaddress"))); // DUMP-LABEL: FunctionDecl {{.*}} f6 // DUMP: NoSanitizeAttr {{.*}} unknown diff --git a/test/SemaCXX/attr-require-constant-initialization.cpp b/test/SemaCXX/attr-require-constant-initialization.cpp index 0df9f2e88029f..2dd72ea6dba98 100644 --- a/test/SemaCXX/attr-require-constant-initialization.cpp +++ b/test/SemaCXX/attr-require-constant-initialization.cpp @@ -56,12 +56,12 @@ struct StoresNonLit { #if defined(TEST_ONE) // Test semantics of attribute // Test diagnostics when attribute is applied to non-static declarations. -void test_func_local(ATTR int param) { // expected-error {{only applies to variables with static or thread}} - ATTR int x = 42; // expected-error {{only applies to variables with static or thread}} +void test_func_local(ATTR int param) { // expected-error {{only applies to global variables}} + ATTR int x = 42; // expected-error {{only applies to}} ATTR extern int y; } -struct ATTR class_mem { // expected-error {{only applies to variables with static or thread}} - ATTR int x; // expected-error {{only applies to variables with static or thread}} +struct ATTR class_mem { // expected-error {{only applies to}} + ATTR int x; // expected-error {{only applies to}} }; // [basic.start.static]p2.1 diff --git a/test/SemaCXX/attr-weak.cpp b/test/SemaCXX/attr-weak.cpp index 8ba3a954282d2..51deb664ce6ea 100644 --- a/test/SemaCXX/attr-weak.cpp +++ b/test/SemaCXX/attr-weak.cpp @@ -3,7 +3,7 @@ static int test0 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} static void test1() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} -namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables, functions and classes}} +namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables, functions, and classes}} } namespace { diff --git a/test/SemaCXX/builtin-assume-aligned-tmpl.cpp b/test/SemaCXX/builtin-assume-aligned-tmpl.cpp index 0909070c5e11f..61b85557d6b29 100644 --- a/test/SemaCXX/builtin-assume-aligned-tmpl.cpp +++ b/test/SemaCXX/builtin-assume-aligned-tmpl.cpp @@ -57,7 +57,7 @@ void test22() { atest4<int, 5>(); } -// expected-warning@+1 {{'assume_aligned' attribute only applies to functions and methods}} +// expected-warning@+1 {{'assume_aligned' attribute only applies to Objective-C methods and functions}} class __attribute__((assume_aligned(32))) x { int y; }; diff --git a/test/SemaCXX/compare-cxx2a.cpp b/test/SemaCXX/compare-cxx2a.cpp new file mode 100644 index 0000000000000..61d35021cc13b --- /dev/null +++ b/test/SemaCXX/compare-cxx2a.cpp @@ -0,0 +1,166 @@ +// 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 -std=c++2a %s + +void test0(long a, unsigned long b) { + enum EnumA {A}; + enum EnumB {B}; + enum EnumC {C = 0x10000}; + // (a,b) + + // FIXME: <=> should never produce -Wsign-compare warnings. All the possible error + // cases involve narrowing conversions and so are ill-formed. + (void)(a <=> (unsigned long) b); // expected-warning {{comparison of integers of different signs}} + (void)(a <=> (unsigned int) b); + (void)(a <=> (unsigned short) b); + (void)(a <=> (unsigned char) b); + (void)((long) a <=> b); // expected-warning {{comparison of integers of different signs}} + (void)((int) a <=> b); // expected-warning {{comparison of integers of different signs}} + (void)((short) a <=> b); // expected-warning {{comparison of integers of different signs}} + (void)((signed char) a <=> b); // expected-warning {{comparison of integers of different signs}} + (void)((long) a <=> (unsigned long) b); // expected-warning {{comparison of integers of different signs}} + (void)((int) a <=> (unsigned int) b); // expected-warning {{comparison of integers of different signs}} + (void)((short) a <=> (unsigned short) b); + (void)((signed char) a <=> (unsigned char) b); + +#if 0 + // (A,b) + (void)(A <=> (unsigned long) b); + (void)(A <=> (unsigned int) b); + (void)(A <=> (unsigned short) b); + (void)(A <=> (unsigned char) b); + (void)((long) A <=> b); + (void)((int) A <=> b); + (void)((short) A <=> b); + (void)((signed char) A <=> b); + (void)((long) A <=> (unsigned long) b); + (void)((int) A <=> (unsigned int) b); + (void)((short) A <=> (unsigned short) b); + (void)((signed char) A <=> (unsigned char) b); + + // (a,B) + (void)(a <=> (unsigned long) B); + (void)(a <=> (unsigned int) B); + (void)(a <=> (unsigned short) B); + (void)(a <=> (unsigned char) B); + (void)((long) a <=> B); + (void)((int) a <=> B); + (void)((short) a <=> B); + (void)((signed char) a <=> B); + (void)((long) a <=> (unsigned long) B); + (void)((int) a <=> (unsigned int) B); + (void)((short) a <=> (unsigned short) B); + (void)((signed char) a <=> (unsigned char) B); + + // (C,b) + (void)(C <=> (unsigned long) b); + (void)(C <=> (unsigned int) b); + (void)(C <=> (unsigned short) b); // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always 'std::strong_ordering::greater'}} + (void)(C <=> (unsigned char) b); // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always 'std::strong_ordering::greater'}} + (void)((long) C <=> b); + (void)((int) C <=> b); + (void)((short) C <=> b); + (void)((signed char) C <=> b); + (void)((long) C <=> (unsigned long) b); + (void)((int) C <=> (unsigned int) b); + (void)((short) C <=> (unsigned short) b); + (void)((signed char) C <=> (unsigned char) b); + + // (a,C) + (void)(a <=> (unsigned long) C); + (void)(a <=> (unsigned int) C); + (void)(a <=> (unsigned short) C); + (void)(a <=> (unsigned char) C); + (void)((long) a <=> C); + (void)((int) a <=> C); + (void)((short) a <=> C); // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always 'std::strong_ordering::less'}} + (void)((signed char) a <=> C); // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always 'std::strong_ordering::less'}} + (void)((long) a <=> (unsigned long) C); + (void)((int) a <=> (unsigned int) C); + (void)((short) a <=> (unsigned short) C); + (void)((signed char) a <=> (unsigned char) C); +#endif + + // (0x80000,b) + (void)(0x80000 <=> (unsigned long) b); + (void)(0x80000 <=> (unsigned int) b); + (void)(0x80000 <=> (unsigned short) b); // expected-warning {{result of comparison of constant 524288 with expression of type 'unsigned short' is always 'std::strong_ordering::greater'}} + (void)(0x80000 <=> (unsigned char) b); // expected-warning {{result of comparison of constant 524288 with expression of type 'unsigned char' is always 'std::strong_ordering::greater'}} + (void)((long) 0x80000 <=> b); + (void)((int) 0x80000 <=> b); + (void)((short) 0x80000 <=> b); + (void)((signed char) 0x80000 <=> b); + (void)((long) 0x80000 <=> (unsigned long) b); + (void)((int) 0x80000 <=> (unsigned int) b); + (void)((short) 0x80000 <=> (unsigned short) b); + (void)((signed char) 0x80000 <=> (unsigned char) b); + + // (a,0x80000) + (void)(a <=> (unsigned long) 0x80000); // expected-warning {{comparison of integers of different signs}} + (void)(a <=> (unsigned int) 0x80000); + (void)(a <=> (unsigned short) 0x80000); + (void)(a <=> (unsigned char) 0x80000); + (void)((long) a <=> 0x80000); + (void)((int) a <=> 0x80000); + (void)((short) a <=> 0x80000); // expected-warning {{comparison of constant 524288 with expression of type 'short' is always 'std::strong_ordering::less'}} + (void)((signed char) a <=> 0x80000); // expected-warning {{comparison of constant 524288 with expression of type 'signed char' is always 'std::strong_ordering::less'}} + (void)((long) a <=> (unsigned long) 0x80000); // expected-warning {{comparison of integers of different signs}} + (void)((int) a <=> (unsigned int) 0x80000); // expected-warning {{comparison of integers of different signs}} + (void)((short) a <=> (unsigned short) 0x80000); + (void)((signed char) a <=> (unsigned char) 0x80000); +} + +void test5(bool b) { + (void) (b <=> -10); // expected-warning{{comparison of constant -10 with expression of type 'bool' is always 'std::strong_ordering::greater'}} + (void) (b <=> -1); // expected-warning{{comparison of constant -1 with expression of type 'bool' is always 'std::strong_ordering::greater'}} + (void) (b <=> 0); + (void) (b <=> 1); + (void) (b <=> 2); // expected-warning{{comparison of constant 2 with expression of type 'bool' is always 'std::strong_ordering::less'}} + (void) (b <=> 10); // expected-warning{{comparison of constant 10 with expression of type 'bool' is always 'std::strong_ordering::less'}} +} + +void test6(signed char sc) { + (void)(sc <=> 200); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always 'std::strong_ordering::less'}} + (void)(200 <=> sc); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always 'std::strong_ordering::greater'}} +} + +// Test many signedness combinations. +void test7(unsigned long other) { + // Common unsigned, other unsigned, constant unsigned + (void)((unsigned)other <=> (unsigned long)(0x1'ffff'ffff)); // expected-warning{{less}} + (void)((unsigned)other <=> (unsigned long)(0xffff'ffff)); + (void)((unsigned long)other <=> (unsigned)(0x1'ffff'ffff)); + (void)((unsigned long)other <=> (unsigned)(0xffff'ffff)); + + // Common unsigned, other signed, constant unsigned + (void)((int)other <=> (unsigned long)(0xffff'ffff'ffff'ffff)); // expected-warning{{different signs}} + (void)((int)other <=> (unsigned long)(0x0000'0000'ffff'ffff)); // expected-warning{{different signs}} + (void)((int)other <=> (unsigned long)(0x0000'0000'0fff'ffff)); // expected-warning{{different signs}} + (void)((int)other <=> (unsigned)(0x8000'0000)); // expected-warning{{different signs}} + + // Common unsigned, other unsigned, constant signed + (void)((unsigned long)other <=> (int)(0xffff'ffff)); // 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)(0xffff'ffff)); // expected-warning{{less}} + (void)((int)other <=> (long)(0xffff'ffff'0000'0000)); // expected-warning{{greater}} + (void)((int)other <=> (long)(0x0fff'ffff)); + (void)((int)other <=> (long)(0xffff'ffff'f000'0000)); + + // 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{{less}} + + // Common signed, other unsigned, constant unsigned + (void)((unsigned char)other <=> (unsigned short)(0xff)); + (void)((unsigned char)other <=> (unsigned short)(0x100)); // expected-warning{{less}} + (void)((unsigned short)other <=> (unsigned char)(0xff)); +} diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp index 0528b044fb1f1..d852180c06630 100644 --- a/test/SemaCXX/compare.cpp +++ b/test/SemaCXX/compare.cpp @@ -73,7 +73,7 @@ int test0(long a, unsigned long b) { ((int) a == (unsigned int) B) + ((short) a == (unsigned short) B) + ((signed char) a == (unsigned char) B) + - (a < (unsigned long) B) + // expected-warning {{comparison of integers of different signs}} + (a < (unsigned long) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}} (a < (unsigned int) B) + (a < (unsigned short) B) + (a < (unsigned char) B) + @@ -81,8 +81,8 @@ int test0(long a, unsigned long b) { ((int) a < B) + ((short) a < B) + ((signed char) a < B) + - ((long) a < (unsigned long) B) + // expected-warning {{comparison of integers of different signs}} - ((int) a < (unsigned int) B) + // expected-warning {{comparison of integers of different signs}} + ((long) a < (unsigned long) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}} + ((int) a < (unsigned int) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}} ((short) a < (unsigned short) B) + ((signed char) a < (unsigned char) B) + @@ -245,8 +245,8 @@ void test4(short s) { // 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 'short' > 4294967295 is always false}} + void (s <= B); // expected-warning{{comparison 'short' <= 4294967295 is always true}} 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'}} @@ -423,3 +423,19 @@ namespace templates { testx<B>(); } } + +namespace tautological_enum { + enum E { a, b, c } e; + + // FIXME: We should warn about constructing this out-of-range numeration value. + const E invalid = (E)-1; + // ... but we should not warn about comparing against it. + bool x = e == invalid; + + // We should not warn about relational comparisons for enumerators, even if + // they're tautological. + bool y = e >= a && e <= b; + const E first_in_range = a; + const E last_in_range = b; + bool z = e >= first_in_range && e <= last_in_range; +} diff --git a/test/SemaCXX/complex-conversion.cpp b/test/SemaCXX/complex-conversion.cpp new file mode 100644 index 0000000000000..e8f09958165c3 --- /dev/null +++ b/test/SemaCXX/complex-conversion.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template<typename T> void take(T); + +void func(float Real, _Complex float Complex) { + Real += Complex; // expected-error {{assigning to 'float' from incompatible type '_Complex float'}} + Real += (float)Complex; + + Real = Complex; // expected-error {{implicit conversion from '_Complex float' to 'float' is not permitted in C++}} + Real = (float)Complex; + + take<float>(Complex); // expected-error {{implicit conversion from '_Complex float' to 'float' is not permitted in C++}} + take<double>(1.0i); // expected-error {{implicit conversion from '_Complex double' to 'double' is not permitted in C++}} + take<_Complex float>(Complex); + + // Conversion to bool doesn't actually discard the imaginary part. + take<bool>(Complex); +} diff --git a/test/SemaCXX/complex-overload.cpp b/test/SemaCXX/complex-overload.cpp index 1381968751af4..9373e44de9504 100644 --- a/test/SemaCXX/complex-overload.cpp +++ b/test/SemaCXX/complex-overload.cpp @@ -4,9 +4,10 @@ char *foo(float); void test_foo_1(float fv, double dv, float _Complex fc, double _Complex dc) { char *cp1 = foo(fv); char *cp2 = foo(dv); - // Note: GCC and EDG reject these two, but they are valid C99 conversions - char *cp3 = foo(fc); - char *cp4 = foo(dc); + // Note: GCC and EDG reject these two, they are valid C99 conversions but + // shouldn't be accepted in C++ because the result is surprising. + char *cp3 = foo(fc); // expected-error {{implicit conversion from '_Complex float' to 'float' is not permitted in C++}} + char *cp4 = foo(dc); // expected-error {{implicit conversion from '_Complex double' to 'float' is not permitted in C++}} } int *foo(float _Complex); diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index 3fda2d0a7fd0e..51dd6199e63a6 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -328,7 +328,7 @@ struct Str { extern char externalvar[]; constexpr bool constaddress = (void *)externalvar == (void *)0x4000UL; // expected-error {{must be initialized by a constant expression}} expected-note {{reinterpret_cast}} -constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}} expected-warning {{unspecified}} +constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}} static_assert(0 != "foo", ""); } @@ -364,7 +364,7 @@ void foo() { constexpr B b3 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}} } -constexpr B &&b4 = ((1, 2), 3, 4, B { {10}, {{20}} }); // expected-warning 4{{unused}} +constexpr B &&b4 = ((1, 2), 3, 4, B { {10}, {{20}} }); static_assert(&b4 != &b2, ""); // Proposed DR: copy-elision doesn't trigger lifetime extension. @@ -604,6 +604,33 @@ static_assert(NATDCArray{}[1][1].n == 0, ""); } +// Per current CWG direction, we reject any cases where pointer arithmetic is +// not statically known to be valid. +namespace ArrayOfUnknownBound { + extern int arr[]; + constexpr int *a = arr; + constexpr int *b = &arr[0]; + static_assert(a == b, ""); + constexpr int *c = &arr[1]; // expected-error {{constant}} expected-note {{indexing of array without known bound}} + constexpr int *d = &a[1]; // expected-error {{constant}} expected-note {{indexing of array without known bound}} + constexpr int *e = a + 1; // expected-error {{constant}} expected-note {{indexing of array without known bound}} + + struct X { + int a; + int b[]; // expected-warning {{C99}} + }; + extern X x; + constexpr int *xb = x.b; // expected-error {{constant}} expected-note {{not supported}} + + struct Y { int a; }; + extern Y yarr[]; + constexpr Y *p = yarr; + constexpr int *q = &p->a; + + extern const int carr[]; // expected-note {{here}} + constexpr int n = carr[0]; // expected-error {{constant}} expected-note {{non-constexpr variable}} +} + namespace DependentValues { struct I { int n; typedef I V[10]; }; @@ -1904,6 +1931,22 @@ namespace Bitfields { }; static_assert(X::f(3) == -1, "3 should truncate to -1"); } + + struct HasUnnamedBitfield { + unsigned a; + unsigned : 20; + unsigned b; + + constexpr HasUnnamedBitfield() : a(), b() {} + constexpr HasUnnamedBitfield(unsigned a, unsigned b) : a(a), b(b) {} + }; + + void testUnnamedBitfield() { + const HasUnnamedBitfield zero{}; + int a = 1 / zero.b; // expected-warning {{division by zero is undefined}} + const HasUnnamedBitfield oneZero{1, 0}; + int b = 1 / oneZero.b; // expected-warning {{division by zero is undefined}} + } } namespace ZeroSizeTypes { @@ -1949,7 +1992,7 @@ namespace NeverConstantTwoWays { constexpr int n = // expected-error {{must be initialized by a constant expression}} (int *)(long)&n == &n ? // expected-note {{reinterpret_cast}} - 1 / 0 : // expected-warning {{division by zero}} + 1 / 0 : 0; } diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp index 0c0cb0ec58a1a..12fec0851691c 100644 --- a/test/SemaCXX/constant-expression-cxx1y.cpp +++ b/test/SemaCXX/constant-expression-cxx1y.cpp @@ -988,3 +988,36 @@ constexpr void Void(int n) { void(); } constexpr int void_test = (Void(0), 1); + +namespace PR19741 { +constexpr void addone(int &m) { m++; } + +struct S { + int m = 0; + constexpr S() { addone(m); } +}; +constexpr bool evalS() { + constexpr S s; + return s.m == 1; +} +static_assert(evalS(), ""); + +struct Nested { + struct First { int x = 42; }; + union { + First first; + int second; + }; + int x; + constexpr Nested(int x) : first(), x(x) { x = 4; } + constexpr Nested() : Nested(42) { + addone(first.x); + x = 3; + } +}; +constexpr bool evalNested() { + constexpr Nested N; + return N.first.x == 43; +} +static_assert(evalNested(), ""); +} // namespace PR19741 diff --git a/test/SemaCXX/constant-expression-cxx2a.cpp b/test/SemaCXX/constant-expression-cxx2a.cpp new file mode 100644 index 0000000000000..935cbefc7cb9d --- /dev/null +++ b/test/SemaCXX/constant-expression-cxx2a.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu + +namespace ThreeWayComparison { + struct A { + int n; + constexpr friend int operator<=>(const A &a, const A &b) { + return a.n < b.n ? -1 : a.n > b.n ? 1 : 0; + } + }; + static_assert(A{1} <=> A{2} < 0); + static_assert(A{2} <=> A{1} > 0); + static_assert(A{2} <=> A{2} == 0); + + // Note: not yet supported. + static_assert(1 <=> 2 < 0); // expected-error {{invalid operands}} + static_assert(2 <=> 1 > 0); // expected-error {{invalid operands}} + static_assert(1 <=> 1 == 0); // expected-error {{invalid operands}} + constexpr int k = (1 <=> 1, 0); + // expected-error@-1 {{constexpr variable 'k' must be initialized by a constant expression}} + // expected-warning@-2 {{three-way comparison result unused}} + + constexpr void f() { // expected-error {{constant expression}} + void(1 <=> 1); // expected-note {{constant expression}} + } + + // TODO: defaulted operator <=> +} diff --git a/test/SemaCXX/constexpr-array-unknown-bound.cpp b/test/SemaCXX/constexpr-array-unknown-bound.cpp new file mode 100644 index 0000000000000..395c4cbd127b2 --- /dev/null +++ b/test/SemaCXX/constexpr-array-unknown-bound.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 %s -Wno-uninitialized -std=c++1z -fsyntax-only -verify + +const extern int arr[]; +constexpr auto p = arr; // ok +constexpr int f(int i) {return p[i];} // expected-note {{read of dereferenced one-past-the-end pointer}} + +constexpr int arr[] {1, 2, 3}; +constexpr auto p2 = arr + 2; // ok +constexpr int x = f(2); // ok +constexpr int y = f(3); // expected-error {{constant expression}} +// expected-note-re@-1 {{in call to 'f({{.*}})'}} + +// FIXME: consider permitting this case +struct A {int m[];} a; +constexpr auto p3 = a.m; // expected-error {{constant expression}} expected-note {{without known bound}} +constexpr auto p4 = a.m + 1; // expected-error {{constant expression}} expected-note {{without known bound}} + +void g(int i) { + int arr[i]; + constexpr auto *p = arr + 2; // expected-error {{constant expression}} expected-note {{without known bound}} + + // FIXME: Give a better diagnostic here. The issue is that computing + // sizeof(*arr2) within the array indexing fails due to the VLA. + int arr2[2][i]; + constexpr int m = ((void)arr2[2], 0); // expected-error {{constant expression}} +} diff --git a/test/SemaCXX/coroutines.cpp b/test/SemaCXX/coroutines.cpp index 6394829f356ae..65e17abb11fe5 100644 --- a/test/SemaCXX/coroutines.cpp +++ b/test/SemaCXX/coroutines.cpp @@ -66,6 +66,12 @@ struct suspend_never { void await_resume() {} }; +struct auto_await_suspend { + bool await_ready(); + template <typename F> auto await_suspend(F) {} + void await_resume(); +}; + struct DummyVoidTag {}; DummyVoidTag no_specialization() { // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<DummyVoidTag>' has no member named 'promise_type'}} co_await a; @@ -159,6 +165,10 @@ void yield() { co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}} } +void check_auto_await_suspend() { + co_await auto_await_suspend{}; // Should compile successfully. +} + void coreturn(int n) { co_await a; if (n == 0) diff --git a/test/SemaCXX/cxx0x-compat.cpp b/test/SemaCXX/cxx0x-compat.cpp index 8f7aaab6a4386..b9ccadd85c2d7 100644 --- a/test/SemaCXX/cxx0x-compat.cpp +++ b/test/SemaCXX/cxx0x-compat.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++11-compat -verify %s -// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++11-compat -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++11-compat-pedantic -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++11-compat-pedantic -verify %s #if __cplusplus < 201103L @@ -52,4 +52,7 @@ static_assert(true); // expected-warning {{incompatible with C++ standards befor template<int ...N> int f() { return (N + ...); } // expected-warning {{incompatible with C++ standards before C++17}} +namespace [[]] NS_with_attr {} // expected-warning {{incompatible with C++ standards before C++17}} +enum { e [[]] }; // expected-warning {{incompatible with C++ standards before C++17}} + #endif diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp index 9b8fadd2f5226..860a4aa6c6ff1 100644 --- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -136,13 +136,19 @@ void auto_deduction() { auto l3 {1}; static_assert(same_type<decltype(l), std::initializer_list<int>>::value, ""); static_assert(same_type<decltype(l3), int>::value, ""); - auto bl = {1, 2.0}; // expected-error {{cannot deduce}} + auto bl = {1, 2.0}; // expected-error {{deduced conflicting types ('int' vs 'double') for initializer list element type}} + + void f1(int), f1(float), f2(int), f3(float); + auto fil = {f1, f2}; + auto ffl = {f1, f3}; + auto fl = {f1, f2, f3}; // expected-error {{deduced conflicting types ('void (*)(int)' vs 'void (*)(float)') for initializer list element type}} for (int i : {1, 2, 3, 4}) {} + for (int j : {1.0, 2.0, 3.0f, 4.0}) {} // expected-error {{deduced conflicting types ('double' vs 'float') for initializer list element type}} } void dangle() { - new auto{1, 2, 3}; // expected-error {{cannot use list-initialization}} + new auto{1, 2, 3}; // expected-error {{new expression for type 'auto' contains multiple constructor arguments}} new std::initializer_list<int>{1, 2, 3}; // expected-warning {{at the end of the full-expression}} } diff --git a/test/SemaCXX/cxx11-ast-print.cpp b/test/SemaCXX/cxx11-ast-print.cpp index 9c617af4e95fd..17dcbcb3f7b00 100644 --- a/test/SemaCXX/cxx11-ast-print.cpp +++ b/test/SemaCXX/cxx11-ast-print.cpp @@ -55,4 +55,8 @@ struct B : A { ; // CHECK-NOT: ; +void g(int n) { + int buffer[n]; // CHECK: int buffer[n]; + [&buffer]() {}(); // CHECK: [&buffer] +} diff --git a/test/SemaCXX/cxx17-compat.cpp b/test/SemaCXX/cxx17-compat.cpp new file mode 100644 index 0000000000000..3b814340c6daf --- /dev/null +++ b/test/SemaCXX/cxx17-compat.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -pedantic -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++2a -Wc++17-compat-pedantic -verify %s + +struct A {}; +int (A::*pa)() const&; +int use_pa = (A().*pa)(); +#if __cplusplus <= 201703L + // expected-warning@-2 {{invoking a pointer to a 'const &' member function on an rvalue is a C++2a extension}} +#else + // expected-warning@-4 {{invoking a pointer to a 'const &' member function on an rvalue is incompatible with C++ standards before C++2a}} +#endif + +struct B { + void b() { + (void) [=, this] {}; +#if __cplusplus <= 201703L + // expected-warning@-2 {{explicit capture of 'this' with a capture default of '=' is a C++2a extension}} +#else + // expected-warning@-4 {{explicit capture of 'this' with a capture default of '=' is incompatible with C++ standards before C++2a}} +#endif + } + + int n : 5 = 0; +#if __cplusplus <= 201703L + // expected-warning@-2 {{default member initializer for bit-field is a C++2a extension}} +#else + // expected-warning@-4 {{default member initializer for bit-field is incompatible with C++ standards before C++2a}} +#endif +}; diff --git a/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp index dc3adca62fd36..eaed45acd11be 100644 --- a/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp +++ b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp @@ -1380,3 +1380,145 @@ XT<int> xt{}; void PR33318(int i) { [&](auto) { static_assert(&i != nullptr, ""); }(0); // expected-warning 2{{always true}} expected-note {{instantiation}} } + +// Check to make sure that we don't capture when member-calls are made to members that are not of 'this' class. +namespace PR34266 { +// https://bugs.llvm.org/show_bug.cgi?id=34266 +namespace ns1 { +struct A { + static void bar(int) { } + static void bar(double) { } +}; + +struct B +{ + template<class T> + auto f() { + auto L = [=] { + T{}.bar(3.0); + T::bar(3); + + }; + ASSERT_NO_CAPTURES(L); + return L; + }; +}; + +void test() { + B{}.f<A>(); +} +} // end ns1 + +namespace ns2 { +struct A { + static void bar(int) { } + static void bar(double) { } +}; + +struct B +{ + using T = A; + auto f() { + auto L = [=](auto a) { + T{}.bar(a); + T::bar(a); + + }; + ASSERT_NO_CAPTURES(L); + return L; + }; +}; + +void test() { + B{}.f()(3.0); + B{}.f()(3); +} +} // end ns2 + +namespace ns3 { +struct A { + void bar(int) { } + static void bar(double) { } +}; + +struct B +{ + using T = A; + auto f() { + auto L = [=](auto a) { + T{}.bar(a); + T::bar(a); // This call ignores the instance member function because the implicit object argument fails to convert. + + }; + ASSERT_NO_CAPTURES(L); + return L; + }; +}; + +void test() { + B{}.f()(3.0); + B{}.f()(3); +} + +} // end ns3 + + +namespace ns4 { +struct A { + void bar(int) { } + static void bar(double) { } +}; + +struct B : A +{ + using T = A; + auto f() { + auto L = [=](auto a) { + T{}.bar(a); + T::bar(a); + + }; + // just check to see if the size if >= 2 bytes (which should be the case if we capture anything) + ASSERT_CLOSURE_SIZE(L, 2); + return L; + }; +}; + +void test() { + B{}.f()(3.0); + B{}.f()(3); +} + +} // end ns4 + +namespace ns5 { +struct A { + void bar(int) { } + static void bar(double) { } +}; + +struct B +{ + template<class T> + auto f() { + auto L = [&](auto a) { + T{}.bar(a); + T::bar(a); + + }; + + ASSERT_NO_CAPTURES(L); + return L; + }; +}; + +void test() { + B{}.f<A>()(3.0); + B{}.f<A>()(3); +} + +} // end ns5 + + + +} // end PR34266 diff --git a/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp b/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp index b0b86e387721f..b8022d209122e 100644 --- a/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp +++ b/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp @@ -98,3 +98,27 @@ namespace variadic_expansion { } #endif +namespace PR33082 { + template<int ...I> void a() { + int arr[] = { [](auto ...K) { (void)I; } ... }; // expected-error {{no viable conversion}} expected-note {{candidate}} + } + + template<typename ...T> struct Pack {}; + template<typename ...T, typename ...U> void b(Pack<U...>, T ...t) { + int arr[] = {[t...]() { // expected-error 2{{cannot initialize an array element of type 'int' with}} + U u; + return u; + }()...}; + } + + void c() { + int arr[] = {[](auto... v) { + v; // expected-error {{unexpanded parameter pack 'v'}} + }...}; // expected-error {{pack expansion does not contain any unexpanded parameter packs}} + } + + void run() { + a<1>(); // expected-note {{instantiation of}} + b(Pack<int*, float*>(), 1, 2, 3); // expected-note {{instantiation of}} + } +} diff --git a/test/SemaCXX/cxx1y-init-captures.cpp b/test/SemaCXX/cxx1y-init-captures.cpp index d681954707d06..4b82452ed5924 100644 --- a/test/SemaCXX/cxx1y-init-captures.cpp +++ b/test/SemaCXX/cxx1y-init-captures.cpp @@ -206,3 +206,11 @@ void test(double weight) { find(weight); // expected-note {{in instantiation of function template specialization}} } } + +namespace init_capture_undeclared_identifier { + auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}} + + int typo_foo; // expected-note 2 {{'typo_foo' declared here}} + auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}} + auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}} +} diff --git a/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp index 9232a8b6eba04..9080f67fe0e11 100644 --- a/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp +++ b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c++1z -verify %s -DERRORS -// RUN: %clang_cc1 -std=c++1z -verify %s -UERRORS +// RUN: %clang_cc1 -std=c++1z -verify %s -DERRORS -Wundefined-func-template +// RUN: %clang_cc1 -std=c++1z -verify %s -UERRORS -Wundefined-func-template // This test is split into two because we only produce "undefined internal" // warnings if we didn't produce any errors. diff --git a/test/SemaCXX/cxx1z-copy-omission.cpp b/test/SemaCXX/cxx1z-copy-omission.cpp index e2b8fd7961740..a7133d79b463f 100644 --- a/test/SemaCXX/cxx1z-copy-omission.cpp +++ b/test/SemaCXX/cxx1z-copy-omission.cpp @@ -2,11 +2,11 @@ struct Noncopyable { Noncopyable(); - Noncopyable(const Noncopyable &) = delete; // expected-note 1+{{deleted}} + Noncopyable(const Noncopyable &) = delete; // expected-note 1+{{deleted}} expected-note 1+ {{not viable}} virtual ~Noncopyable(); }; struct Derived : Noncopyable {}; -struct NoncopyableAggr { +struct NoncopyableAggr { // expected-note 3{{candidate}} Noncopyable nc; }; struct Indestructible { @@ -38,11 +38,39 @@ Noncopyable nrvo() { Noncopyable nc1 = make(); Noncopyable nc2 = Noncopyable(); Noncopyable nc3 = Derived(); // expected-error {{deleted constructor}} +Noncopyable nc4((Noncopyable())); +Noncopyable nc5 = {Noncopyable()}; +Noncopyable nc6{Noncopyable()}; NoncopyableAggr nca1 = NoncopyableAggr{}; NoncopyableAggr nca2 = NoncopyableAggr{{}}; NoncopyableAggr nca3 = NoncopyableAggr{NoncopyableAggr{Noncopyable()}}; +template<typename T> struct Convert { operator T(); }; // expected-note 1+{{candidate}} +Noncopyable conv1 = Convert<Noncopyable>(); +Noncopyable conv2((Convert<Noncopyable>())); +Noncopyable conv3 = {Convert<Noncopyable>()}; +Noncopyable conv4{Convert<Noncopyable>()}; + +Noncopyable ref_conv1 = Convert<Noncopyable&>(); // expected-error {{deleted constructor}} +Noncopyable ref_conv2((Convert<Noncopyable&>())); // expected-error {{deleted constructor}} +Noncopyable ref_conv3 = {Convert<Noncopyable&>()}; // expected-error {{deleted constructor}} +Noncopyable ref_conv4{Convert<Noncopyable&>()}; // expected-error {{deleted constructor}} + +Noncopyable derived_conv1 = Convert<Derived>(); // expected-error {{deleted constructor}} +Noncopyable derived_conv2((Convert<Derived>())); // expected-error {{deleted constructor}} +Noncopyable derived_conv3 = {Convert<Derived>()}; // expected-error {{deleted constructor}} +Noncopyable derived_conv4{Convert<Derived>()}; // expected-error {{deleted constructor}} + +NoncopyableAggr nc_aggr1 = Convert<NoncopyableAggr>(); +NoncopyableAggr nc_aggr2((Convert<NoncopyableAggr>())); +NoncopyableAggr nc_aggr3 = {Convert<NoncopyableAggr>()}; // expected-error {{no viable conversion}} +NoncopyableAggr nc_aggr4{Convert<NoncopyableAggr>()}; // expected-error {{no viable conversion}} +NoncopyableAggr nc_aggr5 = Convert<Noncopyable>(); // expected-error {{no viable}} +NoncopyableAggr nc_aggr6((Convert<Noncopyable>())); // expected-error {{no matching constructor}} +NoncopyableAggr nc_aggr7 = {Convert<Noncopyable>()}; +NoncopyableAggr nc_aggr8{Convert<Noncopyable>()}; + void test_expressions(bool b) { auto lambda = [a = make()] {}; @@ -132,3 +160,12 @@ struct AsDelegating final { // classes? AsDelegating(int n) : AsDelegating(make(n)) {} // expected-error {{deleted}} }; + +namespace CtorTemplateBeatsNonTemplateConversionFn { + struct Foo { template <typename Derived> Foo(const Derived &); }; + template <typename Derived> struct Base { operator Foo() const = delete; }; // expected-note {{deleted}} + struct Derived : Base<Derived> {}; + + Foo f(Derived d) { return d; } // expected-error {{invokes a deleted function}} + Foo g(Derived d) { return Foo(d); } // ok, calls constructor +} diff --git a/test/SemaCXX/cxx1z-init-statement-template.cpp b/test/SemaCXX/cxx1z-init-statement-template.cpp new file mode 100644 index 0000000000000..cedd2c720d909 --- /dev/null +++ b/test/SemaCXX/cxx1z-init-statement-template.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -std=c++1z -verify -emit-llvm-only %s +// expected-no-diagnostics + +// rdar://problem/33888545 +template <unsigned int BUFFER_SIZE> class Buffer {}; + +class A { +public: + int status; +}; + +template <unsigned int N> A parse(Buffer<N> buffer); + +template<unsigned int N> +void init_in_if(Buffer<N> buffer) { + if (A a = parse(buffer); a.status > 0) { + } +} + +template<unsigned int N> +void init_in_switch(Buffer<N> buffer) { + switch (A a = parse(buffer); a.status) { + default: + break; + } +} + +void test() { + Buffer<10> buffer; + init_in_if(buffer); + init_in_switch(buffer); +} diff --git a/test/SemaCXX/cxx1z-noexcept-function-type.cpp b/test/SemaCXX/cxx1z-noexcept-function-type.cpp index 6578eb89b0baf..814b04c6e42f1 100644 --- a/test/SemaCXX/cxx1z-noexcept-function-type.cpp +++ b/test/SemaCXX/cxx1z-noexcept-function-type.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions %s -// RUN: %clang_cc1 -std=c++1z -verify -fexceptions -fcxx-exceptions %s -Wno-dynamic-exception-spec +// RUN: %clang_cc1 -std=c++17 -verify -fexceptions -fcxx-exceptions %s -Wno-dynamic-exception-spec // RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions -Wno-c++1z-compat-mangling -DNO_COMPAT_MANGLING %s // RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions -Wno-noexcept-type -DNO_COMPAT_MANGLING %s diff --git a/test/SemaCXX/cxx2a-destroying-delete.cpp b/test/SemaCXX/cxx2a-destroying-delete.cpp new file mode 100644 index 0000000000000..6115774e3836d --- /dev/null +++ b/test/SemaCXX/cxx2a-destroying-delete.cpp @@ -0,0 +1,122 @@ +// RUN: %clang_cc1 -std=c++2a -verify %s + +namespace std { + using size_t = decltype(sizeof(0)); + enum class align_val_t : size_t; + + struct destroying_delete_t { + struct __construct { explicit __construct() = default; }; + explicit destroying_delete_t(__construct) {} + }; + + inline constexpr destroying_delete_t destroying_delete(destroying_delete_t::__construct()); +} + +void operator delete(void*, std::destroying_delete_t); // ok, just a placement delete + +struct A; +void operator delete(A*, std::destroying_delete_t); // expected-error {{first parameter of 'operator delete' must have type 'void *'}} + +struct A { + void operator delete(A*, std::destroying_delete_t); + void operator delete(A*, std::destroying_delete_t, std::size_t); + void operator delete(A*, std::destroying_delete_t, std::align_val_t); + void operator delete(A*, std::destroying_delete_t, std::size_t, std::align_val_t); + void operator delete(A*, std::destroying_delete_t, int); // expected-error {{destroying operator delete can have only an optional size and optional alignment parameter}} + // FIXME: It's probably a language defect that we permit usual operator delete to be variadic. + void operator delete(A*, std::destroying_delete_t, std::size_t, ...); + + void operator delete(struct X*, std::destroying_delete_t, std::size_t, ...); // expected-error {{first parameter of 'operator delete' must have type 'A *'}} + + void operator delete(void*, std::size_t); +}; + +void delete_A(A *a) { delete a; } + +namespace convert_param { + struct A { + void operator delete( + A*, + std::destroying_delete_t); + }; + struct B : private A { using A::operator delete; }; // expected-note 2{{declared private here}} + struct C : B {}; + void delete_C(C *c) { delete c; } // expected-error {{cannot cast 'convert_param::C' to its private base class 'convert_param::A'}} + + // expected-error@-7 {{cannot cast 'convert_param::D' to its private base class 'convert_param::A'}} + struct D : B { virtual ~D() {} }; // expected-note {{while checking implicit 'delete this' for virtual destructor}} +} + +namespace delete_selection { + struct B { + void operator delete(void*) = delete; + void operator delete(B *, std::destroying_delete_t) = delete; // expected-note {{deleted}} + }; + void delete_B(B *b) { delete b; } // expected-error {{deleted}} + + struct C { + C(); + void *operator new(std::size_t); + void operator delete(void*) = delete; + void operator delete(C *, std::destroying_delete_t) = delete; + }; + // FIXME: This should be ill-formed, but we incorrectly decide that overload + // resolution failed (because it selected a deleted function) and thus no + // 'operator delete' should be called. + C *new_C() { return new C; } + + struct D { + void operator delete(D *, std::destroying_delete_t) = delete; // expected-note {{deleted}} + void operator delete(D *, std::destroying_delete_t, std::align_val_t) = delete; + }; + void delete_D(D *d) { delete d; } // expected-error {{deleted}} + + struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) E { + void operator delete(E *, std::destroying_delete_t) = delete; + void operator delete(E *, std::destroying_delete_t, std::align_val_t) = delete; // expected-note {{deleted}} + }; + void delete_E(E *e) { delete e; } // expected-error {{deleted}} + + struct F { + void operator delete(F *, std::destroying_delete_t) = delete; // expected-note {{deleted}} + void operator delete(F *, std::destroying_delete_t, std::size_t) = delete; + }; + void delete_F(F *f) { delete f; } // expected-error {{deleted}} + + struct G { + void operator delete(G *, std::destroying_delete_t, std::align_val_t) = delete; + void operator delete(G *, std::destroying_delete_t, std::size_t) = delete; // expected-note {{deleted}} + }; + void delete_G(G *g) { delete g; } // expected-error {{deleted}} + + struct H { + void operator delete(H *, std::destroying_delete_t, std::align_val_t) = delete; // expected-note {{deleted}} + void operator delete(H *, std::destroying_delete_t, std::size_t, std::align_val_t) = delete; + }; + void delete_H(H *h) { delete h; } // expected-error {{deleted}} + + struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) I { + void operator delete(I *, std::destroying_delete_t, std::size_t) = delete; + void operator delete(I *, std::destroying_delete_t, std::size_t, std::align_val_t) = delete; // expected-note {{deleted}} + }; + void delete_I(I *i) { delete i; } // expected-error {{deleted}} +} + +namespace first_param_conversion { + struct A { + void operator delete(A *, std::destroying_delete_t); + }; + void f(const volatile A *a) { + delete a; // ok + } + + struct B { + void operator delete(B *, std::destroying_delete_t); + }; + struct C : B {}; + struct D : B {}; + struct E : C, D {}; + void g(E *e) { + delete e; // expected-error {{ambiguous conversion from derived class 'first_param_conversion::E' to base class 'first_param_conversion::B':}} + } +} diff --git a/test/SemaCXX/cxx2a-lambda-equals-this.cpp b/test/SemaCXX/cxx2a-lambda-equals-this.cpp new file mode 100644 index 0000000000000..ce6916322e5d1 --- /dev/null +++ b/test/SemaCXX/cxx2a-lambda-equals-this.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -std=c++2a -verify %s +// expected-no-diagnostics + +// This test does two things. +// Deleting the copy constructor ensures that an [=, this] capture doesn't copy the object. +// Accessing a member variable from the lambda ensures that the capture actually works. +class A { + A(const A &) = delete; + int i; + + void func() { + auto L = [=, this]() -> int { return i; }; + L(); + } +}; diff --git a/test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp b/test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp new file mode 100644 index 0000000000000..e9cbb1a18532f --- /dev/null +++ b/test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++2a %s -verify + +struct X { + void ref() & {} + void cref() const& {} +}; + +void test() { + X{}.ref(); // expected-error{{cannot initialize object parameter of type 'X' with an expression of type 'X'}} + X{}.cref(); // expected-no-error + + (X{}.*&X::ref)(); // expected-error-re{{pointer-to-member function type 'void (X::*)() {{.*}}&' can only be called on an lvalue}} + (X{}.*&X::cref)(); // expected-no-error +} diff --git a/test/SemaCXX/cxx2a-three-way-comparison.cpp b/test/SemaCXX/cxx2a-three-way-comparison.cpp new file mode 100644 index 0000000000000..eb1480ce6102b --- /dev/null +++ b/test/SemaCXX/cxx2a-three-way-comparison.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -std=c++2a -verify %s + +struct A {}; +constexpr int operator<=>(A a, A b) { return 42; } +static_assert(operator<=>(A(), A()) == 42); + +int operator<=>(); // expected-error {{overloaded 'operator<=>' must have at least one parameter of class or enumeration type}} +int operator<=>(A); // expected-error {{overloaded 'operator<=>' must be a binary operator}} +int operator<=>(int, int); // expected-error {{overloaded 'operator<=>' must have at least one parameter of class or enumeration type}} +int operator<=>(A, A, A); // expected-error {{overloaded 'operator<=>' must be a binary operator}} +int operator<=>(A, A, ...); // expected-error {{overloaded 'operator<=>' cannot be variadic}} +int operator<=>(int, A = {}); // expected-error {{parameter of overloaded 'operator<=>' cannot have a default argument}} + +struct B { + int &operator<=>(int); + friend int operator<=>(A, B); + + friend int operator<=>(int, int); // expected-error {{overloaded 'operator<=>' must have at least one parameter of class or enumeration type}} + void operator<=>(); // expected-error {{overloaded 'operator<=>' must be a binary operator}}; + void operator<=>(A, ...); // expected-error {{overloaded 'operator<=>' cannot be variadic}} + void operator<=>(A, A); // expected-error {{overloaded 'operator<=>' must be a binary operator}}; +}; + +int &r = B().operator<=>(0); diff --git a/test/SemaCXX/cxx98-compat-flags.cpp b/test/SemaCXX/cxx98-compat-flags.cpp index 62d687c49cf79..5e07964335349 100644 --- a/test/SemaCXX/cxx98-compat-flags.cpp +++ b/test/SemaCXX/cxx98-compat-flags.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -verify %s -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -Wno-bind-to-temporary-copy -Wno-unnamed-type-template-args -Wno-local-type-template-args -Werror %s +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat-pedantic -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat-pedantic -Wno-bind-to-temporary-copy -Wno-unnamed-type-template-args -Wno-local-type-template-args -Wno-binary-literal -Werror %s template<typename T> int TemplateFn(T) { return 0; } void LocalTemplateArg() { @@ -32,4 +32,6 @@ namespace CopyCtorIssues { const NoViable &b = NoViable(); // expected-warning {{copying variable of type 'CopyCtorIssues::NoViable' when binding a reference to a temporary would find no viable constructor in C++98}} const Ambiguous &c = Ambiguous(); // expected-warning {{copying variable of type 'CopyCtorIssues::Ambiguous' when binding a reference to a temporary would find ambiguous constructors in C++98}} const Deleted &d = Deleted(); // expected-warning {{copying variable of type 'CopyCtorIssues::Deleted' when binding a reference to a temporary would invoke a deleted constructor in C++98}} + + int n = 0b00100101001; // expected-warning {{binary integer literals are incompatible with C++ standards before C++14}} } diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp index 1b1f7dc8a70e2..1e31d701d0c16 100644 --- a/test/SemaCXX/decl-expr-ambiguity.cpp +++ b/test/SemaCXX/decl-expr-ambiguity.cpp @@ -48,13 +48,20 @@ void f() { struct RAII { RAII(); + RAII(int); ~RAII(); }; +struct NotRAII { + NotRAII(); + NotRAII(int); +}; + void func(); void func2(short); namespace N { struct S; + int n; void emptyParens() { RAII raii(); // expected-warning {{function declaration}} expected-note {{remove parentheses to declare a variable}} @@ -69,6 +76,23 @@ namespace N { void nonEmptyParens() { int f = 0, // g = 0; expected-note {{change this ',' to a ';' to call 'func2'}} func2(short(f)); // expected-warning {{function declaration}} expected-note {{add a pair of parentheses}} + + RAII(n); // expected-warning {{parentheses were disambiguated as redundant parentheses around declaration of variable named 'n'}} + // expected-note@-1 {{add a variable name to declare a 'RAII' initialized with 'n'}} + // expected-note@-2 {{add enclosing parentheses to perform a function-style cast}} + // expected-note@-3 {{remove parentheses to silence this warning}} + + RAII(undeclared1); +#pragma clang diagnostic push +#pragma clang diagnostic warning "-Wredundant-parens" + RAII(undeclared2); // expected-warning {{redundant parentheses surrounding declarator}} +#pragma clang diagnostic pop + + { + NotRAII(n); // expected-warning {{parentheses were disambiguated as redundant parentheses around declaration of variable named 'n'}} + // expected-note@-1 {{add enclosing parentheses to perform a function-style cast}} + // expected-note@-2 {{remove parentheses to silence this warning}} + } } } diff --git a/test/SemaCXX/decomposed-condition.cpp b/test/SemaCXX/decomposed-condition.cpp new file mode 100644 index 0000000000000..ab011f6ae4ba4 --- /dev/null +++ b/test/SemaCXX/decomposed-condition.cpp @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -std=c++1z -Wno-binding-in-condition -verify %s + +struct X { + bool flag; + int data; + constexpr explicit operator bool() const { + return flag; + } + constexpr operator int() const { + return data; + } +}; + +namespace CondInIf { +constexpr int f(X x) { + if (auto [ok, d] = x) + return d + int(ok); + else + return d * int(ok); + ok = {}; // expected-error {{use of undeclared identifier 'ok'}} + d = {}; // expected-error {{use of undeclared identifier 'd'}} +} + +static_assert(f({true, 2}) == 3); +static_assert(f({false, 2}) == 0); + +constexpr char g(char const (&x)[2]) { + if (auto &[a, b] = x) + return a; + else + return b; + + if (auto [a, b] = x) // expected-error {{an array type is not allowed here}} + ; +} + +static_assert(g("x") == 'x'); +} // namespace CondInIf + +namespace CondInSwitch { +constexpr int f(int n) { + switch (X s = {true, n}; auto [ok, d] = s) { + s = {}; + case 0: + return int(ok); + case 1: + return d * 10; + case 2: + return d * 40; + default: + return 0; + } + ok = {}; // expected-error {{use of undeclared identifier 'ok'}} + d = {}; // expected-error {{use of undeclared identifier 'd'}} + s = {}; // expected-error {{use of undeclared identifier 's'}} +} + +static_assert(f(0) == 1); +static_assert(f(1) == 10); +static_assert(f(2) == 80); +} // namespace CondInSwitch + +namespace CondInWhile { +constexpr int f(int n) { + int m = 1; + while (auto [ok, d] = X{n > 1, n}) { + m *= d; + --n; + } + return m; + return ok; // expected-error {{use of undeclared identifier 'ok'}} +} + +static_assert(f(0) == 1); +static_assert(f(1) == 1); +static_assert(f(4) == 24); +} // namespace CondInWhile + +namespace CondInFor { +constexpr int f(int n) { + int a = 1, b = 1; + for (X x = {true, n}; auto &[ok, d] = x; --d) { + if (d < 2) + ok = false; + else { + int x = b; + b += a; + a = x; + } + } + return b; + return d; // expected-error {{use of undeclared identifier 'd'}} +} + +static_assert(f(0) == 1); +static_assert(f(1) == 1); +static_assert(f(2) == 2); +static_assert(f(5) == 8); +} // namespace CondInFor diff --git a/test/SemaCXX/deleted-operator.cpp b/test/SemaCXX/deleted-operator.cpp index f71e83aa25870..64b2b22e5661c 100644 --- a/test/SemaCXX/deleted-operator.cpp +++ b/test/SemaCXX/deleted-operator.cpp @@ -8,8 +8,8 @@ struct PR10757 { int PR10757f() { PR10757 a1; // FIXME: We get a ridiculous number of "built-in candidate" notes here... - if(~a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 8 {{built-in candidate}} - if(a1==a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 144 {{built-in candidate}} + if(~a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 6-8 {{built-in candidate}} + if(a1==a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 1-144 {{built-in candidate}} } struct DelOpDel { diff --git a/test/SemaCXX/deprecated.cpp b/test/SemaCXX/deprecated.cpp index 26f30c91b0980..773085bf2b965 100644 --- a/test/SemaCXX/deprecated.cpp +++ b/test/SemaCXX/deprecated.cpp @@ -20,7 +20,12 @@ void i() throw(...); // expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept(false)' instead}} #endif -void stuff() { +void stuff(register int q) { +#if __cplusplus > 201402L + // expected-error@-2 {{ISO C++17 does not allow 'register' storage class specifier}} +#elif __cplusplus >= 201103L && !defined(NO_DEPRECATED_FLAGS) + // expected-warning@-4 {{'register' storage class specifier is deprecated}} +#endif register int n; #if __cplusplus > 201402L // expected-error@-2 {{ISO C++17 does not allow 'register' storage class specifier}} @@ -93,3 +98,6 @@ namespace DeprecatedCopy { void g() { c1 = c2; } // expected-note {{implicit copy assignment operator for 'DeprecatedCopy::Dtor' first required here}} } #endif + +# 1 "/usr/include/system-header.h" 1 3 +void system_header_function(void) throw(); diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp index 49cdc50f3c13c..00d2fc5529783 100644 --- a/test/SemaCXX/destructor.cpp +++ b/test/SemaCXX/destructor.cpp @@ -1,5 +1,36 @@ // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -fcxx-exceptions -verify %s // RUN: %clang_cc1 -std=c++11 -triple %ms_abi_triple -DMSABI -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s + +#if defined(BE_THE_HEADER) + +// Wdelete-non-virtual-dtor should warn about the delete from smart pointer +// classes in system headers (std::unique_ptr...) too. + +#pragma clang system_header +namespace dnvd { + +struct SystemB { + virtual void foo(); +}; + +template <typename T> +class simple_ptr { +public: + simple_ptr(T* t): _ptr(t) {} + ~simple_ptr() { delete _ptr; } // \ + // expected-warning {{delete called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}} \ + // expected-warning {{delete called on non-final 'dnvd::D' that has virtual functions but non-virtual destructor}} + T& operator*() const { return *_ptr; } +private: + T* _ptr; +}; +} + +#else + +#define BE_THE_HEADER +#include __FILE__ + class A { public: ~A(); @@ -213,18 +244,6 @@ struct VD: VB {}; struct VF final: VB {}; template <typename T> -class simple_ptr { -public: - simple_ptr(T* t): _ptr(t) {} - ~simple_ptr() { delete _ptr; } // \ - // expected-warning {{delete called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}} \ - // expected-warning {{delete called on non-final 'dnvd::D' that has virtual functions but non-virtual destructor}} - T& operator*() const { return *_ptr; } -private: - T* _ptr; -}; - -template <typename T> class simple_ptr2 { public: simple_ptr2(T* t): _ptr(t) {} @@ -235,6 +254,7 @@ private: }; void use(B&); +void use(SystemB&); void use(VB&); void nowarnstack() { @@ -335,10 +355,28 @@ void warn0() { } } +// Taken from libc++, slightly simplified. +template <class> +struct __is_destructible_apply { typedef int type; }; +struct __two {char __lx[2];}; +template <typename _Tp> +struct __is_destructor_wellformed { + template <typename _Tp1> + static char __test(typename __is_destructible_apply< + decltype(_Tp1().~_Tp1())>::type); + template <typename _Tp1> + static __two __test (...); + + static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char); +}; + void warn0_explicit_dtor(B* b, B& br, D* d) { b->~B(); // expected-warning {{destructor called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}} expected-note{{qualify call to silence this warning}} b->B::~B(); // No warning when the call isn't virtual. + // No warning in unevaluated contexts. + (void)__is_destructor_wellformed<B>::value; + br.~B(); // expected-warning {{destructor called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}} expected-note{{qualify call to silence this warning}} br.B::~B(); @@ -367,6 +405,10 @@ void nowarn1() { simple_ptr<VF> vf(new VF()); use(*vf); } + { + simple_ptr<SystemB> sb(new SystemB()); + use(*sb); + } } void warn1() { @@ -451,3 +493,4 @@ void foo1() { x.foo1(); } } +#endif // BE_THE_HEADER diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp index a3fed70ec958b..c09a531c19b7d 100644 --- a/test/SemaCXX/dllexport.cpp +++ b/test/SemaCXX/dllexport.cpp @@ -17,18 +17,18 @@ struct External { int v; }; // Invalid usage. __declspec(dllexport) typedef int typedef1; -// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}} typedef __declspec(dllexport) int typedef2; -// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllexport' attribute only applies to}} typedef int __declspec(dllexport) typedef3; -// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllexport' attribute only applies to}} typedef __declspec(dllexport) void (*FunTy)(); -// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllexport' attribute only applies to}} enum __declspec(dllexport) Enum {}; -// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllexport' attribute only applies to}} #if __has_feature(cxx_strong_enums) enum class __declspec(dllexport) EnumClass {}; -// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllexport' attribute only applies to}} #endif @@ -565,7 +565,7 @@ private: __declspec(dllexport) void privateDef(); public: - __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} + __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to}} __declspec(dllexport) static int StaticField; __declspec(dllexport) static int StaticFieldDef; __declspec(dllexport) static const int StaticConstField; @@ -977,7 +977,7 @@ private: __declspec(dllexport) void privateDef(); public: - __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} + __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to}} __declspec(dllexport) static int StaticField; __declspec(dllexport) static int StaticFieldDef; __declspec(dllexport) static const int StaticConstField; diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp index 1c59ccad6e140..04c33e9fb5c8c 100644 --- a/test/SemaCXX/dllimport.cpp +++ b/test/SemaCXX/dllimport.cpp @@ -16,18 +16,18 @@ namespace { struct Internal {}; } // Invalid usage. __declspec(dllimport) typedef int typedef1; -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}} typedef __declspec(dllimport) int typedef2; -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllimport' attribute only applies to}} typedef int __declspec(dllimport) typedef3; -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllimport' attribute only applies to}} typedef __declspec(dllimport) void (*FunTy)(); -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllimport' attribute only applies to}} enum __declspec(dllimport) Enum {}; -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllimport' attribute only applies to}} #if __has_feature(cxx_strong_enums) enum class __declspec(dllimport) EnumClass {}; -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} +// expected-warning@-1{{'dllimport' attribute only applies to}} #endif @@ -574,7 +574,7 @@ private: __declspec(dllimport) void privateDecl(); public: - __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} + __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to}} __declspec(dllimport) static int StaticField; __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} __declspec(dllimport) static const int StaticConstField; @@ -1147,7 +1147,7 @@ private: __declspec(dllimport) void privateDecl(); public: - __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} + __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to}} __declspec(dllimport) static int StaticField; __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} __declspec(dllimport) static const int StaticConstField; diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp index 3114bca9347df..1fcafb1dd0fdc 100644 --- a/test/SemaCXX/enum-scoped.cpp +++ b/test/SemaCXX/enum-scoped.cpp @@ -309,3 +309,8 @@ namespace test11 { bool f() { return !f1(); } // expected-error {{invalid argument type 'test11::E2' (aka 'test11::E') to unary expression}} } + +namespace PR35586 { + enum C { R, G, B }; + enum B { F = (enum C) -1, T}; // this should compile cleanly, it used to assert. +}; diff --git a/test/SemaCXX/enum.cpp b/test/SemaCXX/enum.cpp index 6b0824b751447..cfe5760112f6d 100644 --- a/test/SemaCXX/enum.cpp +++ b/test/SemaCXX/enum.cpp @@ -110,3 +110,13 @@ enum { overflow = 123456 * 234567 }; // expected-warning@-2 {{not an integral constant expression}} // expected-note@-3 {{value 28958703552 is outside the range of representable values}} #endif + +// PR28903 +struct PR28903 { + enum { + PR28903_A = (enum { // expected-error-re {{'PR28903::(anonymous enum at {{.*}})' cannot be defined in an enumeration}} + PR28903_B, + PR28903_C = PR28903_B + }) + }; +}; diff --git a/test/SemaCXX/flexible-array-test.cpp b/test/SemaCXX/flexible-array-test.cpp index 2d74fa52452eb..f2105ca361300 100644 --- a/test/SemaCXX/flexible-array-test.cpp +++ b/test/SemaCXX/flexible-array-test.cpp @@ -66,6 +66,11 @@ union B { char c[]; }; +class C { + char c[]; // expected-error {{flexible array member 'c' with type 'char []' is not at the end of class}} + int s; // expected-note {{next field declaration is here}} +}; + namespace rdar9065507 { struct StorageBase { diff --git a/test/SemaCXX/has_unique_object_reps_member_ptr.cpp b/test/SemaCXX/has_unique_object_reps_member_ptr.cpp new file mode 100644 index 0000000000000..b8e27f82ff386 --- /dev/null +++ b/test/SemaCXX/has_unique_object_reps_member_ptr.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple x86_64-linux-pc -DIS64 -fsyntax-only -verify -std=c++17 %s +// RUN: %clang_cc1 -triple x86_64-windows-pc -DIS64 -fsyntax-only -verify -std=c++17 %s +// RUN: %clang_cc1 -triple i386-linux-pc -fsyntax-only -verify -std=c++17 %s +// RUN: %clang_cc1 -triple i386-windows-pc -DW32 -fsyntax-only -verify -std=c++17 %s +// expected-no-diagnostics + +struct Base {}; +struct A : virtual Base { + virtual void n() {} +}; + +auto p = &A::n; +static_assert(__has_unique_object_representations(decltype(p))); + +struct B { + decltype(p) x; + int b; +#ifdef IS64 + // required on 64 bit to fill out the tail padding. + int c; +#endif +}; +static_assert(__has_unique_object_representations(B)); + +struct C { // has padding on Win32, but nothing else. + decltype(p) x; +}; +#ifdef W32 +static_assert(!__has_unique_object_representations(C)); +#else +static_assert(__has_unique_object_representations(C)); +#endif diff --git a/test/SemaCXX/imaginary-constants.cpp b/test/SemaCXX/imaginary-constants.cpp new file mode 100644 index 0000000000000..bbff92755a1fd --- /dev/null +++ b/test/SemaCXX/imaginary-constants.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -include %s -std=gnu++98 +// RUN: %clang_cc1 -fsyntax-only -verify %s -include %s -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -include %s -std=c++14 -DCXX14=1 + +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +_Complex int val1 = 2i; +_Complex long val2 = 2il; +_Complex long long val3 = 2ill; +_Complex float val4 = 2.0if; +_Complex double val5 = 2.0i; +_Complex long double val6 = 2.0il; + +#if CXX14 + +#pragma clang system_header + +namespace std { + template<typename T> struct complex {}; + complex<float> operator""if(unsigned long long); + complex<float> operator""if(long double); + + complex<double> operator"" i(unsigned long long); + complex<double> operator"" i(long double); + + complex<long double> operator"" il(unsigned long long); + complex<long double> operator"" il(long double); +} + +using namespace std; + +complex<float> f1 = 2.0if; +complex<float> f2 = 2if; +complex<double> d1 = 2.0i; +complex<double> d2 = 2i; +complex<long double> l1 = 2.0il; +complex<long double> l2 = 2il; + +#endif + +#endif diff --git a/test/SemaCXX/implicit-exception-spec.cpp b/test/SemaCXX/implicit-exception-spec.cpp index f400c222de83c..c21f773e94c66 100644 --- a/test/SemaCXX/implicit-exception-spec.cpp +++ b/test/SemaCXX/implicit-exception-spec.cpp @@ -121,7 +121,7 @@ namespace PotentiallyConstructed { T &a = *p; static_assert(noexcept(a = a) == D, ""); static_assert(noexcept(a = static_cast<T&&>(a)) == E, ""); - static_assert(noexcept(delete &a) == F, ""); // expected-warning 2{{abstract}} + static_assert(noexcept(delete &a) == F, ""); // These are last because the first failure here causes instantiation to bail out. static_assert(noexcept(new (nothrow) T()) == A, ""); // expected-error 2{{abstract}} diff --git a/test/SemaCXX/init-expr-crash.cpp b/test/SemaCXX/init-expr-crash.cpp new file mode 100644 index 0000000000000..407da78e60b02 --- /dev/null +++ b/test/SemaCXX/init-expr-crash.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++11 + +// Test reproduces a pair of crashes that were caused by code attempting +// to materialize a default constructor's exception specifier. + +template <class T> struct A { + static T tab[]; + + const int M = UNDEFINED; // expected-error {{use of undeclared identifier}} + + int main() + { + A<char> a; + + return 0; + } +}; + +template <class T> struct B { + static T tab[]; + + // expected-error@+1 {{invalid application of 'sizeof' to an incomplete type}} + const int N = sizeof(B<char>::tab) / sizeof(char); + + int main() + { + B<char> b; + + return 0; + } +}; diff --git a/test/SemaCXX/integer-overflow.cpp b/test/SemaCXX/integer-overflow.cpp index a119f0eabe3a4..6abc95614496b 100644 --- a/test/SemaCXX/integer-overflow.cpp +++ b/test/SemaCXX/integer-overflow.cpp @@ -164,7 +164,7 @@ uint64_t check_integer_overflows(int i) { //expected-note {{declared here}} // expected-warning@+3 {{array index 536870912 is past the end of the array (which contains 10 elements)}} // expected-note@+1 {{array 'a' declared here}} uint64_t a[10]; - a[4608 * 1024 * 1024] = 1i; + a[4608 * 1024 * 1024] = 1; // expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024))); diff --git a/test/SemaCXX/internal_linkage.cpp b/test/SemaCXX/internal_linkage.cpp index d5cc6767392da..921a90ab4a41a 100644 --- a/test/SemaCXX/internal_linkage.cpp +++ b/test/SemaCXX/internal_linkage.cpp @@ -5,7 +5,7 @@ int f() __attribute__((internal_linkage)); class A; class __attribute__((internal_linkage)) A { public: - int x __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}} + int x __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to variables, functions, and classes}} static int y __attribute__((internal_linkage)); void f1() __attribute__((internal_linkage)); void f2() __attribute__((internal_linkage)) {} @@ -16,7 +16,7 @@ public: ~A() __attribute__((internal_linkage)) {} A& operator=(const A&) __attribute__((internal_linkage)) { return *this; } struct { - int z __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}} + int z __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to}} }; }; @@ -24,14 +24,14 @@ __attribute__((internal_linkage)) void A::f4() {} // expected-error{{'internal_l __attribute__((internal_linkage)) int A::zz; // expected-error{{'internal_linkage' attribute does not appear on the first declaration of 'zz'}} -namespace Z __attribute__((internal_linkage)) { // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}} +namespace Z __attribute__((internal_linkage)) { // expected-warning{{'internal_linkage' attribute only applies to}} } __attribute__((internal_linkage("foo"))) int g() {} // expected-error{{'internal_linkage' attribute takes no arguments}} [[clang::internal_linkage]] int h() {} -enum struct __attribute__((internal_linkage)) E { // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}} +enum struct __attribute__((internal_linkage)) E { // expected-warning{{'internal_linkage' attribute only applies to}} a = 1, b = 2 }; diff --git a/test/SemaCXX/linkage2.cpp b/test/SemaCXX/linkage2.cpp index a7eb15f7c6be6..6f43af39f7c57 100644 --- a/test/SemaCXX/linkage2.cpp +++ b/test/SemaCXX/linkage2.cpp @@ -143,9 +143,10 @@ namespace test13 { } namespace test14 { + // Anonymous namespace implies internal linkage, so 'static' has no effect. namespace { - void a(void); // expected-note {{previous declaration is here}} - static void a(void) {} // expected-error {{static declaration of 'a' follows non-static declaration}} + void a(void); + static void a(void) {} } } @@ -217,3 +218,34 @@ namespace PR18964 { unsigned &*foo; //expected-error{{'foo' declared as a pointer to a reference of type}} extern struct {} *foo; // don't assert } + +namespace typedef_name_for_linkage { + template<typename T> struct Use {}; + + struct A { A(); A(const A&); ~A(); }; + + typedef struct { + A a; + } B; + + struct C { + typedef struct { + A a; + } D; + }; + + typedef struct { + void f() { static int n; struct Inner {};} + } E; + + // FIXME: Ideally this would be accepted in all modes. In C++98, we trigger a + // linkage calculation to drive the "internal linkage type as template + // argument" warning. + typedef struct { + void f() { struct Inner {}; Use<Inner> ui; } + } F; +#if __cplusplus < 201103L + // expected-error@-2 {{unsupported: typedef changes linkage of anonymous type, but linkage was already computed}} + // expected-note@-5 {{use a tag name here}} +#endif +} diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp index c296baa5bce70..82750878e584f 100644 --- a/test/SemaCXX/member-init.cpp +++ b/test/SemaCXX/member-init.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 -Wall %s struct Bitfield { - int n : 3 = 7; // expected-error {{bit-field member cannot have an in-class initializer}} + int n : 3 = 7; // expected-warning {{C++2a extension}} expected-warning {{changes value from 7 to -1}} }; int a; diff --git a/test/SemaCXX/microsoft-varargs.cpp b/test/SemaCXX/microsoft-varargs.cpp index 35f31a97c4f16..5b0f90eb5ca04 100644 --- a/test/SemaCXX/microsoft-varargs.cpp +++ b/test/SemaCXX/microsoft-varargs.cpp @@ -20,3 +20,8 @@ int builtin(int i, ...) { return __builtin_va_arg(ap, int); } +void test___va_start_ignore_const(const char *format, ...) { + va_list args; + ((void)(__va_start(&args, (&const_cast<char &>(reinterpret_cast<const volatile char &>(format))), ((sizeof(format) + 4 - 1) & ~(4 - 1)), (&const_cast<char &>(reinterpret_cast<const volatile char &>(format)))))); +} + diff --git a/test/SemaCXX/microsoft-vs-float128.cpp b/test/SemaCXX/microsoft-vs-float128.cpp new file mode 100644 index 0000000000000..d271e470032d2 --- /dev/null +++ b/test/SemaCXX/microsoft-vs-float128.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -triple i686-pc-win32 -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 -DMS %s + +template <bool> struct enable_if {}; +template<> struct enable_if<true> { typedef void type; }; + +template <typename, typename> struct is_same { static constexpr bool value = false; }; +template <typename T> struct is_same<T, T> { static constexpr bool value = true; }; + + + + +struct S { + // The only numeric types S can be converted to is __int128 and __float128. + template <typename T, typename = typename enable_if< + !((__is_integral(T) && sizeof(T) != 16) || + is_same<T, float>::value || + is_same<T, double>::value || + is_same<T, long double>::value)>::type> + operator T() { return T(); } +}; + +void f() { +#ifdef MS + // When targeting Win32, __float128 and __int128 do not exist, so the S + // object cannot be converted to anything usable in the expression. + // expected-error@+2{{invalid operands to binary expression ('S' and 'double')}} +#endif + double d = S() + 1.0; +#ifndef MS + // expected-error@-2{{use of overloaded operator '+' is ambiguous}} + // expected-note@-3 36{{built-in candidate operator+}} +#endif +} diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp index 96bed074db857..61dddcbe5026b 100644 --- a/test/SemaCXX/missing-members.cpp +++ b/test/SemaCXX/missing-members.cpp @@ -37,3 +37,17 @@ struct S : A::B::C { using A::B::C::f; // expected-error {{no member named 'f' in 'A::B::C'}} }; + +struct S1 {}; + +struct S2 : S1 {}; + +struct S3 : S2 { + void run(); +}; + +struct S4: S3 {}; + +void test(S4 *ptr) { + ptr->S1::run(); // expected-error {{no member named 'run' in 'S1'}} +} diff --git a/test/SemaCXX/modules-ts.cppm b/test/SemaCXX/modules-ts.cppm index 2ea4958bffda1..c07ee82e313c3 100644 --- a/test/SemaCXX/modules-ts.cppm +++ b/test/SemaCXX/modules-ts.cppm @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DTEST=0 -// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DTEST=1 -// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -verify -DTEST=2 -// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -verify -Dfoo=bar -DTEST=3 +// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.0.pcm -verify -DTEST=0 +// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.1.pcm -verify -DTEST=1 +// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.0.pcm -o %t.2.pcm -verify -DTEST=2 +// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.0.pcm -o %t.3.pcm -verify -Dfoo=bar -DTEST=3 #if TEST == 0 // expected-no-diagnostics @@ -14,14 +14,14 @@ export module foo; #endif static int m; -#if TEST == 2 // FIXME: 'm' has internal linkage, so there should be no error here +#if TEST == 2 // expected-error@-2 {{redefinition of '}} // expected-note@-3 {{unguarded header; consider using #ifdef guards or #pragma once}} // FIXME: We should drop the "header from" in this diagnostic. // expected-note-re@modules-ts.cppm:1 {{'{{.*}}modules-ts.cppm' included multiple times, additional include site in header from module 'foo'}} #endif int n; -#if TEST >= 2 +#if TEST == 2 // expected-error@-2 {{redefinition of '}} // expected-note@-3 {{unguarded header; consider using #ifdef guards or #pragma once}} // FIXME: We should drop the "header from" in this diagnostic. @@ -52,15 +52,11 @@ export {} // expected-error {{export declaration cannot be empty}} export { ; } export { static_assert(true); } -// FIXME: These diagnostics are not very good. -export import foo; // expected-error {{expected unqualified-id}} -export { import foo; } // expected-error {{expected unqualified-id}} - int use_b = b; int use_n = n; // FIXME: this should not be visible, because it is not exported extern int n; -static_assert(&n == p); // FIXME: these are not the same entity +static_assert(&n != p); #endif diff --git a/test/SemaCXX/ms-interface.cpp b/test/SemaCXX/ms-interface.cpp index 4a1c13ddcbbae..66ce376e2a949 100644 --- a/test/SemaCXX/ms-interface.cpp +++ b/test/SemaCXX/ms-interface.cpp @@ -77,3 +77,32 @@ class C1 : I6<C> { class C2 : I6<I> { }; + + +// MSVC makes a special case in that an interface is allowed to have a data +// member if it is a property. +__interface HasProp { + __declspec(property(get = Get, put = Put)) int data; + int Get(void); + void Put(int); +}; + +struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) + IUnknown { + void foo(); + __declspec(property(get = Get, put = Put), deprecated) int data; + int Get(void); + void Put(int); +}; + +struct IFaceStruct : IUnknown { + __declspec(property(get = Get2, put = Put2), deprecated) int data2; + int Get2(void); + void Put2(int); +}; + +__interface IFaceInheritsStruct : IFaceStruct {}; +static_assert(!__is_interface_class(HasProp), "oops"); +static_assert(!__is_interface_class(IUnknown), "oops"); +static_assert(!__is_interface_class(IFaceStruct), "oops"); +static_assert(!__is_interface_class(IFaceInheritsStruct), "oops"); diff --git a/test/SemaCXX/ms-iunknown-inline-def.cpp b/test/SemaCXX/ms-iunknown-inline-def.cpp new file mode 100644 index 0000000000000..70f1107c2e318 --- /dev/null +++ b/test/SemaCXX/ms-iunknown-inline-def.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s + +struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown { + void foo() {} +}; + +// expected-error@+1{{interface type cannot inherit from}} +__interface HasError : public IUnknown {}; diff --git a/test/SemaCXX/ms-iunknown-outofline-def.cpp b/test/SemaCXX/ms-iunknown-outofline-def.cpp new file mode 100644 index 0000000000000..b6e74d0eb6043 --- /dev/null +++ b/test/SemaCXX/ms-iunknown-outofline-def.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s + +struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown { + void foo(); +}; + +__interface NoError : public IUnknown {}; +void IUnknown::foo() {} +// expected-error@+1{{interface type cannot inherit from}} +__interface HasError : public IUnknown {}; diff --git a/test/SemaCXX/ms-iunknown-template-function.cpp b/test/SemaCXX/ms-iunknown-template-function.cpp new file mode 100644 index 0000000000000..8f741a18eaacd --- /dev/null +++ b/test/SemaCXX/ms-iunknown-template-function.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s +// expected-no-diagnostics +typedef long HRESULT; +typedef unsigned long ULONG; +typedef struct _GUID { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +} GUID; +typedef GUID IID; + +// remove stdcall, since the warnings have nothing to do with +// what is being tested. +#define __stdcall + +extern "C" { +extern "C++" { +struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) + IUnknown { +public: + virtual HRESULT __stdcall QueryInterface( + const IID &riid, + void **ppvObject) = 0; + + virtual ULONG __stdcall AddRef(void) = 0; + + virtual ULONG __stdcall Release(void) = 0; + + template <class Q> + HRESULT __stdcall QueryInterface(Q **pp) { + return QueryInterface(__uuidof(Q), (void **)pp); + } +}; +} +} + +__interface ISfFileIOPropertyPage : public IUnknown{}; + diff --git a/test/SemaCXX/ms-iunknown.cpp b/test/SemaCXX/ms-iunknown.cpp new file mode 100644 index 0000000000000..df761d56a8001 --- /dev/null +++ b/test/SemaCXX/ms-iunknown.cpp @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s + +extern "C++" struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown { + void foo(); + // Definitions aren't allowed, unless they are a template. + template<typename T> + void bar(T t){} +}; + +struct IPropertyPageBase : public IUnknown {}; +struct IPropertyPage : public IPropertyPageBase {}; +__interface ISfFileIOPropertyPage : public IPropertyPage {}; + + +namespace NS { + struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {}; + // expected-error@+1 {{interface type cannot inherit from}} + __interface IPropertyPageBase : public IUnknown {}; +} + +namespace NS2 { +extern "C++" struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {}; +// expected-error@+1 {{interface type cannot inherit from}} +__interface IPropertyPageBase : public IUnknown{}; +} + +// expected-error@+1 {{interface type cannot inherit from}} +__interface IPropertyPageBase2 : public NS::IUnknown {}; + +__interface temp_iface {}; +struct bad_base : temp_iface {}; +// expected-error@+1 {{interface type cannot inherit from}} +__interface bad_inherit : public bad_base{}; + +struct mult_inher_base : temp_iface, IUnknown {}; +// expected-error@+1 {{interface type cannot inherit from}} +__interface bad_inherit2 : public mult_inher_base{}; + +struct PageBase : public IUnknown {}; +struct Page3 : public PageBase {}; +struct Page4 : public PageBase {}; +__interface PropertyPage : public Page4 {}; + +struct Page5 : public Page3, Page4{}; +// expected-error@+1 {{interface type cannot inherit from}} +__interface PropertyPage2 : public Page5 {}; + +__interface IF1 {}; +__interface PP : IUnknown, IF1{}; +__interface PP2 : PP, Page3, Page4{}; diff --git a/test/SemaCXX/new-array-size-conv.cpp b/test/SemaCXX/new-array-size-conv.cpp index dbdd4bd8951e7..36b2f23a0e977 100644 --- a/test/SemaCXX/new-array-size-conv.cpp +++ b/test/SemaCXX/new-array-size-conv.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=gnu++98 %s // RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++98 %s // RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++11 %s diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp index cb0d030d99c20..870a5921d2530 100644 --- a/test/SemaCXX/new-delete.cpp +++ b/test/SemaCXX/new-delete.cpp @@ -80,12 +80,21 @@ void bad_news(int *ip) (void)new int[1.1]; #if __cplusplus <= 199711L // expected-error@-2 {{array size expression must have integral or enumeration type, not 'double'}} -#else +#elif __cplusplus <= 201103L // expected-error@-4 {{array size expression must have integral or unscoped enumeration type, not 'double'}} +#else + // expected-warning@-6 {{implicit conversion from 'double' to 'unsigned int' changes value from 1.1 to 1}} #endif - (void)new int[1][i]; // expected-error {{only the first dimension}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} - (void)new (int[1][i]); // expected-error {{only the first dimension}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} + (void)new int[1][i]; // expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} + (void)new (int[1][i]); // expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} +#if __cplusplus <= 201103L + // expected-error@-3 {{only the first dimension}} + // expected-error@-3 {{only the first dimension}} +#else + // expected-error@-6 {{array size is not a constant expression}} + // expected-error@-6 {{array size is not a constant expression}} +#endif (void)new (int[i]); // expected-warning {{when type is in parentheses}} (void)new int(*(S*)0); // expected-error {{no viable conversion from 'S' to 'int'}} (void)new int(1, 2); // expected-error {{excess elements in scalar initializer}} @@ -94,13 +103,20 @@ void bad_news(int *ip) (void)new const int; // expected-error {{default initialization of an object of const type 'const int'}} (void)new float*(ip); // expected-error {{cannot initialize a new value of type 'float *' with an lvalue of type 'int *'}} // Undefined, but clang should reject it directly. - (void)new int[-1]; // expected-error {{array size is negative}} + (void)new int[-1]; +#if __cplusplus <= 201103L + // expected-error@-2 {{array size is negative}} +#else + // expected-error@-4 {{array is too large}} +#endif (void)new int[2000000000]; // expected-error {{array is too large}} (void)new int[*(S*)0]; #if __cplusplus <= 199711L // expected-error@-2 {{array size expression must have integral or enumeration type, not 'S'}} -#else +#elif __cplusplus <= 201103L // expected-error@-4 {{array size expression must have integral or unscoped enumeration type, not 'S'}} +#else + // expected-error@-6 {{converting 'S' to incompatible type}} #endif (void)::S::new int; // expected-error {{expected unqualified-id}} diff --git a/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp b/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp new file mode 100644 index 0000000000000..ee5b0c47b9ffc --- /dev/null +++ b/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wsystem-headers -isystem %S %s + +#include <no-warn-user-defined-literals-in-system-headers.h> + +void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}} diff --git a/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.h b/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.h new file mode 100644 index 0000000000000..d1e2583168f15 --- /dev/null +++ b/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.h @@ -0,0 +1,2 @@ +// Header for no-warn-user-defined-literals-in-system-headers.cpp +void operator "" foo (const char *); diff --git a/test/SemaCXX/nothrow-as-noexcept-ctor.cpp b/test/SemaCXX/nothrow-as-noexcept-ctor.cpp new file mode 100644 index 0000000000000..7cca414d7a6a9 --- /dev/null +++ b/test/SemaCXX/nothrow-as-noexcept-ctor.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 %s -fcxx-exceptions -fsyntax-only -Wexceptions -verify -std=c++14 + +// expected-no-diagnostics +struct Base { + __attribute__((nothrow)) Base() {} +}; + +struct Derived : Base { + Derived() noexcept = default; +}; + +struct Base2 { + Base2() noexcept {} +}; + +struct Derived2 : Base2 { + __attribute__((nothrow)) Derived2() = default; +}; + +struct Base3 { + __attribute__((nothrow)) Base3() {} +}; + +struct Derived3 : Base3 { + __attribute__((nothrow)) Derived3() = default; +}; diff --git a/test/SemaCXX/nullptr-arithmetic.cpp b/test/SemaCXX/nullptr-arithmetic.cpp new file mode 100644 index 0000000000000..9963c8858ee87 --- /dev/null +++ b/test/SemaCXX/nullptr-arithmetic.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -Wextra -std=c++11 +// RUN: %clang_cc1 %s -fsyntax-only -triple i686-unknown-unknown -verify -pedantic -Wextra -std=c++11 +// RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-unknown -verify -pedantic -Wextra -std=c++11 + +#include <stdint.h> + +void f(intptr_t offset) { + // A zero offset from a nullptr is OK. + char *f = (char*)nullptr + 0; + int *g = (int*)0 + 0; + f = (char*)nullptr - 0; + g = (int*)nullptr - 0; + // adding other values is undefined. + f = (char*)nullptr + offset; // expected-warning {{arithmetic on a null pointer treated as a cast from integer to pointer is a GNU extension}} + // Cases that don't match the GNU inttoptr idiom get a different warning. + f = (char*)0 - offset; // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior if the offset is nonzero}} + g = (int*)0 + offset; // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior if the offset is nonzero}} +} + +// Value-dependent pointer arithmetic should not produce a nullptr warning. +template<char *P> +char* g(intptr_t offset) { + return P + offset; +} + +// Value-dependent offsets should not produce a nullptr warning. +template<intptr_t N> +char *h() { + return (char*)nullptr + N; +} diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp index 0e3a9ee50bb24..0c4bba5027f7e 100644 --- a/test/SemaCXX/overload-call.cpp +++ b/test/SemaCXX/overload-call.cpp @@ -658,3 +658,11 @@ namespace StringLiteralToCharAmbiguity { // expected-note@-5 {{candidate function}} #endif } + +namespace ProduceNotesAfterSFINAEFailure { + struct A { + template<typename T, typename U = typename T::x> A(T); // expected-warning 0-1{{extension}} + }; + void f(void*, A); // expected-note {{candidate function not viable}} + void g() { f(1, 2); } // expected-error {{no matching function}} +} diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp index 369e9eb802a59..dff9350cc9847 100644 --- a/test/SemaCXX/overloaded-operator.cpp +++ b/test/SemaCXX/overloaded-operator.cpp @@ -531,3 +531,57 @@ namespace NoADLForMemberOnlyOperators { b3 / 0; // expected-note {{in instantiation of}} expected-error {{invalid operands to}} } } + + +namespace PR27027 { + template <class T> void operator+(T, T) = delete; // expected-note 4 {{candidate}} + template <class T> void operator+(T) = delete; // expected-note 4 {{candidate}} + + struct A {} a_global; + void f() { + A a; + +a; // expected-error {{overload resolution selected deleted operator '+'}} + a + a; // expected-error {{overload resolution selected deleted operator '+'}} + bool operator+(A); + extern bool operator+(A, A); + +a; // OK + a + a; + } + bool test_global_1 = +a_global; // expected-error {{overload resolution selected deleted operator '+'}} + bool test_global_2 = a_global + a_global; // expected-error {{overload resolution selected deleted operator '+'}} +} + +namespace LateADLInNonDependentExpressions { + struct A {}; + struct B : A {}; + int &operator+(A, A); + int &operator!(A); + int &operator+=(A, A); + int &operator<<(A, A); + int &operator++(A); + int &operator++(A, int); + int &operator->*(A, A); + + template<typename T> void f() { + // An instantiation-dependent value of type B. + // These are all non-dependent operator calls of type int&. +#define idB ((void()), B()) + int &a = idB + idB, + &b = !idB, + &c = idB += idB, + &d = idB << idB, + &e = ++idB, + &f = idB++, + &g = idB ->* idB; + } + + // These should not be found by ADL in the template instantiation. + float &operator+(B, B); + float &operator!(B); + float &operator+=(B, B); + float &operator<<(B, B); + float &operator++(B); + float &operator++(B, int); + float &operator->*(B, B); + template void f<int>(); +} diff --git a/test/SemaCXX/short-wchar-sign.cpp b/test/SemaCXX/short-wchar-sign.cpp index 7ce21c523cd77..a43e68a086aa1 100644 --- a/test/SemaCXX/short-wchar-sign.cpp +++ b/test/SemaCXX/short-wchar-sign.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -pedantic -verify %s -// RUN: %clang_cc1 -fshort-wchar -fsyntax-only -pedantic -verify %s +// RUN: %clang_cc1 -fwchar-type=short -fno-signed-wchar -fsyntax-only -pedantic -verify %s // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -pedantic -verify %s // expected-no-diagnostics diff --git a/test/SemaCXX/static-assert.cpp b/test/SemaCXX/static-assert.cpp index 196375c3d6870..846303807a023 100644 --- a/test/SemaCXX/static-assert.cpp +++ b/test/SemaCXX/static-assert.cpp @@ -51,3 +51,20 @@ StaticAssertProtected<X> sap2; // expected-note {{instantiation}} static_assert(true); // expected-warning {{C++17 extension}} static_assert(false); // expected-error-re {{failed{{$}}}} expected-warning {{extension}} + + +// Diagnostics for static_assert with multiple conditions +template<typename T> struct first_trait { + static const bool value = false; +}; + +template<> +struct first_trait<X> { + static const bool value = true; +}; + +template<typename T> struct second_trait { + static const bool value = false; +}; + +static_assert(first_trait<X>::value && second_trait<X>::value, "message"); // expected-error{{static_assert failed due to requirement 'second_trait<X>::value' "message"}} diff --git a/test/SemaCXX/template-default-param-through-using.cpp b/test/SemaCXX/template-default-param-through-using.cpp new file mode 100644 index 0000000000000..4bf26d5811606 --- /dev/null +++ b/test/SemaCXX/template-default-param-through-using.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics +namespace llvm { + template<typename T > struct StringSet; + template<int I > struct Int; + template <typename Inner, template <typename> class Outer> + struct TemplTempl; +} + +namespace lld { + using llvm::StringSet; + using llvm::Int; + using llvm::TemplTempl; +}; + +namespace llvm { + template<typename T > struct StringSet; +} + +template<typename T> struct Temp{}; + +namespace llvm { + template<typename T = int> struct StringSet{}; + template<int I = 5> struct Int{}; + template <typename Inner, template <typename> class Outer = Temp> + struct TemplTempl{}; +}; + +namespace lld { + StringSet<> s; + Int<> i; + TemplTempl<int> tt; +} diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index 5879a77dd5a84..b334e507554f0 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -2352,3 +2352,320 @@ void is_trivially_destructible_test() { { int arr[F(__is_trivially_destructible(void))]; } { int arr[F(__is_trivially_destructible(const volatile void))]; } } + +// Instantiation of __has_unique_object_representations +template <typename T> +struct has_unique_object_representations { + static const bool value = __has_unique_object_representations(T); +}; + +static_assert(!has_unique_object_representations<void>::value, "void is never unique"); +static_assert(!has_unique_object_representations<const void>::value, "void is never unique"); +static_assert(!has_unique_object_representations<volatile void>::value, "void is never unique"); +static_assert(!has_unique_object_representations<const volatile void>::value, "void is never unique"); + +static_assert(has_unique_object_representations<int>::value, "integrals are"); +static_assert(has_unique_object_representations<const int>::value, "integrals are"); +static_assert(has_unique_object_representations<volatile int>::value, "integrals are"); +static_assert(has_unique_object_representations<const volatile int>::value, "integrals are"); + +static_assert(has_unique_object_representations<void *>::value, "as are pointers"); +static_assert(has_unique_object_representations<const void *>::value, "as are pointers"); +static_assert(has_unique_object_representations<volatile void *>::value, "are pointers"); +static_assert(has_unique_object_representations<const volatile void *>::value, "as are pointers"); + +static_assert(has_unique_object_representations<int *>::value, "as are pointers"); +static_assert(has_unique_object_representations<const int *>::value, "as are pointers"); +static_assert(has_unique_object_representations<volatile int *>::value, "as are pointers"); +static_assert(has_unique_object_representations<const volatile int *>::value, "as are pointers"); + +class C {}; +using FP = int (*)(int); +using PMF = int (C::*)(int); +using PMD = int C::*; + +static_assert(has_unique_object_representations<FP>::value, "even function pointers"); +static_assert(has_unique_object_representations<const FP>::value, "even function pointers"); +static_assert(has_unique_object_representations<volatile FP>::value, "even function pointers"); +static_assert(has_unique_object_representations<const volatile FP>::value, "even function pointers"); + +static_assert(has_unique_object_representations<PMF>::value, "and pointer to members"); +static_assert(has_unique_object_representations<const PMF>::value, "and pointer to members"); +static_assert(has_unique_object_representations<volatile PMF>::value, "and pointer to members"); +static_assert(has_unique_object_representations<const volatile PMF>::value, "and pointer to members"); + +static_assert(has_unique_object_representations<PMD>::value, "and pointer to members"); +static_assert(has_unique_object_representations<const PMD>::value, "and pointer to members"); +static_assert(has_unique_object_representations<volatile PMD>::value, "and pointer to members"); +static_assert(has_unique_object_representations<const volatile PMD>::value, "and pointer to members"); + +static_assert(has_unique_object_representations<bool>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<char>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<signed char>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<unsigned char>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<short>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<unsigned short>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<int>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<unsigned int>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<long>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<unsigned long>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<long long>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<unsigned long long>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<wchar_t>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<char16_t>::value, "yes, all integral types"); +static_assert(has_unique_object_representations<char32_t>::value, "yes, all integral types"); + +static_assert(!has_unique_object_representations<void>::value, "but not void!"); +static_assert(!has_unique_object_representations<decltype(nullptr)>::value, "or nullptr_t"); +static_assert(!has_unique_object_representations<float>::value, "definitely not Floating Point"); +static_assert(!has_unique_object_representations<double>::value, "definitely not Floating Point"); +static_assert(!has_unique_object_representations<long double>::value, "definitely not Floating Point"); + +struct NoPadding { + int a; + int b; +}; + +static_assert(has_unique_object_representations<NoPadding>::value, "types without padding are"); + +struct InheritsFromNoPadding : NoPadding { + int c; + int d; +}; + +static_assert(has_unique_object_representations<InheritsFromNoPadding>::value, "types without padding are"); + +struct VirtuallyInheritsFromNoPadding : virtual NoPadding { + int c; + int d; +}; + +static_assert(!has_unique_object_representations<VirtuallyInheritsFromNoPadding>::value, "No virtual inheritence"); + +struct Padding { + char a; + int b; +}; + +//static_assert(!has_unique_object_representations<Padding>::value, "but not with padding"); + +struct InheritsFromPadding : Padding { + int c; + int d; +}; + +static_assert(!has_unique_object_representations<InheritsFromPadding>::value, "or its subclasses"); + +struct TailPadding { + int a; + char b; +}; + +static_assert(!has_unique_object_representations<TailPadding>::value, "even at the end"); + +struct TinyStruct { + char a; +}; + +static_assert(has_unique_object_representations<TinyStruct>::value, "Should be no padding"); + +struct InheritsFromTinyStruct : TinyStruct { + int b; +}; + +static_assert(!has_unique_object_representations<InheritsFromTinyStruct>::value, "Inherit causes padding"); + +union NoPaddingUnion { + int a; + unsigned int b; +}; + +static_assert(has_unique_object_representations<NoPaddingUnion>::value, "unions follow the same rules as structs"); + +union PaddingUnion { + int a; + long long b; +}; + +static_assert(!has_unique_object_representations<PaddingUnion>::value, "unions follow the same rules as structs"); + +struct NotTriviallyCopyable { + int x; + NotTriviallyCopyable(const NotTriviallyCopyable &) {} +}; + +static_assert(!has_unique_object_representations<NotTriviallyCopyable>::value, "must be trivially copyable"); + +struct HasNonUniqueMember { + float x; +}; + +static_assert(!has_unique_object_representations<HasNonUniqueMember>::value, "all members must be unique"); + +enum ExampleEnum { xExample, + yExample }; +enum LLEnum : long long { xLongExample, + yLongExample }; + +static_assert(has_unique_object_representations<ExampleEnum>::value, "Enums are integrals, so unique!"); +static_assert(has_unique_object_representations<LLEnum>::value, "Enums are integrals, so unique!"); + +enum class ExampleEnumClass { xExample, + yExample }; +enum class LLEnumClass : long long { xLongExample, + yLongExample }; + +static_assert(has_unique_object_representations<ExampleEnumClass>::value, "Enums are integrals, so unique!"); +static_assert(has_unique_object_representations<LLEnumClass>::value, "Enums are integrals, so unique!"); + +// because references aren't trivially copyable. +static_assert(!has_unique_object_representations<int &>::value, "No references!"); +static_assert(!has_unique_object_representations<const int &>::value, "No references!"); +static_assert(!has_unique_object_representations<volatile int &>::value, "No references!"); +static_assert(!has_unique_object_representations<const volatile int &>::value, "No references!"); +static_assert(!has_unique_object_representations<Empty>::value, "No empty types!"); + +class Compressed : Empty { + int x; +}; + +static_assert(has_unique_object_representations<Compressed>::value, "But inheriting from one is ok"); + +class EmptyInheritor : Compressed {}; + +static_assert(has_unique_object_representations<EmptyInheritor>::value, "As long as the base has items, empty is ok"); + +class Dynamic { + virtual void A(); + int i; +}; + +static_assert(!has_unique_object_representations<Dynamic>::value, "Dynamic types are not valid"); + +class InheritsDynamic : Dynamic { + int j; +}; + +static_assert(!has_unique_object_representations<InheritsDynamic>::value, "Dynamic types are not valid"); + +static_assert(has_unique_object_representations<int[42]>::value, "Arrays are fine, as long as their value type is"); +static_assert(has_unique_object_representations<int[]>::value, "Arrays are fine, as long as their value type is"); +static_assert(has_unique_object_representations<int[][42]>::value, "Arrays are fine, as long as their value type is"); +static_assert(!has_unique_object_representations<double[42]>::value, "So no array of doubles!"); +static_assert(!has_unique_object_representations<double[]>::value, "So no array of doubles!"); +static_assert(!has_unique_object_representations<double[][42]>::value, "So no array of doubles!"); + +struct __attribute__((aligned(16))) WeirdAlignment { + int i; +}; +union __attribute__((aligned(16))) WeirdAlignmentUnion { + int i; +}; +static_assert(!has_unique_object_representations<WeirdAlignment>::value, "Alignment causes padding"); +static_assert(!has_unique_object_representations<WeirdAlignmentUnion>::value, "Alignment causes padding"); +static_assert(!has_unique_object_representations<WeirdAlignment[42]>::value, "Also no arrays that have padding"); + +static_assert(!has_unique_object_representations<int(int)>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int) const>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int) volatile>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int) const volatile>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int) &>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int) const &>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int) volatile &>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int) const volatile &>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int) &&>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int) const &&>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int) volatile &&>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int) const volatile &&>::value, "Functions are not unique"); + +static_assert(!has_unique_object_representations<int(int, ...)>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int, ...) const>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int, ...) volatile>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int, ...) const volatile>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int, ...) &>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int, ...) const &>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int, ...) volatile &>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int, ...) const volatile &>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int, ...) &&>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int, ...) const &&>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int, ...) volatile &&>::value, "Functions are not unique"); +static_assert(!has_unique_object_representations<int(int, ...) const volatile &&>::value, "Functions are not unique"); + +void foo(){ + static auto lambda = []() {}; + static_assert(!has_unique_object_representations<decltype(lambda)>::value, "Lambdas follow struct rules"); + int i; + static auto lambda2 = [i]() {}; + static_assert(has_unique_object_representations<decltype(lambda2)>::value, "Lambdas follow struct rules"); +} + +struct PaddedBitfield { + char c : 6; + char d : 1; +}; + +struct UnPaddedBitfield { + char c : 6; + char d : 2; +}; + +struct AlignedPaddedBitfield { + char c : 6; + __attribute__((aligned(1))) + char d : 2; +}; + +static_assert(!has_unique_object_representations<PaddedBitfield>::value, "Bitfield padding"); +static_assert(has_unique_object_representations<UnPaddedBitfield>::value, "Bitfield padding"); +static_assert(!has_unique_object_representations<AlignedPaddedBitfield>::value, "Bitfield padding"); + +struct BoolBitfield { + bool b : 8; +}; + +static_assert(has_unique_object_representations<BoolBitfield>::value, "Bitfield bool"); + +struct BoolBitfield2 { + bool b : 16; +}; + +static_assert(!has_unique_object_representations<BoolBitfield2>::value, "Bitfield bool"); + +struct GreaterSizeBitfield { + //expected-warning@+1 {{width of bit-field 'n'}} + int n : 1024; +}; + +static_assert(sizeof(GreaterSizeBitfield) == 128, "Bitfield Size"); +static_assert(!has_unique_object_representations<GreaterSizeBitfield>::value, "Bitfield padding"); + +struct StructWithRef { + int &I; +}; + +static_assert(has_unique_object_representations<StructWithRef>::value, "References are still unique"); + +struct NotUniqueBecauseTailPadding { + int &r; + char a; +}; +struct CanBeUniqueIfNoPadding : NotUniqueBecauseTailPadding { + char b[7]; +}; + +static_assert(!has_unique_object_representations<NotUniqueBecauseTailPadding>::value, + "non trivial"); +// Can be unique on Itanium, since the is child class' data is 'folded' into the +// parent's tail padding. +static_assert(sizeof(CanBeUniqueIfNoPadding) != 16 || + has_unique_object_representations<CanBeUniqueIfNoPadding>::value, + "inherit from std layout"); + +namespace ErrorType { + struct S; //expected-note{{forward declaration of 'ErrorType::S'}} + + struct T { + S t; //expected-error{{field has incomplete type 'ErrorType::S'}} + }; + bool b = __has_unique_object_representations(T); +}; diff --git a/test/SemaCXX/typo-correction-crash.cpp b/test/SemaCXX/typo-correction-crash.cpp index 0b8383dbafef4..b7b9c73a0cbd3 100644 --- a/test/SemaCXX/typo-correction-crash.cpp +++ b/test/SemaCXX/typo-correction-crash.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s auto check1() { return 1; return s; // expected-error {{use of undeclared identifier 's'}} @@ -19,3 +19,5 @@ struct FooRecord { }; FooRecord::NestedNamespace::type x; // expected-error {{no member named 'NestedNamespace' in 'FooRecord'; did you mean 'BarNamespace::NestedNamespace'?}} void cast_expr(int g) { +int(n)(g); } // expected-error {{undeclared identifier 'n'}} + +void bind() { for (const auto& [test,_] : _test_) { }; } // expected-error {{undeclared identifier '_test_'}} diff --git a/test/SemaCXX/unavailable_aligned_allocation.cpp b/test/SemaCXX/unavailable_aligned_allocation.cpp index 2ae5d2e2c7041..2000e0b6a319a 100644 --- a/test/SemaCXX/unavailable_aligned_allocation.cpp +++ b/test/SemaCXX/unavailable_aligned_allocation.cpp @@ -1,6 +1,12 @@ // RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify %s // RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s // RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -faligned-allocation -faligned-alloc-unavailable -std=c++14 -verify %s +// RUN: %clang_cc1 -triple arm64-apple-ios10.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DIOS %s +// RUN: %clang_cc1 -triple arm64-apple-ios10.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s +// RUN: %clang_cc1 -triple arm64-apple-tvos10.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DTVOS %s +// RUN: %clang_cc1 -triple arm64-apple-tvos10.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s +// RUN: %clang_cc1 -triple armv7k-apple-watchos3.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DWATCHOS %s +// RUN: %clang_cc1 -triple armv7k-apple-watchos3.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s namespace std { typedef decltype(sizeof(0)) size_t; @@ -56,44 +62,68 @@ void testOveraligned() { #ifdef NO_ERRORS // expected-no-diagnostics #else -// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}} +// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}} // expected-note@-17 {{if you supply your own aligned allocation functions}} -// expected-error@-18 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}} +// expected-error@-18 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} // expected-note@-19 {{if you supply your own aligned allocation functions}} -// expected-error@-20 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}} +// expected-error@-20 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}} // expected-note@-21 {{if you supply your own aligned allocation functions}} -// expected-error@-22 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}} +// expected-error@-22 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} // expected-note@-23 {{if you supply your own aligned allocation functions}} -// expected-error@-24 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}} +// expected-error@-24 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} // expected-note@-25 {{if you supply your own aligned allocation functions}} -// expected-error@-26 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}} +// expected-error@-26 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}} // expected-note@-27 {{if you supply your own aligned allocation functions}} -// expected-error@-28 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}} +// expected-error@-28 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}} // expected-note@-29 {{if you supply your own aligned allocation functions}} -// expected-error@-29 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}} +// expected-error@-29 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}} // expected-note@-30 {{if you supply your own aligned allocation functions}} -// expected-error@-31 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}} +// expected-error@-31 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} // expected-note@-32 {{if you supply your own aligned allocation functions}} -// expected-error@-33 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}} +// expected-error@-33 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}} // expected-note@-34 {{if you supply your own aligned allocation functions}} -// expected-error@-35 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}} +// expected-error@-35 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} // expected-note@-36 {{if you supply your own aligned allocation functions}} -// expected-error@-37 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}} +// expected-error@-37 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} // expected-note@-38 {{if you supply your own aligned allocation functions}} -// expected-error@-39 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}} +// expected-error@-39 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}} // expected-note@-40 {{if you supply your own aligned allocation functions}} -// expected-error@-41 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}} +// expected-error@-41 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}} // expected-note@-42 {{if you supply your own aligned allocation functions}} #endif +void testOveralignedCheckOS() { + auto *p = new OveralignedS; +} + +#ifdef NO_ERRORS +// expected-no-diagnostics +#else +#if defined(IOS) +// expected-error@-7 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on iOS 11 or newer}} +// expected-error@-8 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on iOS 11 or newer}}} +#elif defined(TVOS) +// expected-error@-10 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on tvOS 11 or newer}}} +// expected-error@-11 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on tvOS 11 or newer}}} +#elif defined(WATCHOS) +// expected-error@-13 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on watchOS 4 or newer}}} +// expected-error@-14 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on watchOS 4 or newer}}} +#else +// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on macOS 10.13 or newer}}} +// expected-error@-17 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.13 or newer}}} +#endif + +// expected-note@-20 2 {{if you supply your own aligned allocation functions}} +#endif + // No errors if user-defined aligned allocation functions are available. void *operator new(std::size_t __sz, std::align_val_t) { static char array[256]; diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp index 32151b71ea17d..60fa202384dee 100644 --- a/test/SemaCXX/undefined-internal.cpp +++ b/test/SemaCXX/undefined-internal.cpp @@ -187,6 +187,10 @@ namespace OverloadUse { void f(); void f(int); // expected-warning {{function 'OverloadUse::(anonymous namespace)::f' has internal linkage but is not defined}} void f(int, int); // expected-warning {{function 'OverloadUse::(anonymous namespace)::f' has internal linkage but is not defined}} +#if __cplusplus < 201103L + // expected-note@-3 {{here}} + // expected-note@-3 {{here}} +#endif } template<void x()> void t() { x(); } template<void x(int)> void t(int*) { x(10); } @@ -194,6 +198,10 @@ namespace OverloadUse { void g(int n) { t<f>(&n); // expected-note {{used here}} t<f>(&n, &n); // expected-note {{used here}} +#if __cplusplus < 201103L + // expected-warning@-3 {{non-type template argument referring to function 'f' with internal linkage}} + // expected-warning@-3 {{non-type template argument referring to function 'f' with internal linkage}} +#endif } } diff --git a/test/SemaCXX/underlying_type.cpp b/test/SemaCXX/underlying_type.cpp index dd019ae6e2775..87f3b92802ad3 100644 --- a/test/SemaCXX/underlying_type.cpp +++ b/test/SemaCXX/underlying_type.cpp @@ -62,3 +62,17 @@ enum E {}; void PR26014() { f<E>(0); } // should not yield an ambiguity error. template<typename ...T> void f(__underlying_type(T) v); // expected-error {{declaration type contains unexpanded parameter pack 'T'}} + +namespace PR23421 { +template <class T> +using underlying_type_t = __underlying_type(T); +// Should not crash. +template <class T> +struct make_unsigned_impl { using type = underlying_type_t<T>; }; +using AnotherType = make_unsigned_impl<E>::type; + +// also should not crash. +template <typename T> +__underlying_type(T) ft(); +auto x = &ft<E>; +} diff --git a/test/SemaCXX/unknown-type-name.cpp b/test/SemaCXX/unknown-type-name.cpp index 2a9748e3ab678..9086c9acc4385 100644 --- a/test/SemaCXX/unknown-type-name.cpp +++ b/test/SemaCXX/unknown-type-name.cpp @@ -95,7 +95,10 @@ template<typename T> int A<T>::h(T::type x, char) {} // expected-error{{missing template<typename T> int h(T::type, int); // expected-error{{missing 'typename'}} template<typename T> int h(T::type x, char); // expected-error{{missing 'typename'}} -template<typename T> int junk1(T::junk); // expected-warning{{variable templates are a C++14 extension}} +template<typename T> int junk1(T::junk); +#if __cplusplus <= 201103L +// expected-warning@-2 {{variable templates are a C++14 extension}} +#endif template<typename T> int junk2(T::junk) throw(); // expected-error{{missing 'typename'}} template<typename T> int junk3(T::junk) = delete; // expected-error{{missing 'typename'}} #if __cplusplus <= 199711L @@ -106,7 +109,11 @@ template<typename T> int junk4(T::junk j); // expected-error{{missing 'typename' // FIXME: We can tell this was intended to be a function because it does not // have a dependent nested name specifier. -template<typename T> int i(T::type, int()); // expected-warning{{variable templates are a C++14 extension}} +template<typename T> int i(T::type, int()); +#if __cplusplus <= 201103L +// expected-warning@-2 {{variable templates are a C++14 extension}} +#endif + // FIXME: We know which type specifier should have been specified here. Provide // a fix-it to add 'typename A<T>::type' diff --git a/test/SemaCXX/unused.cpp b/test/SemaCXX/unused.cpp index ba9ab2363b062..abaf611b0df80 100644 --- a/test/SemaCXX/unused.cpp +++ b/test/SemaCXX/unused.cpp @@ -6,7 +6,7 @@ // PR4103 : Make sure we don't get a bogus unused expression warning namespace PR4103 { class APInt { - char foo; + char foo; // expected-warning {{private field 'foo' is not used}} }; class APSInt : public APInt { char bar; // expected-warning {{private field 'bar' is not used}} diff --git a/test/SemaCXX/varargs.cpp b/test/SemaCXX/varargs.cpp index f9027c2479930..f2f53dc2001fd 100644 --- a/test/SemaCXX/varargs.cpp +++ b/test/SemaCXX/varargs.cpp @@ -8,7 +8,7 @@ void f(const string& s, ...) { // expected-note {{parameter of type 'const stri __builtin_va_start(ap, s); // expected-warning {{passing an object of reference type to 'va_start' has undefined behavior}} } -void g(register int i, ...) { +void g(register int i, ...) { // expected-warning 0-1{{deprecated}} __builtin_va_start(ap, i); // UB in C, OK in C++ } diff --git a/test/SemaCXX/vartemplate-lambda.cpp b/test/SemaCXX/vartemplate-lambda.cpp index 5b91e232e3a67..6744968bcc4d3 100644 --- a/test/SemaCXX/vartemplate-lambda.cpp +++ b/test/SemaCXX/vartemplate-lambda.cpp @@ -8,7 +8,7 @@ template<typename T> auto v1 = [](int a = T(1)) { return a; }(); struct S { template<class T> - static constexpr T t = [](int f = T(7)){return f;}(); // expected-error{{constexpr variable 't<int>' must be initialized by a constant expression}} expected-error{{a lambda expression may not appear inside of a constant expression}} expected-note{{cannot be used in a constant expression}} + static constexpr T t = [](int f = T(7)){return f;}(); // expected-error{{constexpr variable 't<int>' must be initialized by a constant expression}} expected-note{{cannot be used in a constant expression}} }; template <typename X> diff --git a/test/SemaCXX/warn-absolute-value.cpp b/test/SemaCXX/warn-absolute-value.cpp index 8a8a6fd67d343..9a23054fd1c26 100644 --- a/test/SemaCXX/warn-absolute-value.cpp +++ b/test/SemaCXX/warn-absolute-value.cpp @@ -448,94 +448,16 @@ void test_long_double(long double x) { } void test_complex_float(_Complex float x) { - (void)abs(x); - // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsf" - (void)labs(x); - // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf" - (void)llabs(x); - // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf" - - (void)fabsf(x); - // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf" - (void)fabs(x); - // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf" - (void)fabsl(x); - // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf" - (void)cabsf(x); (void)cabs(x); (void)cabsl(x); - (void)__builtin_abs(x); - // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsf" - (void)__builtin_labs(x); - // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf" - (void)__builtin_llabs(x); - // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf" - - (void)__builtin_fabsf(x); - // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf" - (void)__builtin_fabs(x); - // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf" - (void)__builtin_fabsl(x); - // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsf' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf" - (void)__builtin_cabsf(x); (void)__builtin_cabs(x); (void)__builtin_cabsl(x); } void test_complex_double(_Complex double x) { - (void)abs(x); - // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabs" - (void)labs(x); - // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs" - (void)llabs(x); - // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs" - - (void)fabsf(x); - // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}} - // expected-note@-2 {{use function 'cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs" - (void)fabs(x); - // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs" - (void)fabsl(x); - // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}} - // expected-note@-2 {{use function 'cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs" - (void)cabsf(x); // expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}} // expected-note@-2 {{use function 'cabs' instead}} @@ -543,31 +465,6 @@ void test_complex_double(_Complex double x) { (void)cabs(x); (void)cabsl(x); - (void)__builtin_abs(x); - // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabs" - (void)__builtin_labs(x); - // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs" - (void)__builtin_llabs(x); - // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs" - - (void)__builtin_fabsf(x); - // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs" - (void)__builtin_fabs(x); - // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs" - (void)__builtin_fabsl(x); - // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabs' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs" (void)__builtin_cabsf(x); // expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}} @@ -578,32 +475,6 @@ void test_complex_double(_Complex double x) { } void test_complex_long_double(_Complex long double x) { - (void)abs(x); - // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsl" - (void)labs(x); - // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl" - (void)llabs(x); - // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl" - - (void)fabsf(x); - // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl" - (void)fabs(x); - // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl" - (void)fabsl(x); - // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}} - // expected-note@-2 {{use function 'cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl" - (void)cabsf(x); // expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}} // expected-note@-2 {{use function 'cabsl' instead}} @@ -614,32 +485,6 @@ void test_complex_long_double(_Complex long double x) { // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl" (void)cabsl(x); - (void)__builtin_abs(x); - // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsl" - (void)__builtin_labs(x); - // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl" - (void)__builtin_llabs(x); - // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl" - - (void)__builtin_fabsf(x); - // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl" - (void)__builtin_fabs(x); - // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl" - (void)__builtin_fabsl(x); - // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}} - // expected-note@-2 {{use function '__builtin_cabsl' instead}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl" - (void)__builtin_cabsf(x); // expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}} // expected-note@-2 {{use function '__builtin_cabsl' instead}} diff --git a/test/SemaCXX/warn-consumed-parsing.cpp b/test/SemaCXX/warn-consumed-parsing.cpp index 179604141b7b2..722a60bf98632 100644 --- a/test/SemaCXX/warn-consumed-parsing.cpp +++ b/test/SemaCXX/warn-consumed-parsing.cpp @@ -22,15 +22,15 @@ class AttrTester0 { void callableWhen() __attribute__ ((callable_when())); // expected-error {{'callable_when' attribute takes at least 1 argument}} }; -int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to methods}} -int var1 TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to methods}} -int var2 CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to methods}} +int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to functions}} +int var1 TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to}} +int var2 CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to}} int var3 CONSUMABLE(consumed); // expected-warning {{'consumable' attribute only applies to classes}} int var4 RETURN_TYPESTATE(consumed); // expected-warning {{'return_typestate' attribute only applies to functions}} -void function0() SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to methods}} -void function1() TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to methods}} -void function2() CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to methods}} +void function0() SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to}} +void function1() TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to}} +void function2() CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to}} void function3() CONSUMABLE(consumed); // expected-warning {{'consumable' attribute only applies to classes}} class CONSUMABLE(unknown) AttrTester1 { diff --git a/test/SemaCXX/warn-enum-compare.cpp b/test/SemaCXX/warn-enum-compare.cpp index 0c287948cd09a..21dea5dfcb00c 100644 --- a/test/SemaCXX/warn-enum-compare.cpp +++ b/test/SemaCXX/warn-enum-compare.cpp @@ -1,9 +1,12 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify +// RUN: %clang_cc1 %s -fsyntax-only -verify -triple %itanium_abi_triple +// RUN: %clang_cc1 %s -fsyntax-only -verify -triple %ms_abi_triple -DMSABI enum Foo { FooA, FooB, FooC }; enum Bar { BarD, BarE, BarF }; enum { AnonAA = 42, AnonAB = 43 }; enum { AnonBA = 44, AnonBB = 45 }; +enum { Anon1, Anon2, Anon3 }; +typedef enum { TD1, TD2 } TD; namespace name1 { enum Foo {F1, F2, F3}; @@ -29,6 +32,7 @@ void test () { name1::Foo a; oneFoo b; twoFoo c; + TD td; while (x == FooA); while (y == BarD); @@ -39,8 +43,10 @@ void test () { while (b == c); while (B1 == name1::B2); while (B2 == name2::B1); +#ifndef MSABI 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}} +#endif while (AnonAA == AnonAB); while (AnonAB == AnonBA); while (AnonBB == AnonAA); @@ -65,6 +71,11 @@ void test () { while ((((((B1))))) == (((name1::B2)))); while (B2 == ((((((name2::B1))))))); + while (td == Anon1); +#ifndef MSABI + while (td == AnonAA); // expected-warning {{comparison of constant 'AnonAA' (42) with expression of type 'TD' is always false}} +#endif + while (B1 == B2); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} while (name1::B2 == name2::B3); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} while (z == name2::B2); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} @@ -209,4 +220,65 @@ void test () { while (getBar() > x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} while (getBar() < x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (td == FooA); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'Foo')}} + while (td == BarD); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'Bar')}} + while (name1::F1 == td); // expected-warning {{comparison of two values with different enumeration types ('name1::Foo' and 'TD')}} + while (name2::B1 == td); // expected-warning {{comparison of two values with different enumeration types ('name2::Baz' and 'TD')}} + while (td == a); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'name1::Foo')}} + while (td == b); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'oneFoo' (aka 'name1::Foo'))}} + while (td == c); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'twoFoo' (aka 'name1::Foo'))}} + while (td == x); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'Foo')}} + while (td == y); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'Bar')}} + while (td == z); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'name1::Baz')}} + + while (a == TD1); // expected-warning {{comparison of two values with different enumeration types ('name1::Foo' and 'TD')}} + while (b == TD2); // expected-warning {{comparison of two values with different enumeration types ('oneFoo' (aka 'name1::Foo') and 'TD')}} + while (c == TD1); // expected-warning {{comparison of two values with different enumeration types ('twoFoo' (aka 'name1::Foo') and 'TD')}} + while (x == TD2); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'TD')}} + while (y == TD1); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'TD')}} + while (z == TD2); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'TD')}} + + switch (a) { + case name1::F1: break; + case name1::F3: break; + case name2::B2: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('name1::Foo' and 'name2::Baz')}} + } + + switch (x) { + case FooB: break; + case FooC: break; + case BarD: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('Foo' and 'Bar')}} + } + + switch(getBar()) { + case BarE: break; + case BarF: break; + case FooA: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('Bar' and 'Foo')}} + } + + switch(x) { + case AnonAA: break; // expected-warning {{case value not in enumerated type 'Foo'}} + case FooA: break; + case FooB: break; + case FooC: break; + } + + switch (td) { + case TD1: break; + case FooB: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('TD' and 'Foo')}} + case BarF: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('TD' and 'Bar')}} + // expected-warning@-1 {{case value not in enumerated type 'TD'}} + case AnonAA: break; // expected-warning {{case value not in enumerated type 'TD'}} + } + + switch (td) { + case Anon1: break; + case TD2: break; + } + + switch (a) { + case TD1: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('name1::Foo' and 'TD')}} + case TD2: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('name1::Foo' and 'TD')}} + case name1::F3: break; + } } diff --git a/test/SemaCXX/warn-global-constructors.cpp b/test/SemaCXX/warn-global-constructors.cpp index 856826414a8b3..430f239a3ed7e 100644 --- a/test/SemaCXX/warn-global-constructors.cpp +++ b/test/SemaCXX/warn-global-constructors.cpp @@ -126,3 +126,22 @@ namespace pr20420 { void *array_storage[1]; const int &global_reference = *(int *)array_storage; } + +namespace bitfields { + struct HasUnnamedBitfield { + unsigned a; + unsigned : 20; + unsigned b; + + constexpr HasUnnamedBitfield() : a(), b() {} + constexpr HasUnnamedBitfield(unsigned a, unsigned b) : a(a), b(b) {} + explicit HasUnnamedBitfield(unsigned a) {} + }; + + const HasUnnamedBitfield zeroConst{}; + HasUnnamedBitfield zeroMutable{}; + const HasUnnamedBitfield explicitConst{1, 2}; + HasUnnamedBitfield explicitMutable{1, 2}; + const HasUnnamedBitfield nonConstexprConst{1}; // expected-warning {{global constructor}} + HasUnnamedBitfield nonConstexprMutable{1}; // expected-warning {{global constructor}} +} diff --git a/test/SemaCXX/warn-sign-conversion-cpp11.cpp b/test/SemaCXX/warn-sign-conversion-cpp11.cpp new file mode 100644 index 0000000000000..e18b7f5645432 --- /dev/null +++ b/test/SemaCXX/warn-sign-conversion-cpp11.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wsign-conversion -std=c++11 %s + +unsigned int test() { + short foo; + return foo; // expected-warning {{implicit conversion changes signedness}} + +} + +unsigned int test3() { + // For a non-defined enum, use the underlying type. + enum u8 : signed char; + u8 foo{static_cast<u8>(0)}; + return foo; // expected-warning {{implicit conversion changes signedness}} + +} +unsigned int test2() { + // For a non-defined enum, use the underlying type. + enum u8 : unsigned char; + u8 foo{static_cast<u8>(0)}; + return foo; +} diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp index bbb4f9b48d365..fc1ea5e9e996e 100644 --- a/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_ASSERT_CAPABILITY=0 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_ASSERT_CAPABILITY=1 %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 @@ -13,8 +14,15 @@ #define ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__))) #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((exclusive_lock_function(__VA_ARGS__))) #define SHARED_LOCK_FUNCTION(...) __attribute__((shared_lock_function(__VA_ARGS__))) + +#if USE_ASSERT_CAPABILITY +#define ASSERT_EXCLUSIVE_LOCK(...) __attribute__((assert_capability(__VA_ARGS__))) +#define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_capability(__VA_ARGS__))) +#else #define ASSERT_EXCLUSIVE_LOCK(...) __attribute__((assert_exclusive_lock(__VA_ARGS__))) #define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_lock(__VA_ARGS__))) +#endif + #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__))) #define SHARED_TRYLOCK_FUNCTION(...) __attribute__((shared_trylock_function(__VA_ARGS__))) #define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) @@ -3675,9 +3683,14 @@ class Foo { SHARED_TRYLOCK_FUNCTION(true, mu2_); void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_) ASSERT_EXCLUSIVE_LOCK(mu2_); + + void alsoAssertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_, mu2_); + void assertShared() ASSERT_SHARED_LOCK(mu1_) ASSERT_SHARED_LOCK(mu2_); + void alsoAssertShared() ASSERT_SHARED_LOCK(mu1_, mu2_); + void test(); void testAssert(); void testAssertShared(); @@ -3741,17 +3754,33 @@ void Foo::test() { // Force duplication of attributes void Foo::assertBoth() { } +void Foo::alsoAssertBoth() { } void Foo::assertShared() { } +void Foo::alsoAssertShared() { } void Foo::testAssert() { - assertBoth(); - a = 0; - b = 0; + { + assertBoth(); + a = 0; + b = 0; + } + { + alsoAssertBoth(); + a = 0; + b = 0; + } } void Foo::testAssertShared() { - assertShared(); - int zz = a + b; + { + assertShared(); + int zz = a + b; + } + + { + alsoAssertShared(); + int zz = a + b; + } } @@ -4398,11 +4427,11 @@ namespace pt_guard_attribute_type { int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}} void test() { - int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} - int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} + int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}} + int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}} - typedef int PT_GUARDED_BY(sls_mu) bad1; // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} - typedef int PT_GUARDED_VAR bad2; // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} + typedef int PT_GUARDED_BY(sls_mu) bad1; // expected-warning {{'pt_guarded_by' attribute only applies to}} + typedef int PT_GUARDED_VAR bad2; // expected-warning {{'pt_guarded_var' attribute only applies to}} } } // end namespace pt_guard_attribute_type @@ -5204,3 +5233,18 @@ class acquired_before_empty_str { } // expected-warning {{mutex 'lock_' is still held at the end of function}} Mutex lock_ ACQUIRED_BEFORE(""); }; + +namespace PR34800 { +struct A { + operator int() const; +}; +struct B { + bool g() __attribute__((locks_excluded(h))); // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}} + int h; +}; +struct C { + B *operator[](int); +}; +C c; +void f() { c[A()]->g(); } +} // namespace PR34800 diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp index ae32bfe9c913e..ac357e8dae375 100644 --- a/test/SemaCXX/warn-thread-safety-parsing.cpp +++ b/test/SemaCXX/warn-thread-safety-parsing.cpp @@ -154,18 +154,18 @@ class GVFoo { }; class GUARDED_VAR GV { // \ - // expected-warning {{'guarded_var' attribute only applies to fields and global variables}} + // expected-warning {{'guarded_var' attribute only applies to non-static data members and global variables}} }; void gv_function() GUARDED_VAR; // \ - // expected-warning {{'guarded_var' attribute only applies to fields and global variables}} + // expected-warning {{'guarded_var' attribute only applies to}} void gv_function_params(int gv_lvar GUARDED_VAR); // \ - // expected-warning {{'guarded_var' attribute only applies to fields and global variables}} + // expected-warning {{'guarded_var' attribute only applies to}} int gv_testfn(int y){ int x GUARDED_VAR = y; // \ - // expected-warning {{'guarded_var' attribute only applies to fields and global variables}} + // expected-warning {{'guarded_var' attribute only applies to}} return x; } @@ -194,7 +194,7 @@ class PGVFoo { }; class PT_GUARDED_VAR PGV { // \ - // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} + // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}} }; int *pgv_var_args __attribute__((pt_guarded_var(1))); // \ @@ -202,14 +202,14 @@ int *pgv_var_args __attribute__((pt_guarded_var(1))); // \ void pgv_function() PT_GUARDED_VAR; // \ - // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} + // expected-warning {{'pt_guarded_var' attribute only applies to}} void pgv_function_params(int *gv_lvar PT_GUARDED_VAR); // \ - // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} + // expected-warning {{'pt_guarded_var' attribute only applies to}} void pgv_testfn(int y){ int *x PT_GUARDED_VAR = new int(0); // \ - // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} + // expected-warning {{'pt_guarded_var' attribute only applies to}} delete x; } @@ -231,28 +231,28 @@ class __attribute__((lockable (1))) LTestClass_args { // \ }; void l_test_function() LOCKABLE; // \ - // expected-warning {{'lockable' attribute only applies to struct, union or class}} + // expected-warning {{'lockable' attribute only applies to structs, unions, and classes}} int l_testfn(int y) { int x LOCKABLE = y; // \ - // expected-warning {{'lockable' attribute only applies to struct, union or class}} + // expected-warning {{'lockable' attribute only applies to}} return x; } int l_test_var LOCKABLE; // \ - // expected-warning {{'lockable' attribute only applies to struct, union or class}} + // expected-warning {{'lockable' attribute only applies to}} class LFoo { private: int test_field LOCKABLE; // \ - // expected-warning {{'lockable' attribute only applies to struct, union or class}} + // expected-warning {{'lockable' attribute only applies to}} void test_method() LOCKABLE; // \ - // expected-warning {{'lockable' attribute only applies to struct, union or class}} + // expected-warning {{'lockable' attribute only applies to}} }; void l_function_params(int lvar LOCKABLE); // \ - // expected-warning {{'lockable' attribute only applies to struct, union or class}} + // expected-warning {{'lockable' attribute only applies to}} //-----------------------------------------// @@ -271,28 +271,28 @@ class __attribute__((scoped_lockable (1))) SLTestClass_args { // \ }; void sl_test_function() SCOPED_LOCKABLE; // \ - // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}} + // expected-warning {{'scoped_lockable' attribute only applies to structs, unions, and classes}} int sl_testfn(int y) { int x SCOPED_LOCKABLE = y; // \ - // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}} + // expected-warning {{'scoped_lockable' attribute only applies to}} return x; } int sl_test_var SCOPED_LOCKABLE; // \ - // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}} + // expected-warning {{'scoped_lockable' attribute only applies to}} class SLFoo { private: int test_field SCOPED_LOCKABLE; // \ - // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}} + // expected-warning {{'scoped_lockable' attribute only applies to}} void test_method() SCOPED_LOCKABLE; // \ - // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}} + // expected-warning {{'scoped_lockable' attribute only applies to}} }; void sl_function_params(int lvar SCOPED_LOCKABLE); // \ - // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}} + // expected-warning {{'scoped_lockable' attribute only applies to}} //-----------------------------------------// @@ -325,18 +325,18 @@ class GBFoo { }; class GUARDED_BY(mu1) GB { // \ - // expected-warning {{'guarded_by' attribute only applies to fields and global variables}} + // expected-warning {{'guarded_by' attribute only applies to non-static data members and global variables}} }; void gb_function() GUARDED_BY(mu1); // \ - // expected-warning {{'guarded_by' attribute only applies to fields and global variables}} + // expected-warning {{'guarded_by' attribute only applies to}} void gb_function_params(int gv_lvar GUARDED_BY(mu1)); // \ - // expected-warning {{'guarded_by' attribute only applies to fields and global variables}} + // expected-warning {{'guarded_by' attribute only applies to}} int gb_testfn(int y){ int x GUARDED_BY(mu1) = y; // \ - // expected-warning {{'guarded_by' attribute only applies to fields and global variables}} + // expected-warning {{'guarded_by' attribute only applies to}} return x; } @@ -351,7 +351,8 @@ int gb_var_arg_5 GUARDED_BY(&mu1); int gb_var_arg_6 GUARDED_BY(muRef); int gb_var_arg_7 GUARDED_BY(muDoubleWrapper.getWrapper()->getMu()); int gb_var_arg_8 GUARDED_BY(muPointer); - +int gb_var_arg_9 GUARDED_BY(!&mu1); +int gb_var_arg_10 GUARDED_BY(!&*&mu1); // illegal attribute arguments int gb_var_arg_bad_1 GUARDED_BY(1); // \ @@ -396,18 +397,18 @@ class PGBFoo { }; class PT_GUARDED_BY(mu1) PGB { // \ - // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} + // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}} }; void pgb_function() PT_GUARDED_BY(mu1); // \ - // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} + // expected-warning {{'pt_guarded_by' attribute only applies to}} void pgb_function_params(int gv_lvar PT_GUARDED_BY(mu1)); // \ - // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} + // expected-warning {{'pt_guarded_by' attribute only applies to}} void pgb_testfn(int y){ int *x PT_GUARDED_BY(mu1) = new int(0); // \ - // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} + // expected-warning {{'pt_guarded_by' attribute only applies to}} delete x; } @@ -458,18 +459,18 @@ class AAFoo { }; class ACQUIRED_AFTER(mu1) AA { // \ - // expected-warning {{'acquired_after' attribute only applies to fields and global variables}} + // expected-warning {{'acquired_after' attribute only applies to non-static data members and global variables}} }; void aa_function() ACQUIRED_AFTER(mu1); // \ - // expected-warning {{'acquired_after' attribute only applies to fields and global variables}} + // expected-warning {{'acquired_after' attribute only applies to}} void aa_function_params(int gv_lvar ACQUIRED_AFTER(mu1)); // \ - // expected-warning {{'acquired_after' attribute only applies to fields and global variables}} + // expected-warning {{'acquired_after' attribute only applies to}} void aa_testfn(int y){ Mutex x ACQUIRED_AFTER(mu1) = Mutex(); // \ - // expected-warning {{'acquired_after' attribute only applies to fields and global variables}} + // expected-warning {{'acquired_after' attribute only applies to}} } //Check argument parsing. @@ -518,18 +519,18 @@ class ABFoo { }; class ACQUIRED_BEFORE(mu1) AB { // \ - // expected-warning {{'acquired_before' attribute only applies to fields and global variables}} + // expected-warning {{'acquired_before' attribute only applies to non-static data members and global variables}} }; void ab_function() ACQUIRED_BEFORE(mu1); // \ - // expected-warning {{'acquired_before' attribute only applies to fields and global variables}} + // expected-warning {{'acquired_before' attribute only applies to}} void ab_function_params(int gv_lvar ACQUIRED_BEFORE(mu1)); // \ - // expected-warning {{'acquired_before' attribute only applies to fields and global variables}} + // expected-warning {{'acquired_before' attribute only applies to}} void ab_testfn(int y){ Mutex x ACQUIRED_BEFORE(mu1) = Mutex(); // \ - // expected-warning {{'acquired_before' attribute only applies to fields and global variables}} + // expected-warning {{'acquired_before' attribute only applies to}} } // Note: illegal int ab_int ACQUIRED_BEFORE(mu1) will diff --git a/test/SemaCXX/warn-throw-out-noexcept-func.cpp b/test/SemaCXX/warn-throw-out-noexcept-func.cpp index 67ffbd93940a8..a6c23ddc6c8fb 100644 --- a/test/SemaCXX/warn-throw-out-noexcept-func.cpp +++ b/test/SemaCXX/warn-throw-out-noexcept-func.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fdelayed-template-parsing -fcxx-exceptions -fsyntax-only -Wexceptions -verify -std=c++11 +// RUN: %clang_cc1 %s -fdelayed-template-parsing -fcxx-exceptions -fsyntax-only -Wexceptions -verify -fdeclspec -std=c++11 struct A_ShouldDiag { ~A_ShouldDiag(); // implicitly noexcept(true) }; @@ -14,6 +14,15 @@ struct R_ShouldDiag : A_ShouldDiag { ~R_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}} throw 1; // expected-warning {{has a non-throwing exception specification but}} } + __attribute__((nothrow)) R_ShouldDiag() {// expected-note {{function declared non-throwing here}} + throw 1;// expected-warning {{has a non-throwing exception specification but}} + } + void __attribute__((nothrow)) SomeThrow() {// expected-note {{function declared non-throwing here}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} + } + void __declspec(nothrow) SomeDeclspecThrow() {// expected-note {{function declared non-throwing here}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} + } }; struct M_ShouldNotDiag { @@ -230,13 +239,30 @@ void n_ShouldNotDiag() noexcept { } catch (const S &s) { } } -void o_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}} +// As seen in p34973, this should not throw the warning. If there is an active +// exception, catch(...) catches everything. +void o_ShouldNotDiag() noexcept { try { - throw; //expected-warning {{has a non-throwing exception specification but}} + throw; } catch (...) { } } +void p_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}} + try { + throw; //expected-warning {{has a non-throwing exception specification but}} + } catch (int){ + } +} + +void q_ShouldNotDiag() noexcept { + try { + throw; + } catch (int){ + } catch (...){ + } +} + #define NOEXCEPT noexcept void with_macro() NOEXCEPT { //expected-note {{function declared non-throwing here}} throw 1; // expected-warning {{has a non-throwing exception specification but}} diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp index b08467ab51e63..08118147b7519 100644 --- a/test/SemaCXX/warn-unreachable.cpp +++ b/test/SemaCXX/warn-unreachable.cpp @@ -49,22 +49,26 @@ void test3() { (halt()); // expected-warning {{will never be executed}} } -void test4() { +namespace Test4 { struct S { int mem; } s; S &foor(); - halt(), foor()// expected-warning {{will never be executed}} - .mem; + void test4() { + halt(), foor()// expected-warning {{will never be executed}} + .mem; + } } -void test5() { +namespace Test5 { struct S { int mem; } s; S &foonr() __attribute__((noreturn)); - foonr() - .mem; // expected-warning {{will never be executed}} + void test5() { + foonr() + .mem; // expected-warning {{will never be executed}} + } } void test6() { diff --git a/test/SemaCXX/warn-unused-attribute.cpp b/test/SemaCXX/warn-unused-attribute.cpp index f52de3b931b0c..dffda31f46462 100644 --- a/test/SemaCXX/warn-unused-attribute.cpp +++ b/test/SemaCXX/warn-unused-attribute.cpp @@ -15,6 +15,6 @@ int main(void) { TestNormal normal; used.use(); - int i __attribute__((warn_unused)) = 12; // expected-warning {{'warn_unused' attribute only applies to struct, union or class}} + int i __attribute__((warn_unused)) = 12; // expected-warning {{'warn_unused' attribute only applies to structs, unions, and classes}} return i; } diff --git a/test/SemaCXX/warn-unused-lambda-capture.cpp b/test/SemaCXX/warn-unused-lambda-capture.cpp index 6ad8e26604a45..52ec390b0bba6 100644 --- a/test/SemaCXX/warn-unused-lambda-capture.cpp +++ b/test/SemaCXX/warn-unused-lambda-capture.cpp @@ -191,3 +191,12 @@ void test_templated() { void test_use_template() { test_templated<int>(); // expected-note{{in instantiation of function template specialization 'test_templated<int>' requested here}} } + +namespace pr35555 { +int a; +void b() { + int c[a]; + auto vla_used = [&c] { return c[0]; }; + auto vla_unused = [&c] {}; // expected-warning{{lambda capture 'c' is not used}} +} +} // namespace pr35555 diff --git a/test/SemaCXX/warn-unused-private-field.cpp b/test/SemaCXX/warn-unused-private-field.cpp index fb34fa98eaf67..fe44122a1d051 100644 --- a/test/SemaCXX/warn-unused-private-field.cpp +++ b/test/SemaCXX/warn-unused-private-field.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++17 %s class NotFullyDefined { public: @@ -246,3 +247,19 @@ namespace pr13543 { X x[4]; // no-warning }; } + +class implicit_special_member { +public: + static implicit_special_member make() { return implicit_special_member(); } + +private: + int n; // expected-warning{{private field 'n' is not used}} +}; + +class defaulted_special_member { +public: + defaulted_special_member(const defaulted_special_member&) = default; + +private: + int n; // expected-warning{{private field 'n' is not used}} +}; diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp index d7be785b35a69..a7ac9afc36ad6 100644 --- a/test/SemaCXX/warn-unused-variables.cpp +++ b/test/SemaCXX/warn-unused-variables.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify -std=c++11 %s template<typename T> void f() { T t; t = 17; @@ -194,3 +195,45 @@ void test() { } } + +#if __cplusplus >= 201103L +namespace with_constexpr { +template <typename T> +struct Literal { + T i; + Literal() = default; + constexpr Literal(T i) : i(i) {} +}; + +struct NoLiteral { + int i; + NoLiteral() = default; + constexpr NoLiteral(int i) : i(i) {} + ~NoLiteral() {} +}; + +static Literal<int> gl1; // expected-warning {{unused variable 'gl1'}} +static Literal<int> gl2(1); // expected-warning {{unused variable 'gl2'}} +static const Literal<int> gl3(0); // expected-warning {{unused variable 'gl3'}} + +template <typename T> +void test(int i) { + Literal<int> l1; // expected-warning {{unused variable 'l1'}} + Literal<int> l2(42); // expected-warning {{unused variable 'l2'}} + Literal<int> l3(i); // no-warning + Literal<T> l4(0); // no-warning + NoLiteral nl1; // no-warning + NoLiteral nl2(42); // no-warning +} +} + +namespace crash { +struct a { + a(const char *); +}; +template <typename b> +void c() { + a d(b::e ? "" : ""); +} +} +#endif diff --git a/test/SemaCXX/warn-zero-nullptr.cpp b/test/SemaCXX/warn-zero-nullptr.cpp index edd2a759b70f7..45f05fa5703b1 100644 --- a/test/SemaCXX/warn-zero-nullptr.cpp +++ b/test/SemaCXX/warn-zero-nullptr.cpp @@ -1,4 +1,10 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -DSYSTEM_WARNINGS -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 + +#include <warn-zero-nullptr.h> + +#define MACRO (0) +#define MCRO(x) (x) struct S {}; @@ -15,8 +21,12 @@ void* p2 = __null; // expected-warning{{zero as null pointer constant}} void (*fp2)() = __null; // expected-warning{{zero as null pointer constant}} int (S::*mp2) = __null; // expected-warning{{zero as null pointer constant}} -void f0(void* v = 0); // expected-warning{{zero as null pointer constant}} -void f1(void* v); +void f0(void* v = MACRO); // expected-warning{{zero as null pointer constant}} +void f1(void* v = NULL); // expected-warning{{zero as null pointer constant}} +void f2(void* v = MCRO(0)); // expected-warning{{zero as null pointer constant}} +void f3(void* v = MCRO(NULL)); // expected-warning{{zero as null pointer constant}} +void f4(void* v = 0); // expected-warning{{zero as null pointer constant}} +void f5(void* v); void g() { f1(0); // expected-warning{{zero as null pointer constant}} @@ -25,3 +35,58 @@ void g() { // Warn on these too. Matches gcc and arguably makes sense. void* pp = (decltype(nullptr))0; // expected-warning{{zero as null pointer constant}} void* pp2 = static_cast<decltype(nullptr)>(0); // expected-warning{{zero as null pointer constant}} + +// Shouldn't warn. +namespace pr34362 { +struct A { operator int*() { return nullptr; } }; +void func() { if (nullptr == A()) {} } +void func2() { if ((nullptr) == A()) {} } +} + +template <typename T> void TmplFunc0(T var) {} +void Func0Test() { + TmplFunc0<int>(0); + TmplFunc0<int*>(0); // expected-warning {{zero as null pointer constant}} + TmplFunc0<void*>(0); // expected-warning {{zero as null pointer constant}} +} + +// FIXME: this one probably should not warn. +template <typename T> void TmplFunc1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}} +void FuncTest() { + TmplFunc1<int>(0); + TmplFunc1<int*>(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1<int *>' required here}} + TmplFunc1<void*>(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1<void *>' required here}} +} + +template<typename T> +class TemplateClass0 { + public: + explicit TemplateClass0(T var) {} +}; +void TemplateClass0Test() { + TemplateClass0<int> a(0); + TemplateClass0<int*> b(0); // expected-warning {{zero as null pointer constant}} + TemplateClass0<void*> c(0); // expected-warning {{zero as null pointer constant}} +} + +template<typename T> +class TemplateClass1 { + public: +// FIXME: this one should *NOT* warn. + explicit TemplateClass1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}} +}; +void IgnoreSubstTemplateType1() { + TemplateClass1<int> a(1); + TemplateClass1<int*> b(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1<int *>' required here}} + TemplateClass1<void*> c(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1<void *>' required here}} +} + +#ifndef SYSTEM_WARNINGS +// Do not warn on *any* other macros from system headers, even if they +// expand to/their expansion contains NULL. +void* sys_init = SYSTEM_MACRO; +void* sys_init2 = OTHER_SYSTEM_MACRO; +#else +void* sys_init = SYSTEM_MACRO; // expected-warning {{zero as null pointer constant}} +void* sys_init2 = OTHER_SYSTEM_MACRO; // expected-warning {{zero as null pointer constant}} +#endif |