diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 |
commit | 2b6b257f4e5503a7a2675bdb8735693db769f75c (patch) | |
tree | e85e046ae7003fe3bcc8b5454cd0fa3f7407b470 /test/SemaCXX | |
parent | b4348ed0b7e90c0831b925fbee00b5f179a99796 (diff) | |
download | src-2b6b257f4e5503a7a2675bdb8735693db769f75c.tar.gz src-2b6b257f4e5503a7a2675bdb8735693db769f75c.zip |
Vendor import of clang release_39 branch r276489:vendor/clang/clang-release_39-r276489
Notes
Notes:
svn path=/vendor/clang/dist/; revision=303233
svn path=/vendor/clang/clang-release_39-r276489/; revision=303234; tag=vendor/clang/clang-release_39-r276489
Diffstat (limited to 'test/SemaCXX')
120 files changed, 3597 insertions, 217 deletions
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp index 22cf2be7c1ac..e10deadf7c7f 100644 --- a/test/SemaCXX/MicrosoftExtensions.cpp +++ b/test/SemaCXX/MicrosoftExtensions.cpp @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions +// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions -DTEST1 +// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fexceptions -fcxx-exceptions -DTEST2 +#if TEST1 // Microsoft doesn't validate exception specification. namespace microsoft_exception_spec { @@ -80,7 +82,73 @@ struct M { // __unaligned handling typedef char __unaligned *aligned_type; typedef struct UnalignedTag { int f; } __unaligned *aligned_type2; +typedef char __unaligned aligned_type3; +struct aligned_type4 { + int i; +}; + +__unaligned int aligned_type4::*p1_aligned_type4 = &aligned_type4::i; +int aligned_type4::* __unaligned p2_aligned_type4 = &aligned_type4::i; +__unaligned int aligned_type4::* __unaligned p3_aligned_type4 = &aligned_type4::i; +void (aligned_type4::*__unaligned p4_aligned_type4)(); + +// Check that __unaligned qualifier can be used for overloading +void foo_unaligned(int *arg) {} +void foo_unaligned(__unaligned int *arg) {} +void foo_unaligned(int arg) {} // expected-note {{previous definition is here}} +void foo_unaligned(__unaligned int arg) {} // expected-error {{redefinition of 'foo_unaligned'}} +class A_unaligned {}; +class B_unaligned : public A_unaligned {}; +int foo_unaligned(__unaligned A_unaligned *arg) { return 0; } +void *foo_unaligned(B_unaligned *arg) { return 0; } + +void test_unaligned() { + int *p1 = 0; + foo_unaligned(p1); + + __unaligned int *p2 = 0; + foo_unaligned(p2); + + __unaligned B_unaligned *p3 = 0; + int p4 = foo_unaligned(p3); + + B_unaligned *p5 = p3; // expected-error {{cannot initialize a variable of type 'B_unaligned *' with an lvalue of type '__unaligned B_unaligned *'}} + + __unaligned B_unaligned *p6 = p3; + + p1_aligned_type4 = p2_aligned_type4; + p2_aligned_type4 = p1_aligned_type4; // expected-error {{assigning to 'int aligned_type4::*' from incompatible type '__unaligned int aligned_type4::*'}} + p3_aligned_type4 = p1_aligned_type4; + + __unaligned int a[10]; + int *b = a; // expected-error {{cannot initialize a variable of type 'int *' with an lvalue of type '__unaligned int [10]'}} +} + +// Test from PR27367 +// We should accept assignment of an __unaligned pointer to a non-__unaligned +// pointer to void +typedef struct _ITEMIDLIST { int i; } ITEMIDLIST; +typedef ITEMIDLIST __unaligned *LPITEMIDLIST; +extern "C" __declspec(dllimport) void __stdcall CoTaskMemFree(void* pv); +__inline void FreeIDListArray(LPITEMIDLIST *ppidls) { + CoTaskMemFree(*ppidls); + __unaligned int *x = 0; + void *y = x; +} + +// Test from PR27666 +// We should accept type conversion of __unaligned to non-__unaligned references +typedef struct in_addr { +public: + in_addr(in_addr &a) {} // expected-note {{candidate constructor not viable: no known conversion from '__unaligned IN_ADDR *' (aka '__unaligned in_addr *') to 'in_addr &' for 1st argument; dereference the argument with *}} + in_addr(in_addr *a) {} // expected-note {{candidate constructor not viable: 1st argument ('__unaligned IN_ADDR *' (aka '__unaligned in_addr *')) would lose __unaligned qualifier}} +} IN_ADDR; + +void f(IN_ADDR __unaligned *a) { + IN_ADDR local_addr = *a; + IN_ADDR local_addr2 = a; // expected-error {{no viable conversion from '__unaligned IN_ADDR *' (aka '__unaligned in_addr *') to 'IN_ADDR' (aka 'in_addr')}} +} template<typename T> void h1(T (__stdcall M::* const )()) { } @@ -420,3 +488,15 @@ struct S { int S::fn() { return 0; } // expected-warning {{is missing exception specification}} } + +#elif TEST2 + +// Check that __unaligned is not recognized if MS extensions are not enabled +typedef char __unaligned *aligned_type; // expected-error {{expected ';' after top level declarator}} + +#else + +#error Unknown test mode + +#endif + diff --git a/test/SemaCXX/PR10177.cpp b/test/SemaCXX/PR10177.cpp index e361ff37bc03..9286e2935167 100644 --- a/test/SemaCXX/PR10177.cpp +++ b/test/SemaCXX/PR10177.cpp @@ -54,6 +54,7 @@ namespace N { namespace { template<typename> extern int n; } template<typename T> int g() { return n<int>; } +namespace { extern template int n<int>; } #endif diff --git a/test/SemaCXX/access.cpp b/test/SemaCXX/access.cpp index 5fa1509c5302..29a58a1388ac 100644 --- a/test/SemaCXX/access.cpp +++ b/test/SemaCXX/access.cpp @@ -158,3 +158,14 @@ namespace LocalExternVar { int array[sizeof(test::private_struct)]; // expected-error {{private}} } + +namespace ThisLambdaIsNotMyFriend { + class A { + friend class D; + static void foo(); // expected-note {{here}} + }; + template <class T> void foo() { + []() { A::foo(); }(); // expected-error {{private}} + } + void bar() { foo<void>(); } +} diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp index 4e4177463f88..ddaf33fc1bfa 100644 --- a/test/SemaCXX/aggregate-initialization.cpp +++ b/test/SemaCXX/aggregate-initialization.cpp @@ -1,4 +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 // Verify that using an initializer list for a non-aggregate looks for // constructors.. @@ -11,7 +13,7 @@ struct NonAggr1 { // expected-note 2 {{candidate constructor}} }; struct Base { }; -struct NonAggr2 : public Base { // expected-note 3 {{candidate constructor}} +struct NonAggr2 : public Base { // expected-note 0-3 {{candidate constructor}} int m; }; @@ -25,9 +27,15 @@ struct NonAggr4 { // expected-note 3 {{candidate constructor}} }; NonAggr1 na1 = { 17 }; // expected-error{{no matching constructor for initialization of 'NonAggr1'}} -NonAggr2 na2 = { 17 }; // expected-error{{no matching constructor for initialization of 'NonAggr2'}} +NonAggr2 na2 = { 17 }; NonAggr3 na3 = { 17 }; // expected-error{{no matching constructor for initialization of 'NonAggr3'}} NonAggr4 na4 = { 17 }; // expected-error{{no matching constructor for initialization of 'NonAggr4'}} +#if __cplusplus <= 201402L +// expected-error@-4{{no matching constructor for initialization of 'NonAggr2'}} +#else +// expected-error@-6{{requires explicit braces}} +NonAggr2 na2b = { {}, 17 }; // ok +#endif // PR5817 typedef int type[][2]; @@ -82,3 +90,59 @@ public: }; AggAgg aggagg = { 1, 2, 3, 4 }; + +namespace diff_cpp14_dcl_init_aggr_example { + struct derived; + struct base { + friend struct derived; + private: + base(); + }; + struct derived : base {}; + + derived d1{}; +#if __cplusplus > 201402L + // expected-error@-2 {{private}} + // expected-note@-7 {{here}} +#endif + derived d2; +} + +namespace ProtectedBaseCtor { + // FIXME: It's unclear whether f() and g() should be valid in C++1z. What is + // the object expression in a constructor call -- the base class subobject or + // the complete object? + struct A { + protected: + A(); + }; + + struct B : public A { + friend B f(); + friend B g(); + friend B h(); + }; + + B f() { return {}; } +#if __cplusplus > 201402L + // expected-error@-2 {{protected default constructor}} + // expected-note@-12 {{here}} +#endif + + B g() { return {{}}; } +#if __cplusplus <= 201402L + // expected-error@-2 {{no matching constructor}} + // expected-note@-15 3{{candidate}} +#else + // expected-error@-5 {{protected default constructor}} + // expected-note@-21 {{here}} +#endif + + B h() { return {A{}}; } +#if __cplusplus <= 201402L + // expected-error@-2 {{no matching constructor}} + // expected-note@-24 3{{candidate}} +#endif + // expected-error@-5 {{protected constructor}} + // expected-note@-30 {{here}} +} diff --git a/test/SemaCXX/alias-template.cpp b/test/SemaCXX/alias-template.cpp index bcfe428c69dd..b6256103ef8d 100644 --- a/test/SemaCXX/alias-template.cpp +++ b/test/SemaCXX/alias-template.cpp @@ -35,8 +35,8 @@ namespace VariableLengthArrays { template<typename Z> using T = int[n]; // expected-error {{variable length array declaration not allowed at file scope}} const int m = 42; - template<typename Z> using U = int[m]; // expected-note {{previous definition}} - template<typename Z> using U = int[42]; // ok + template<typename Z> using U = int[m]; + template<typename Z> using U = int[42]; // expected-note {{previous definition}} template<typename Z> using U = int; // expected-error {{type alias template redefinition with different types ('int' vs 'int [42]')}} } diff --git a/test/SemaCXX/anonymous-struct.cpp b/test/SemaCXX/anonymous-struct.cpp index 1b5dc13cea01..b584f89ff447 100644 --- a/test/SemaCXX/anonymous-struct.cpp +++ b/test/SemaCXX/anonymous-struct.cpp @@ -1,7 +1,12 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s struct S { - S(); // expected-note {{because type 'S' has a user-provided default constructor}} + S(); +#if __cplusplus <= 199711L + // expected-note@-2 {{because type 'S' has a user-provided default constructor}} +#endif }; struct { // expected-error {{anonymous structs and classes must be class members}} @@ -9,15 +14,25 @@ struct { // expected-error {{anonymous structs and classes must be class members struct E { struct { - S x; // expected-error {{anonymous struct member 'x' has a non-trivial constructor}} + S x; +#if __cplusplus <= 199711L + // expected-error@-2 {{anonymous struct member 'x' has a non-trivial constructor}} +#endif }; static struct { }; }; template <class T> void foo(T); -typedef struct { // expected-note {{use a tag name here to establish linkage prior to definition}} expected-note {{declared here}} +typedef struct { // expected-note {{use a tag name here to establish linkage prior to definition}} +#if __cplusplus <= 199711L +// expected-note@-2 {{declared here}} +#endif + void test() { - foo(this); // expected-warning {{template argument uses unnamed type}} + foo(this); +#if __cplusplus <= 199711L + // expected-warning@-2 {{template argument uses unnamed type}} +#endif } } A; // expected-error {{unsupported: typedef changes linkage of anonymous type, but linkage was already computed}} diff --git a/test/SemaCXX/ast-print.cpp b/test/SemaCXX/ast-print.cpp index 39a52ab8d7e8..408af35c2951 100644 --- a/test/SemaCXX/ast-print.cpp +++ b/test/SemaCXX/ast-print.cpp @@ -227,3 +227,14 @@ template <typename T> struct Foo : T { using T::operator-; }; } + +namespace dont_crash_on_auto_vars { +struct T { enum E {X = 12ll }; }; +struct S { + struct { int I; } ADecl; + static const auto Y = T::X; +}; +//CHECK: static const auto Y = T::X; +constexpr auto var = T::X; +//CHECK: constexpr auto var = T::X; +} diff --git a/test/SemaCXX/atomic-ops.cpp b/test/SemaCXX/atomic-ops.cpp new file mode 100644 index 000000000000..213161364f58 --- /dev/null +++ b/test/SemaCXX/atomic-ops.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -triple=i686-linux-gnu -std=c++11 + +// We crashed when we couldn't properly convert the first arg of __atomic_* to +// an lvalue. +void PR28623() { + void helper(int); // expected-note{{target}} + void helper(char); // expected-note{{target}} + __atomic_store_n(helper, 0, 0); // expected-error{{reference to overloaded function could not be resolved}} +} diff --git a/test/SemaCXX/attr-abi-tag-syntax.cpp b/test/SemaCXX/attr-abi-tag-syntax.cpp new file mode 100644 index 000000000000..4f14a3c043b5 --- /dev/null +++ b/test/SemaCXX/attr-abi-tag-syntax.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +namespace N1 { + +namespace __attribute__((__abi_tag__)) {} +// expected-warning@-1 {{'abi_tag' attribute on non-inline namespace ignored}} + +namespace N __attribute__((__abi_tag__)) {} +// expected-warning@-1 {{'abi_tag' attribute on non-inline namespace ignored}} + +} // namespace N1 + +namespace N2 { + +inline namespace __attribute__((__abi_tag__)) {} +// expected-warning@-1 {{'abi_tag' attribute on anonymous namespace ignored}} + +inline namespace N __attribute__((__abi_tag__)) {} + +} // namespcace N2 + +__attribute__((abi_tag("B", "A"))) extern int a1; + +__attribute__((abi_tag("A", "B"))) extern int a1; +// expected-note@-1 {{previous declaration is here}} + +__attribute__((abi_tag("A", "C"))) extern int a1; +// expected-error@-1 {{'abi_tag' C missing in original declaration}} + +extern int a2; +// expected-note@-1 {{previous declaration is here}} +__attribute__((abi_tag("A")))extern int a2; +// expected-error@-1 {{cannot add 'abi_tag' attribute in a redeclaration}} diff --git a/test/SemaCXX/attr-deprecated-replacement-error.cpp b/test/SemaCXX/attr-deprecated-replacement-error.cpp new file mode 100644 index 000000000000..54d0f9e74f34 --- /dev/null +++ b/test/SemaCXX/attr-deprecated-replacement-error.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -verify -fsyntax-only -std=c++11 -fms-extensions %s + +#if !__has_feature(attribute_deprecated_with_replacement) +#error "Missing __has_feature" +#endif + +int a1 [[deprecated("warning", "fixit")]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +int a2 [[deprecated("warning", 1)]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +int b1 [[gnu::deprecated("warning", "fixit")]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +int b2 [[gnu::deprecated("warning", 1)]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +__declspec(deprecated("warning", "fixit")) int c1; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +__declspec(deprecated("warning", 1)) int c2; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +int d1 __attribute__((deprecated("warning", "fixit"))); +int d2 __attribute__((deprecated("warning", 1))); // expected-error{{'deprecated' attribute requires a string}} diff --git a/test/SemaCXX/attr-deprecated-replacement-fixit.cpp b/test/SemaCXX/attr-deprecated-replacement-fixit.cpp new file mode 100644 index 000000000000..2e635a72c196 --- /dev/null +++ b/test/SemaCXX/attr-deprecated-replacement-fixit.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -verify -fsyntax-only %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: cp %s %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fixit %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -Werror %t + +#if !__has_feature(attribute_deprecated_with_replacement) +#error "Missing __has_feature" +#endif + +#if !__has_feature(attribute_availability_with_replacement) +#error "Missing __has_feature" +#endif + +void f_8(int) __attribute__((deprecated("message", "new8"))); // expected-note {{'f_8' has been explicitly marked deprecated here}} +void new8(int); +void f_2(int) __attribute__((availability(macosx,deprecated=9.0,replacement="new2"))); // expected-note {{'f_2' has been explicitly marked deprecated here}} +void new2(int); +void test() { + f_8(0); // expected-warning{{'f_8' is deprecated}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:6}:"new8" + f_2(0); // expected-warning{{'f_2' is deprecated: first deprecated in macOS 9.0}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:6}:"new2" +} diff --git a/test/SemaCXX/attr-lto-visibility-public.cpp b/test/SemaCXX/attr-lto-visibility-public.cpp new file mode 100644 index 000000000000..2f9ed87f6ee0 --- /dev/null +++ b/test/SemaCXX/attr-lto-visibility-public.cpp @@ -0,0 +1,14 @@ +// 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}} +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}} +}; + +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 new file mode 100644 index 000000000000..4e1489a8a5bd --- /dev/null +++ b/test/SemaCXX/attr-mode-tmpl.cpp @@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef enum { XX } EnumType; +struct S { int x; }; + +// Check enumerations. Vector modes on enum types must cause an error. +template <class T> +void CheckEnumerations() { + // Check that non-vector 'mode' attribute is OK with enumeration types. + typedef T __attribute__((mode(QI))) T1; + typedef T T2 __attribute__((mode(HI))); + typedef T __attribute__((mode(V8SI))) T3; // expected-error{{mode 'V8SI' is not supported for enumeration types}} + // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} + + typedef enum __attribute__((mode(HI))) { A4, B4 } T4; + typedef enum { A5, B5 } __attribute__((mode(SI))) T5; + typedef enum __attribute__((mode(V2SI))) { A6, B6 } T6; // expected-error{{mode 'V2SI' is not supported for enumeration types}} + // expected-warning@-1{{deprecated}} + typedef enum { A7, B7 } __attribute__((mode(V2QI))) T7; // expected-error{{mode 'V2QI' is not supported for enumeration types}} + // expected-warning@-1{{deprecated}} +} + +// Check that attribute applies only for integer and floating-point types. +// OK when instantiated with 'int', error with structure types, for example. +template <class T> +void CheckPrimitiveTypes() { + typedef T __attribute__((mode(QI))) T1; // expected-error{{mode attribute only supported for integer and floating-point types}} + typedef T __attribute__((mode(V2SI))) VT1; // expected-error{{mode attribute only supported for integer and floating-point types}} + // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} +} + +// Check that attribute supports certain modes. Check that wrong machine modes +// are NOT diagnosed twice during instantiation. +template <class T> +void CheckMachineMode() { + typedef T __attribute__((mode(QI))) T1; // expected-error{{type of machine mode does not match type of base type}} + typedef T __attribute__((mode(HI))) T2; // expected-error{{type of machine mode does not match type of base type}} + typedef T __attribute__((mode(SI))) T3; // expected-error{{type of machine mode does not match type of base type}} + typedef T __attribute__((mode(DI))) T4; // expected-error{{type of machine mode does not match type of base type}} + typedef T __attribute__((mode(SF))) T5; // expected-error2{{type of machine mode does not match type of base type}} + typedef T __attribute__((mode(DF))) T6; // expected-error2{{type of machine mode does not match type of base type}} + typedef T __attribute__((mode(II))) T7; // expected-error{{unknown machine mode}} + typedef T __attribute__((mode(12))) T8; // expected-error{{'mode' attribute requires an identifier}} +} + +// Check attributes on function parameters. +template <class T1, class T2> +void CheckParameters(T1 __attribute__((mode(SI))) paramSI, // expected-note2{{ignored: substitution failure}} + T1 __attribute__((mode(V4DI))) paramV4DI, // expected-warning{{deprecated}} + T2 __attribute__((mode(SF))) paramSF, + T2 __attribute__((mode(V4DF))) paramV4DF) { // expected-warning{{deprecated}} +} + + +// Check dependent structure. +template <class T> +struct TemplatedStruct { + // Check fields. + T __attribute__((mode(HI))) x1; + T __attribute__((mode(V4HI))) x2; // expected-error{{mode 'V4HI' is not supported for enumeration types}} + // expected-warning@-1{{deprecated}} + + // Check typedefs. + typedef T __attribute__((mode(DI))) T1; + typedef T __attribute__((mode(V8DI))) T2; // expected-error{{mode 'V8DI' is not supported for enumeration types}} + // expected-warning@-1{{deprecated}} + + // Check parameters. + void f1(T __attribute__((mode(QI))) x) {} + void f2(T __attribute__((mode(SF))) x) {} // expected-error2{{type of machine mode does not match type of base type}} + void f3(T __attribute__((mode(V4QI))) x) {} // expected-error{{mode 'V4QI' is not supported for enumeration types}} + // 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}} +}; + + + +int main() { + CheckEnumerations<int>(); + CheckEnumerations<EnumType>(); // expected-note{{in instantiation of}} + + CheckPrimitiveTypes<int>(); + CheckPrimitiveTypes<S>(); // expected-note{{in instantiation of}} + + // 'II' mode is unknown, no matter what we instantiate with. + CheckMachineMode<int>(); // expected-note{{in instantiation of}} + CheckMachineMode<EnumType>(); // expected-note{{in instantiation of}} + CheckMachineMode<float>(); // expected-note{{in instantiation of}} + + int __attribute__((mode(V4DI))) valV4DI; // expected-warning{{deprecated}} + float __attribute__((mode(V4DF))) valV4DF; // expected-warning{{deprecated}} + // OK. + CheckParameters<int, float>(0, valV4DI, 1.0, valV4DF); + // Enumeral type with vector mode is invalid. + CheckParameters<EnumType, float>(0, valV4DI, 1.0, valV4DF); // expected-error{{no matching function for call}} + // 'V4DF' mode with 'int' type is invalid. + CheckParameters<int, int>(0, valV4DI, 1, valV4DF); // expected-error{{no matching function for call}} + + TemplatedStruct<int> s1; // expected-note{{in instantiation of}} + TemplatedStruct<EnumType> s2; // expected-note{{in instantiation of}} + return 0; +} diff --git a/test/SemaCXX/attr-selectany.cpp b/test/SemaCXX/attr-selectany.cpp index 058f2fcb84ab..9dc14b3c3818 100644 --- a/test/SemaCXX/attr-selectany.cpp +++ b/test/SemaCXX/attr-selectany.cpp @@ -39,7 +39,9 @@ __declspec(selectany) auto x8 = Internal(); // expected-error {{'selectany' can // The D3D11 headers do something like this. MSVC doesn't error on this at // all, even without the __declspec(selectany), in violation of the standard. // We fall back to a warning for selectany to accept headers. -struct SomeStruct {}; +struct SomeStruct { + int foo; +}; extern const __declspec(selectany) SomeStruct some_struct; // expected-warning {{default initialization of an object of const type 'const SomeStruct' without a user-provided default constructor is a Microsoft extension}} // It should be possible to redeclare variables that were defined diff --git a/test/SemaCXX/attr-swiftcall.cpp b/test/SemaCXX/attr-swiftcall.cpp new file mode 100644 index 000000000000..fd17aae18523 --- /dev/null +++ b/test/SemaCXX/attr-swiftcall.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s + +#define SWIFTCALL __attribute__((swiftcall)) +#define INDIRECT_RESULT __attribute__((swift_indirect_result)) +#define ERROR_RESULT __attribute__((swift_error_result)) +#define CONTEXT __attribute__((swift_context)) + +int notAFunction SWIFTCALL; // expected-warning {{'swiftcall' only applies to function types; type here is 'int'}} +void variadic(int x, ...) SWIFTCALL; // expected-error {{variadic function cannot use swiftcall calling convention}} +void multiple_ccs(int x) SWIFTCALL __attribute__((vectorcall)); // expected-error {{vectorcall and swiftcall attributes are not compatible}} +void (*functionPointer)(void) SWIFTCALL; + +void indirect_result_nonswift(INDIRECT_RESULT void *out); // expected-error {{'swift_indirect_result' parameter can only be used with swiftcall calling convention}} +void indirect_result_bad_position(int first, INDIRECT_RESULT void *out) SWIFTCALL; // expected-error {{'swift_indirect_result' parameters must be first parameters of function}} +void indirect_result_bad_type(INDIRECT_RESULT int out) SWIFTCALL; // expected-error {{'swift_indirect_result' parameter must have pointer type; type here is 'int'}} +void indirect_result_single(INDIRECT_RESULT void *out) SWIFTCALL; +void indirect_result_multiple(INDIRECT_RESULT void *out1, INDIRECT_RESULT void *out2) SWIFTCALL; + +void error_result_nonswift(ERROR_RESULT void **error); // expected-error {{'swift_error_result' parameter can only be used with swiftcall calling convention}} expected-error{{'swift_error_result' parameter must follow 'swift_context' parameter}} +void error_result_bad_position(ERROR_RESULT void **error, int last) SWIFTCALL; // expected-error {{'swift_error_result' parameter must be last parameter of function}} +void error_result_bad_position2(int first, ERROR_RESULT void **error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must follow 'swift_context' parameter}} +void error_result_bad_type(CONTEXT void *context, ERROR_RESULT int error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must have pointer to unqualified pointer type; type here is 'int'}} +void error_result_bad_type2(CONTEXT void *context, ERROR_RESULT int *error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must have pointer to unqualified pointer type; type here is 'int *'}} +void error_result_okay(int a, int b, CONTEXT void *context, ERROR_RESULT void **error) SWIFTCALL; + +void context_nonswift(CONTEXT void *context); // expected-error {{'swift_context' parameter can only be used with swiftcall calling convention}} +void context_bad_position(CONTEXT void *context, int x) SWIFTCALL; // expected-error {{'swift_context' parameter can only be followed by 'swift_error_result' parameter}} +void context_bad_type(CONTEXT int context) SWIFTCALL; // expected-error {{'swift_context' parameter must have pointer type; type here is 'int'}} +void context_okay(CONTEXT void *context) SWIFTCALL; + +template <class T> void indirect_result_temp_okay1(INDIRECT_RESULT T *out) SWIFTCALL; +template <class T> void indirect_result_temp_okay2(INDIRECT_RESULT T out) SWIFTCALL; // expected-note {{candidate template ignored: substitution failure [with T = int]: 'swift_indirect_result' parameter must have pointer type; type here is 'int'}} +void test_indirect_result_temp(void *out) { + indirect_result_temp_okay1(out); + indirect_result_temp_okay2(out); + indirect_result_temp_okay2(1); // expected-error {{no matching function for call to 'indirect_result_temp_okay2'}} +} diff --git a/test/SemaCXX/attr-unavailable.cpp b/test/SemaCXX/attr-unavailable.cpp index 51dc8fe3789e..bafae2ab43a2 100644 --- a/test/SemaCXX/attr-unavailable.cpp +++ b/test/SemaCXX/attr-unavailable.cpp @@ -5,7 +5,8 @@ double &foo(double); // expected-note {{candidate}} void foo(...) __attribute__((__unavailable__)); // expected-note {{candidate function}} \ // expected-note{{'foo' has been explicitly marked unavailable here}} -void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}} +void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}} \ + // expected-note 2{{candidate function has been explicitly made unavailable}} void test_foo(short* sp) { int &ir = foo(1); @@ -56,3 +57,85 @@ typedef enum UnavailableEnum AnotherUnavailableEnum; // expected-error {{'Unavai __attribute__((unavailable)) UnavailableEnum testUnavailable(UnavailableEnum X) { return X; } + + +// Check that unavailable classes can be used as arguments to unavailable +// function, particularly in template functions. +#if !__has_feature(attribute_availability_in_templates) +#error "Missing __has_feature" +#endif +class __attribute((unavailable)) UnavailableClass; // \ + expected-note 3{{'UnavailableClass' has been explicitly marked unavailable here}} +void unavail_class(UnavailableClass&); // expected-error {{'UnavailableClass' is unavailable}} +void unavail_class_marked(UnavailableClass&) __attribute__((unavailable)); +template <class T> void unavail_class(UnavailableClass&); // expected-error {{'UnavailableClass' is unavailable}} +template <class T> void unavail_class_marked(UnavailableClass&) __attribute__((unavailable)); +template <class T> void templated(T&); +void untemplated(UnavailableClass &UC) { // expected-error {{'UnavailableClass' is unavailable}} + templated(UC); +} +void untemplated_marked(UnavailableClass &UC) __attribute__((unavailable)) { + templated(UC); +} + +template <class T> void templated_calls_bar() { bar(); } // \ + // expected-error{{call to unavailable function 'bar'}} +template <class T> void templated_calls_bar_arg(T v) { bar(v); } // \ + // expected-error{{call to unavailable function 'bar'}} +template <class T> void templated_calls_bar_arg_never_called(T v) { bar(v); } + +template <class T> +void unavail_templated_calls_bar() __attribute__((unavailable)) { // \ + expected-note{{candidate function [with T = int] has been explicitly made unavailable}} + bar(5); +} +template <class T> +void unavail_templated_calls_bar_arg(T v) __attribute__((unavailable)) { // \ + expected-note{{candidate function [with T = int] has been explicitly made unavailable}} + bar(v); +} + +void calls_templates_which_call_bar() { + templated_calls_bar<int>(); + + templated_calls_bar_arg(5); // \ + expected-note{{in instantiation of function template specialization 'templated_calls_bar_arg<int>' requested here}} + + unavail_templated_calls_bar<int>(); // \ + expected-error{{call to unavailable function 'unavail_templated_calls_bar'}} + + unavail_templated_calls_bar_arg(5); // \ + expected-error{{call to unavailable function 'unavail_templated_calls_bar_arg'}} +} + +template <class T> void unavail_templated(T) __attribute__((unavailable)); // \ + expected-note{{candidate function [with T = int] has been explicitly made unavailable}} +void calls_unavail_templated() { + unavail_templated(5); // expected-error{{call to unavailable function 'unavail_templated'}} +} +void unavail_calls_unavail_templated() __attribute__((unavailable)) { + unavail_templated(5); +} + +void unavailable() __attribute((unavailable)); // \ + expected-note 4{{candidate function has been explicitly made unavailable}} +struct AvailableStruct { + void calls_unavailable() { unavailable(); } // \ + expected-error{{call to unavailable function 'unavailable'}} + template <class U> void calls_unavailable() { unavailable(); } // \ + expected-error{{call to unavailable function 'unavailable'}} +}; +template <class T> struct AvailableStructTemplated { + void calls_unavailable() { unavailable(); } // \ + expected-error{{call to unavailable function 'unavailable'}} + template <class U> void calls_unavailable() { unavailable(); } // \ + expected-error{{call to unavailable function 'unavailable'}} +}; +struct __attribute__((unavailable)) UnavailableStruct { + void calls_unavailable() { unavailable(); } + template <class U> void calls_unavailable() { unavailable(); } +}; +template <class T> struct __attribute__((unavailable)) UnavailableStructTemplated { + void calls_unavailable() { unavailable(); } + template <class U> void calls_unavailable() { unavailable(); } +}; diff --git a/test/SemaCXX/attr-x86-interrupt.cpp b/test/SemaCXX/attr-x86-interrupt.cpp new file mode 100644 index 000000000000..95abc7cd74db --- /dev/null +++ b/test/SemaCXX/attr-x86-interrupt.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-pc-win32 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple i386-pc-win32 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnux32 -fsyntax-only -verify %s + +struct a { + int b; + static void foo(int *a) __attribute__((interrupt)) {} + void *operator new(__SIZE_TYPE__) throw() __attribute__((interrupt)) { return 0; } // expected-warning {{'interrupt' attribute only applies to non-K&R-style functions}} +}; + +struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to non-K&R-style functions}} + +__attribute__((interrupt)) int foo1(void) { return 0; } // expected-error-re {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have a 'void' return type}} +__attribute__((interrupt)) void foo2(void) {} // expected-error-re {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have only a pointer parameter optionally followed by an integer parameter}} +__attribute__((interrupt)) void foo3(void *a, unsigned b, int c) {} // expected-error-re {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have only a pointer parameter optionally followed by an integer parameter}} +__attribute__((interrupt)) void foo4(int a) {} // expected-error-re {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have a pointer as the first parameter}} +#ifdef _LP64 +// expected-error-re@+6 {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have a 'unsigned long' type as the second parameter}} +#elif defined(__x86_64__) +// expected-error-re@+4 {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have a 'unsigned long long' type as the second parameter}} +#else +// expected-error-re@+2 {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have a 'unsigned int' type as the second parameter}} +#endif +__attribute__((interrupt)) void foo5(void *a, float b) {} +#ifdef _LP64 +// expected-error-re@+6 {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have a 'unsigned long' type as the second parameter}} +#elif defined(__x86_64__) +// expected-error-re@+4 {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have a 'unsigned long long' type as the second parameter}} +#else +// expected-error-re@+2 {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have a 'unsigned int' type as the second parameter}} +#endif +__attribute__((interrupt)) void foo6(float *a, int b) {} + +#ifdef _LP64 +// expected-error-re@+4 {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have a 'unsigned long' type as the second parameter}} +#elif defined(__x86_64__) +// expected-error-re@+2 {{{{(x86|x86-64)}} 'interrupt' attribute only applies to functions that have a 'unsigned long long' type as the second parameter}} +#endif +__attribute__((interrupt)) void foo7(int *a, unsigned b) {} +__attribute__((interrupt)) void foo8(int *a) {} +template<typename T> +__attribute__((interrupt)) void foo9(T *a) {} + +template <typename T> +void bar(T *a) { + foo9(a); // expected-error {{interrupt service routine cannot be called directly}} +} + +template <typename Fn> +void bar1(Fn F) { + F(0); +} +__attribute__((interrupt)) void foo(int *) {} + +void g(void (*fp)(int *)); +int main(int argc, char **argv) { + void *ptr = (void *)&foo7; + g(foo8); + (void)ptr; + a::foo(ptr); // expected-error {{interrupt service routine cannot be called directly}} + bar1(foo); +#ifndef __x86_64__ + // expected-error@+2 {{interrupt service routine cannot be called directly}} +#endif + foo7((int *)argv, argc); + foo8((int *)argv); // expected-error {{interrupt service routine cannot be called directly}} + bar(argv); // expected-note {{in instantiation of function template specialization 'bar<char *>' requested here}} + return 0; +} + diff --git a/test/SemaCXX/builtin-classify-type.cpp b/test/SemaCXX/builtin-classify-type.cpp new file mode 100644 index 000000000000..f700c1d5baa9 --- /dev/null +++ b/test/SemaCXX/builtin-classify-type.cpp @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// expected-no-diagnostics + +enum gcc_type_class { + no_type_class = -1, + void_type_class, integer_type_class, char_type_class, + enumeral_type_class, boolean_type_class, + pointer_type_class, reference_type_class, offset_type_class, + real_type_class, complex_type_class, + function_type_class, method_type_class, + record_type_class, union_type_class, + array_type_class, string_type_class, + lang_type_class +}; + +class cl { +public: + void bar() {} + int baz; +}; + +int builtin_result; + +void foo() { + int i; + char c; + enum { red, green, blue} enum_obj; + bool b; + int *p; + int &r = i; + double d; + extern void f(); + cl cl_obj; + union { int a; float b; } u_obj; + int arr[10]; + + int a1[__builtin_classify_type(f()) == void_type_class ? 1 : -1]; + int a2[__builtin_classify_type(i) == integer_type_class ? 1 : -1]; + int a3[__builtin_classify_type(c) == integer_type_class ? 1 : -1]; + int a4[__builtin_classify_type(enum_obj) == enumeral_type_class ? 1 : -1]; + int a5[__builtin_classify_type(b) == boolean_type_class ? 1 : -1]; + int a6[__builtin_classify_type(p) == pointer_type_class ? 1 : -1]; + int a7[__builtin_classify_type(r) == integer_type_class ? 1 : -1]; + int a8[__builtin_classify_type(&cl::baz) == offset_type_class ? 1 : -1]; + int a9[__builtin_classify_type(d) == real_type_class ? 1 : -1]; + int a10[__builtin_classify_type(f) == function_type_class ? 1 : -1]; + int a11[__builtin_classify_type(&cl::bar) == method_type_class ? 1 : -1]; + int a12[__builtin_classify_type(cl_obj) == record_type_class ? 1 : -1]; + int a13[__builtin_classify_type(u_obj) == union_type_class ? 1 : -1]; + int a14[__builtin_classify_type(arr) == array_type_class ? 1 : -1]; + int a15[__builtin_classify_type("abc") == array_type_class ? 1 : -1]; +} + diff --git a/test/SemaCXX/builtin-object-size-cxx14.cpp b/test/SemaCXX/builtin-object-size-cxx14.cpp new file mode 100644 index 000000000000..32d752d27365 --- /dev/null +++ b/test/SemaCXX/builtin-object-size-cxx14.cpp @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s + +namespace basic { +// Ensuring that __bos can be used in constexpr functions without anything +// sketchy going on... +constexpr int bos0() { + int k = 5; + char cs[10] = {}; + return __builtin_object_size(&cs[k], 0); +} + +constexpr int bos1() { + int k = 5; + char cs[10] = {}; + return __builtin_object_size(&cs[k], 1); +} + +constexpr int bos2() { + int k = 5; + char cs[10] = {}; + return __builtin_object_size(&cs[k], 2); +} + +constexpr int bos3() { + int k = 5; + char cs[10] = {}; + return __builtin_object_size(&cs[k], 3); +} + +static_assert(bos0() == sizeof(char) * 5, ""); +static_assert(bos1() == sizeof(char) * 5, ""); +static_assert(bos2() == sizeof(char) * 5, ""); +static_assert(bos3() == sizeof(char) * 5, ""); +} + +namespace in_enable_if { +// The code that prompted these changes was __bos in enable_if + +void copy5CharsInto(char *buf) // expected-note{{candidate}} + __attribute__((enable_if(__builtin_object_size(buf, 0) != -1 && + __builtin_object_size(buf, 0) > 5, + ""))); + +// We use different EvalModes for __bos with type 0 versus 1. Ensure 1 works, +// too... +void copy5CharsIntoStrict(char *buf) // expected-note{{candidate}} + __attribute__((enable_if(__builtin_object_size(buf, 1) != -1 && + __builtin_object_size(buf, 1) > 5, + ""))); + +struct LargeStruct { + int pad; + char buf[6]; + int pad2; +}; + +struct SmallStruct { + int pad; + char buf[5]; + int pad2; +}; + +void noWriteToBuf() { + char buf[6]; + copy5CharsInto(buf); + + LargeStruct large; + copy5CharsIntoStrict(large.buf); +} + +void initTheBuf() { + char buf[6] = {}; + copy5CharsInto(buf); + + LargeStruct large = {0, {}, 0}; + copy5CharsIntoStrict(large.buf); +} + +int getI(); +void initTheBufWithALoop() { + char buf[6] = {}; + for (unsigned I = getI(); I != sizeof(buf); ++I) + buf[I] = I; + copy5CharsInto(buf); + + LargeStruct large; + for (unsigned I = getI(); I != sizeof(buf); ++I) + large.buf[I] = I; + copy5CharsIntoStrict(large.buf); +} + +void tooSmallBuf() { + char buf[5]; + copy5CharsInto(buf); // expected-error{{no matching function for call}} + + SmallStruct small; + copy5CharsIntoStrict(small.buf); // expected-error{{no matching function for call}} +} +} diff --git a/test/SemaCXX/c99-variable-length-array-cxx11.cpp b/test/SemaCXX/c99-variable-length-array-cxx11.cpp index 03cf28388d98..68858410ec76 100644 --- a/test/SemaCXX/c99-variable-length-array-cxx11.cpp +++ b/test/SemaCXX/c99-variable-length-array-cxx11.cpp @@ -22,5 +22,9 @@ void vla(int N) { POD array2[N]; // expected-warning{{variable length arrays are a C99 feature}} StillPOD array3[N]; // expected-warning{{variable length arrays are a C99 feature}} StillPOD2 array4[N][3]; // expected-warning{{variable length arrays are a C99 feature}} - NonPOD array5[N]; // expected-error{{variable length array of non-POD element type 'NonPOD'}} + NonPOD array5[N]; // expected-error{{no matching constructor for initialization of 'NonPOD [N]'}} + // expected-warning@-1{{variable length arrays are a C99 feature}} + // expected-note@-16{{candidate constructor not viable}} + // expected-note@-18{{candidate constructor (the implicit copy constructor) not viable}} + // expected-note@-19{{candidate constructor (the implicit move constructor) not viable}} } diff --git a/test/SemaCXX/c99-variable-length-array.cpp b/test/SemaCXX/c99-variable-length-array.cpp index 237f56458dab..5fd7e3749f7d 100644 --- a/test/SemaCXX/c99-variable-length-array.cpp +++ b/test/SemaCXX/c99-variable-length-array.cpp @@ -16,8 +16,8 @@ struct POD { void vla(int N) { int array1[N]; // expected-warning{{variable length arrays are a C99 feature}} POD array2[N]; // expected-warning{{variable length arrays are a C99 feature}} - NonPOD array3[N]; // expected-error{{variable length array of non-POD element type 'NonPOD'}} - NonPOD2 array4[N][3]; // expected-error{{variable length array of non-POD element type 'NonPOD2'}} + NonPOD array3[N]; // expected-warning{{variable length arrays are a C99 feature}} + NonPOD2 array4[N][3]; // expected-warning{{variable length arrays are a C99 feature}} } /// Warn about VLAs in templates. diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp index a6694403a68a..a3593689b5fb 100644 --- a/test/SemaCXX/class.cpp +++ b/test/SemaCXX/class.cpp @@ -1,7 +1,12 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wc++11-compat %s class C { public: - auto int errx; // expected-error {{storage class specified for a member declaration}} expected-warning {{'auto' storage class specifier is redundant}} + auto int errx; // expected-error {{storage class specified for a member declaration}} +#if __cplusplus <= 199711L + // expected-warning@-2 {{'auto' storage class specifier is redundant}} +#else + // expected-warning@-4 {{'auto' storage class specifier is not permitted in C++11, and will not be supported in future releases}} +#endif register int erry; // expected-error {{storage class specified for a member declaration}} extern int errz; // expected-error {{storage class specified for a member declaration}} @@ -36,12 +41,18 @@ public: enum E1 { en1, en2 }; - int i = 0; // expected-warning {{in-class initialization of non-static data member is a C++11 extension}} + int i = 0; +#if __cplusplus <= 199711L + // expected-warning@-2 {{in-class initialization of non-static data member is a C++11 extension}} +#endif static int si = 0; // expected-error {{non-const static data member must be initialized out of line}} static const NestedC ci = 0; // expected-error {{static data member of type 'const C::NestedC' must be initialized out of line}} static const int nci = vs; // expected-error {{in-class initializer for static data member is not a constant expression}} static const int vi = 0; static const volatile int cvi = 0; // ok, illegal in C++11 +#if __cplusplus >= 201103L + // expected-error@-2 {{static const volatile data member must be initialized out of line}} +#endif static const E evi = 0; void m() { @@ -169,10 +180,18 @@ namespace rdar8066414 { namespace rdar8367341 { float foo(); +#if __cplusplus >= 201103L + // expected-note@-2 {{declared here}} +#endif struct A { +#if __cplusplus <= 199711L static const float x = 5.0f; // expected-warning {{in-class initializer for static data member of type 'const float' is a GNU extension}} static const float y = foo(); // expected-warning {{in-class initializer for static data member of type 'const float' is a GNU extension}} expected-error {{in-class initializer for static data member is not a constant expression}} +#else + static constexpr float x = 5.0f; + static constexpr float y = foo(); // expected-error {{constexpr variable 'y' must be initialized by a constant expression}} expected-note {{non-constexpr function 'foo' cannot be used in a constant expression}} +#endif }; } diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp index b757fcb8cd5c..5596564d2481 100644 --- a/test/SemaCXX/condition.cpp +++ b/test/SemaCXX/condition.cpp @@ -65,3 +65,7 @@ void test5() { void test5_inst() { test5<int>(); } + +void PR28373() { + if (!x) {} // expected-error {{undeclared}} +} diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp index 538de5847de8..c12efc0be7ef 100644 --- a/test/SemaCXX/conditional-expr.cpp +++ b/test/SemaCXX/conditional-expr.cpp @@ -384,3 +384,12 @@ namespace PR17052 { int &test() { return b_ ? i_ : throw 1; } }; } + +namespace PR26448 { +struct Base {}; +struct Derived : Base {}; +Base b; +Derived d; +typedef decltype(true ? static_cast<Base&&>(b) : static_cast<Derived&&>(d)) x; +typedef Base &&x; +} diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index 7b9d0150e1e8..e2b3f091f70f 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -1181,6 +1181,20 @@ namespace ExternConstexpr { constexpr int j = 0; constexpr int k; // expected-error {{default initialization of an object of const type}} } + + extern const int q; + constexpr int g() { return q; } + constexpr int q = g(); + static_assert(q == 0, "zero-initialization should precede static initialization"); + + extern int r; // expected-note {{here}} + constexpr int h() { return r; } // expected-error {{never produces a constant}} expected-note {{read of non-const}} + + struct S { int n; }; + extern const S s; + constexpr int x() { return s.n; } + constexpr S s = {x()}; + static_assert(s.n == 0, "zero-initialization should precede static initialization"); } namespace ComplexConstexpr { @@ -2005,3 +2019,50 @@ namespace PR24597 { constexpr int a = *f().p; constexpr int b = *g().p; } + +namespace IncompleteClass { + struct XX { + static constexpr int f(XX*) { return 1; } // expected-note {{here}} + friend constexpr int g(XX*) { return 2; } // expected-note {{here}} + + static constexpr int i = f(static_cast<XX*>(nullptr)); // expected-error {{constexpr variable 'i' must be initialized by a constant expression}} expected-note {{undefined function 'f' cannot be used in a constant expression}} + static constexpr int j = g(static_cast<XX*>(nullptr)); // expected-error {{constexpr variable 'j' must be initialized by a constant expression}} expected-note {{undefined function 'g' cannot be used in a constant expression}} + }; +} + +namespace InheritedCtor { + struct A { constexpr A(int) {} }; + + struct B : A { int n; using A::A; }; // expected-note {{here}} + constexpr B b(0); // expected-error {{constant expression}} expected-note {{derived class}} + + struct C : A { using A::A; struct { union { int n, m = 0; }; union { int a = 0; }; int k = 0; }; struct {}; union {}; }; // expected-warning 4{{extension}} + constexpr C c(0); + + struct D : A { + using A::A; // expected-note {{here}} + struct { // expected-warning {{extension}} + union { // expected-warning {{extension}} + int n; + }; + }; + }; + constexpr D d(0); // expected-error {{constant expression}} expected-note {{derived class}} + + struct E : virtual A { using A::A; }; // expected-note {{here}} + // We wrap a function around this to avoid implicit zero-initialization + // happening first; the zero-initialization step would produce the same + // error and defeat the point of this test. + void f() { + constexpr E e(0); // expected-error {{constant expression}} expected-note {{derived class}} + } + // FIXME: This produces a note with no source location. + //constexpr E e(0); + + struct W { constexpr W(int n) : w(n) {} int w; }; + struct X : W { using W::W; int x = 2; }; + struct Y : X { using X::X; int y = 3; }; + struct Z : Y { using Y::Y; int z = 4; }; + constexpr Z z(1); + static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, ""); +} diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp index e9ecbe83b3da..f8103224af89 100644 --- a/test/SemaCXX/constant-expression-cxx1y.cpp +++ b/test/SemaCXX/constant-expression-cxx1y.cpp @@ -179,12 +179,10 @@ namespace string_assign { static_assert(!test1(100), ""); static_assert(!test1(101), ""); // expected-error {{constant expression}} expected-note {{in call to 'test1(101)'}} - // FIXME: We should be able to reject this before it's called - constexpr void f() { + constexpr void f() { // expected-error{{constexpr function never produces a constant expression}} expected-note@+2{{assignment to dereferenced one-past-the-end pointer is not allowed in a constant expression}} char foo[10] = { "z" }; // expected-note {{here}} - foo[10] = 'x'; // expected-warning {{past the end}} expected-note {{assignment to dereferenced one-past-the-end pointer}} + foo[10] = 'x'; // expected-warning {{past the end}} } - constexpr int k = (f(), 0); // expected-error {{constant expression}} expected-note {{in call}} } namespace array_resize { @@ -938,3 +936,24 @@ namespace EmptyClass { constexpr int testb = f(e2, 3); // expected-error {{constant expression}} expected-note {{in call}} constexpr int testc = f(e3, 3); } + +namespace SpeculativeEvalWrites { + // Ensure that we don't try to speculatively evaluate writes. + constexpr int f() { + int i = 0; + int a = 0; + // __builtin_object_size speculatively evaluates its first argument. + __builtin_object_size((i = 1, &a), 0); + return i; + } + + static_assert(!f(), ""); +} + +namespace PR27989 { + constexpr int f(int n) { + int a = (n = 1, 0); + return n; + } + static_assert(f(0) == 1, ""); +} diff --git a/test/SemaCXX/constant-expression-cxx1z.cpp b/test/SemaCXX/constant-expression-cxx1z.cpp new file mode 100644 index 000000000000..e84de44d374a --- /dev/null +++ b/test/SemaCXX/constant-expression-cxx1z.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -std=c++1z -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu + +namespace BaseClassAggregateInit { + struct A { + int a, b, c; + constexpr A(int n) : a(n), b(3 * n), c(b - 1) {} // expected-note {{outside the range of representable}} + constexpr A() : A(10) {}; + }; + struct B : A {}; + struct C { int q; }; + struct D : B, C { int k; }; + + constexpr D d1 = { 1, 2, 3 }; + static_assert(d1.a == 1 && d1.b == 3 && d1.c == 2 && d1.q == 2 && d1.k == 3); + + constexpr D d2 = { 14 }; + static_assert(d2.a == 14 && d2.b == 42 && d2.c == 41 && d2.q == 0 && d2.k == 0); + + constexpr D d3 = { A(5), C{2}, 1 }; + static_assert(d3.a == 5 && d3.b == 15 && d3.c == 14 && d3.q == 2 && d3.k == 1); + + constexpr D d4 = {}; + static_assert(d4.a == 10 && d4.b == 30 && d4.c == 29 && d4.q == 0 && d4.k == 0); + + constexpr D d5 = { __INT_MAX__ }; // expected-error {{must be initialized by a constant expression}} + // expected-note-re@-1 {{in call to 'A({{.*}})'}} +} diff --git a/test/SemaCXX/constexpr-nqueens.cpp b/test/SemaCXX/constexpr-nqueens.cpp index b158d6e4b6e0..47133a293434 100644 --- a/test/SemaCXX/constexpr-nqueens.cpp +++ b/test/SemaCXX/constexpr-nqueens.cpp @@ -10,26 +10,26 @@ struct Board { constexpr Board(const Board &O) : State(O.State), Failed(O.Failed) {} constexpr Board(uint64_t State, bool Failed = false) : State(State), Failed(Failed) {} - constexpr Board addQueen(int Row, int Col) { + constexpr Board addQueen(int Row, int Col) const { return Board(State | ((uint64_t)Row << (Col * 4))); } - constexpr int getQueenRow(int Col) { + constexpr int getQueenRow(int Col) const { return (State >> (Col * 4)) & 0xf; } - constexpr bool ok(int Row, int Col) { + constexpr bool ok(int Row, int Col) const { return okRecurse(Row, Col, 0); } - constexpr bool okRecurse(int Row, int Col, int CheckCol) { + constexpr bool okRecurse(int Row, int Col, int CheckCol) const { return Col == CheckCol ? true : getQueenRow(CheckCol) == Row ? false : getQueenRow(CheckCol) == Row + (Col - CheckCol) ? false : getQueenRow(CheckCol) == Row + (CheckCol - Col) ? false : okRecurse(Row, Col, CheckCol + 1); } - constexpr bool at(int Row, int Col) { + constexpr bool at(int Row, int Col) const { return getQueenRow(Col) == Row; } - constexpr bool check(const char *, int=0, int=0); + constexpr bool check(const char *, int=0, int=0) const; }; constexpr Board buildBoardRecurse(int N, int Col, const Board &B); @@ -54,7 +54,7 @@ constexpr Board buildBoard(int N) { constexpr Board q8 = buildBoard(8); -constexpr bool Board::check(const char *p, int Row, int Col) { +constexpr bool Board::check(const char *p, int Row, int Col) const { return *p == '\n' ? check(p+1, Row+1, 0) : *p == 'o' ? at(Row, Col) && check(p+1, Row, Col+1) : diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp index 065111133551..3528fdcd8816 100644 --- a/test/SemaCXX/constexpr-value-init.cpp +++ b/test/SemaCXX/constexpr-value-init.cpp @@ -14,7 +14,7 @@ void f() { constexpr A a; // expected-error {{constant expression}} expected-note {{in call to 'A()'}} } -constexpr B b1; // expected-error {{without a user-provided default constructor}} +constexpr B b1; // ok constexpr B b2 = B(); // ok static_assert(b2.a.a == 1, ""); static_assert(b2.a.b == 2, ""); diff --git a/test/SemaCXX/constructor-recovery.cpp b/test/SemaCXX/constructor-recovery.cpp index c1bb43628356..a0d8441012c5 100644 --- a/test/SemaCXX/constructor-recovery.cpp +++ b/test/SemaCXX/constructor-recovery.cpp @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -struct C { +struct C { // expected-note 1+{{candidate}} virtual C() = 0; // expected-error{{constructor cannot be declared 'virtual'}} }; void f() { - C c; + C c; // expected-error {{no matching constructor}} } diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp index 649f6b4dce94..3f494cce8ce3 100644 --- a/test/SemaCXX/conversion-function.cpp +++ b/test/SemaCXX/conversion-function.cpp @@ -1,4 +1,7 @@ // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -Wbind-to-temporary-copy -verify %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -Wbind-to-temporary-copy -verify -std=c++98 %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -Wbind-to-temporary-copy -verify -std=c++11 %s + class X { public: operator bool(); @@ -133,7 +136,12 @@ private: A1 f() { // FIXME: redundant diagnostics! - return "Hello"; // expected-error {{calling a private constructor}} expected-warning {{an accessible copy constructor}} + return "Hello"; // expected-error {{calling a private constructor}} +#if __cplusplus <= 199711L + // expected-warning@-2 {{an accessible copy constructor}} +#else + // expected-warning@-4 {{copying parameter of type 'A1' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}} +#endif } namespace source_locations { @@ -175,7 +183,13 @@ namespace crazy_declarators { (&operator bool())(); // expected-error {{use a typedef to declare a conversion to 'bool (&)()'}} *operator int(); // expected-error {{put the complete type after 'operator'}} // No suggestion of using a typedef here; that's not possible. - template<typename T> (&operator T())(); // expected-error-re {{cannot specify any part of a return type in the declaration of a conversion function{{$}}}} + template<typename T> (&operator T())(); +#if __cplusplus <= 199711L + // expected-error-re@-2 {{cannot specify any part of a return type in the declaration of a conversion function{{$}}}} +#else + // expected-error-re@-4 {{cannot specify any part of a return type in the declaration of a conversion function; use an alias template to declare a conversion to 'T (&)()'{{$}}}} +#endif + }; } @@ -193,6 +207,10 @@ namespace smart_ptr { }; struct X { // expected-note{{candidate constructor (the implicit copy constructor) not}} +#if __cplusplus >= 201103L + // expected-note@-2 {{candidate constructor (the implicit move constructor) not}} +#endif + explicit X(Y); }; @@ -215,7 +233,12 @@ struct Other { }; void test_any() { - Any any = Other(); // expected-error{{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}} + Any any = Other(); +#if __cplusplus <= 199711L + // expected-error@-2 {{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}} +#else + // expected-error@-4 {{cannot pass object of non-trivial type 'Other' through variadic constructor; call will abort at runtime}} +#endif } namespace PR7055 { diff --git a/test/SemaCXX/conversion.cpp b/test/SemaCXX/conversion.cpp index 4c4089c6aae7..7b86cecdbcef 100644 --- a/test/SemaCXX/conversion.cpp +++ b/test/SemaCXX/conversion.cpp @@ -228,3 +228,73 @@ namespace test10 { assert(test2(x)); } } + +namespace test11 { + +#define assert11(expr) ((expr) ? 0 : 0) + +// The whitespace in macro run1 are important to trigger the macro being split +// over multiple SLocEntry's. +#define run1() (dostuff() ? \ + NULL : NULL) +#define run2() (dostuff() ? NULL : NULL) +int dostuff (); + +void test(const char * content_type) { + assert11(run1()); + assert11(run2()); +} + +} + +namespace test12 { + +#define x return NULL; + +bool run() { + x // expected-warning{{}} +} + +} + +// More tests with macros. Specficially, test function-like macros that either +// have a pointer return type or take pointer arguments. Basically, if the +// macro was changed into a function and Clang doesn't warn, then it shouldn't +// warn for the macro either. +namespace test13 { +#define check_str_nullptr_13(str) ((str) ? str : nullptr) +#define check_str_null_13(str) ((str) ? str : NULL) +#define test13(condition) if (condition) return; +#define identity13(arg) arg +#define CHECK13(condition) test13(identity13(!(condition))) + +void function1(const char* str) { + CHECK13(check_str_nullptr_13(str)); + CHECK13(check_str_null_13(str)); +} + +bool some_bool_function(bool); +void function2() { + CHECK13(some_bool_function(nullptr)); // expected-warning{{implicit conversion of nullptr constant to 'bool'}} + CHECK13(some_bool_function(NULL)); // expected-warning{{implicit conversion of NULL constant to 'bool'}} +} + +#define run_check_nullptr_13(str) \ + if (check_str_nullptr_13(str)) return; +#define run_check_null_13(str) \ + if (check_str_null_13(str)) return; +void function3(const char* str) { + run_check_nullptr_13(str) + run_check_null_13(str) + if (check_str_nullptr_13(str)) return; + if (check_str_null_13(str)) return; +} + +void run(int* ptr); +#define conditional_run_13(ptr) \ + if (ptr) run(ptr); +void function4() { + conditional_run_13(nullptr); + conditional_run_13(NULL); +} +} diff --git a/test/SemaCXX/crashes.cpp b/test/SemaCXX/crashes.cpp index 926d13ab4533..a80587d8405b 100644 --- a/test/SemaCXX/crashes.cpp +++ b/test/SemaCXX/crashes.cpp @@ -105,8 +105,7 @@ namespace PR9026 { namespace PR10270 { template<typename T> class C; template<typename T> void f() { - if (C<T> == 1) // expected-error{{expected unqualified-id}} \ - // expected-error{{invalid '==' at end of declaration}} + if (C<T> == 1) // expected-error{{expected unqualified-id}} return; } } diff --git a/test/SemaCXX/cstyle-cast.cpp b/test/SemaCXX/cstyle-cast.cpp index afac6a137ec4..2327d7b51d97 100644 --- a/test/SemaCXX/cstyle-cast.cpp +++ b/test/SemaCXX/cstyle-cast.cpp @@ -84,11 +84,11 @@ void t_529_2() (void)(void*)((int*)0); (void)(volatile const void*)((const int*)0); (void)(A*)((B*)0); - (void)(A&)(*((B*)0)); + (void)(A&)(*((B*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}} (void)(const B*)((C1*)0); - (void)(B&)(*((C1*)0)); + (void)(B&)(*((C1*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}} (void)(A*)((D*)0); - (void)(const A&)(*((D*)0)); + (void)(const A&)(*((D*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}} (void)(int B::*)((int A::*)0); (void)(void (B::*)())((void (A::*)())0); (void)(A*)((E*)0); // C-style cast ignores access control diff --git a/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp index dfca17ad7cd8..17215fedf0ab 100644 --- a/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -11,6 +11,7 @@ struct non_const_copy { non_const_copy& operator = (non_const_copy&) &; non_const_copy& operator = (non_const_copy&) &&; non_const_copy() = default; // expected-note {{not viable}} + int uninit_field; }; non_const_copy::non_const_copy(non_const_copy&) = default; // expected-note {{not viable}} non_const_copy& non_const_copy::operator = (non_const_copy&) & = default; // expected-note {{not viable}} @@ -30,6 +31,98 @@ void fn1 () { ncc = cncc; // expected-error {{no viable overloaded}} }; +struct no_fields { }; +struct all_init { + int a = 0; + int b = 0; +}; +struct some_init { + int a = 0; + int b; + int c = 0; +}; +struct some_init_mutable { + int a = 0; + mutable int b; + int c = 0; +}; +struct some_init_def { + some_init_def() = default; + int a = 0; + int b; + int c = 0; +}; +struct some_init_ctor { + some_init_ctor(); + int a = 0; + int b; + int c = 0; +}; +struct sub_some_init : public some_init_def { }; +struct sub_some_init_ctor : public some_init_def { + sub_some_init_ctor(); +}; +struct sub_some_init_ctor2 : public some_init_ctor { +}; +struct some_init_container { + some_init_def sid; +}; +struct some_init_container_ctor { + some_init_container_ctor(); + some_init_def sid; +}; +struct no_fields_container { + no_fields nf; +}; +struct param_pack_ctor { + template <typename... T> + param_pack_ctor(T...); + int n; +}; +struct param_pack_ctor_field { + param_pack_ctor ndc; +}; +struct multi_param_pack_ctor { + template <typename... T, typename... U> + multi_param_pack_ctor(T..., U..., int f = 0); + int n; +}; +struct ignored_template_ctor_and_def { + template <class T> ignored_template_ctor_and_def(T* f = nullptr); + ignored_template_ctor_and_def() = default; + int field; +}; +template<bool, typename = void> struct enable_if {}; +template<typename T> struct enable_if<true, T> { typedef T type; }; +struct multi_param_pack_and_defaulted { + template <typename... T, + typename enable_if<sizeof...(T) != 0>::type* = nullptr> + multi_param_pack_and_defaulted(T...); + multi_param_pack_and_defaulted() = default; + int n; +}; + +void constobjs() { + const no_fields nf; // ok + const all_init ai; // ok + const some_init si; // expected-error {{default initialization of an object of const type 'const some_init' without a user-provided default constructor}} + const some_init_mutable sim; // ok + const some_init_def sid; // expected-error {{default initialization of an object of const type 'const some_init_def' without a user-provided default constructor}} + const some_init_ctor sic; // ok + const sub_some_init ssi; // expected-error {{default initialization of an object of const type 'const sub_some_init' without a user-provided default constructor}} + const sub_some_init_ctor ssic; // ok + const sub_some_init_ctor2 ssic2; // ok + const some_init_container sicon; // expected-error {{default initialization of an object of const type 'const some_init_container' without a user-provided default constructor}} + const some_init_container_ctor siconc; // ok + const no_fields_container nfc; // ok + const param_pack_ctor ppc; // ok + const param_pack_ctor_field ppcf; // ok + const multi_param_pack_ctor mppc; // ok + const multi_param_pack_and_defaulted mppad; // expected-error {{default initialization of an object of const type 'const multi_param_pack_and_defaulted' without a user-provided default constructor}} + const ignored_template_ctor_and_def itcad; // expected-error {{default initialization of an object of const type 'const ignored_template_ctor_and_def' without a user-provided default constructor}} + +} + struct non_const_derived : non_const_copy { non_const_derived(const non_const_derived&) = default; // expected-error {{requires it to be non-const}} non_const_derived& operator =(non_const_derived&) = default; diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp index 617a25716314..16e20ff4964d 100644 --- a/test/SemaCXX/cxx0x-defaulted-functions.cpp +++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp @@ -150,6 +150,14 @@ namespace PR13527 { Y::~Y() = default; // expected-error {{definition of explicitly defaulted}} } +namespace PR27699 { + struct X { + X(); + }; + X::X() = default; // expected-note {{here}} + X::X() = default; // expected-error {{redefinition of 'X'}} +} + namespace PR14577 { template<typename T> struct Outer { @@ -188,3 +196,15 @@ namespace PR15597 { A<int> a; B<int> b; // expected-note {{here}} } + +namespace PR27941 { +struct ExplicitBool { + ExplicitBool &operator=(bool) = default; // expected-error{{only special member functions may be defaulted}} + int member; +}; + +int fn() { + ExplicitBool t; + t = true; +} +} diff --git a/test/SemaCXX/cxx11-attr-print.cpp b/test/SemaCXX/cxx11-attr-print.cpp index 999eaed61802..12b41758c74d 100644 --- a/test/SemaCXX/cxx11-attr-print.cpp +++ b/test/SemaCXX/cxx11-attr-print.cpp @@ -16,6 +16,15 @@ int a __attribute__((deprecated("warning"))); // CHECK: int b {{\[}}[gnu::deprecated("warning")]]; int b [[gnu::deprecated("warning")]]; +// CHECK: __declspec(deprecated("warning")) +__declspec(deprecated("warning")) int c; + +// CHECK: int d {{\[}}[deprecated("warning")]]; +int d [[deprecated("warning")]]; + +// CHECK: __attribute__((deprecated("warning", "fixit"))); +int e __attribute__((deprecated("warning", "fixit"))); + // CHECK: int cxx11_alignas alignas(4); alignas(4) int cxx11_alignas; diff --git a/test/SemaCXX/cxx11-gnu-attrs.cpp b/test/SemaCXX/cxx11-gnu-attrs.cpp index d20617815e6a..231be727714e 100644 --- a/test/SemaCXX/cxx11-gnu-attrs.cpp +++ b/test/SemaCXX/cxx11-gnu-attrs.cpp @@ -19,6 +19,7 @@ int *[[gnu::unused]] attr_on_ptr; [[gnu::fastcall]] void pr17424_4() [[gnu::stdcall]]; // expected-warning@-1 {{calling convention 'fastcall' ignored for this target}} // expected-warning@-2 {{attribute 'stdcall' ignored, because it cannot be applied to a type}} +// expected-warning@-3 {{calling convention 'stdcall' ignored for this target}} void pr17424_5 [[gnu::fastcall]](); // expected-warning@-1 {{calling convention 'fastcall' ignored for this target}} diff --git a/test/SemaCXX/cxx11-inheriting-ctors.cpp b/test/SemaCXX/cxx11-inheriting-ctors.cpp index 04aa117b29dd..9c33ac05cc5f 100644 --- a/test/SemaCXX/cxx11-inheriting-ctors.cpp +++ b/test/SemaCXX/cxx11-inheriting-ctors.cpp @@ -34,3 +34,25 @@ namespace WrongIdent { using B::A; }; } + +namespace DefaultCtorConflict { + struct A { A(int = 0); }; + struct B : A { + using A::A; + } b; // ok, not ambiguous, inherited constructor suppresses implicit default constructor + struct C { + B b; + } c; +} + +namespace InvalidConstruction { + struct A { A(int); }; + struct B { B() = delete; }; + struct C : A, B { using A::A; }; + // Initialization here is performed as if by a defaulted default constructor, + // which would be ill-formed (in the immediate context) in this case because + // it would be defined as deleted. + template<typename T> void f(decltype(T(0))*); + template<typename T> int &f(...); + int &r = f<C>(0); +} diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp index 225d2348ccdc..593ec48b4394 100644 --- a/test/SemaCXX/cxx1y-deduced-return-type.cpp +++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp @@ -496,3 +496,13 @@ namespace TrailingReturnTypeForConversionOperator { } }; }; + +namespace PR24989 { + auto x = [](auto){}; + using T = decltype(x); + void (T::*p)(int) const = &T::operator(); +} + +void forinit_decltypeauto() { + for (decltype(auto) forinit_decltypeauto_inner();;) {} // expected-warning {{interpreted as a function}} expected-note {{replace}} +} diff --git a/test/SemaCXX/cxx1y-init-captures.cpp b/test/SemaCXX/cxx1y-init-captures.cpp index d36882d8e5d1..d681954707d0 100644 --- a/test/SemaCXX/cxx1y-init-captures.cpp +++ b/test/SemaCXX/cxx1y-init-captures.cpp @@ -196,3 +196,13 @@ namespace N3922 { auto a = [x{X()}] { return x.n; }; // ok auto b = [x = {X()}] {}; // expected-error{{<initializer_list>}} } + +namespace init_capture_non_mutable { +void test(double weight) { + double init; + auto find = [max = init](auto current) { + max = current; // expected-error{{cannot assign to a variable captured by copy in a non-mutable lambda}} + }; + find(weight); // expected-note {{in instantiation of function template specialization}} +} +} diff --git a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp index 65e2d6b608c2..e2fbdfd69954 100644 --- a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp +++ b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++11-extensions -Wno-c++1y-extensions -DPRECXX11 +// RUN: %clang_cc1 -std=c++98 -verify -fsyntax-only %s -Wno-c++11-extensions -Wno-c++1y-extensions -DPRECXX11 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s -// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s +// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s -DCPP1Y #define CONST const @@ -338,3 +338,47 @@ namespace b20896909 { A<int> ai; // expected-note {{in instantiation of}} } } +namespace member_access_is_ok { +#ifdef CPP1Y + namespace ns1 { + struct A { + template<class T, T N> constexpr static T Var = N; + }; + static_assert(A{}.Var<int,5> == 5,""); + } // end ns1 +#endif // CPP1Y + +namespace ns2 { + template<class T> struct A { + template<class U, T N, U M> static T&& Var; + }; + template<class T> template<class U, T N, U M> T&& A<T>::Var = T(N + M); + int *AV = &A<int>().Var<char, 5, 'A'>; + +} //end ns2 +} // end ns member_access_is_ok + +#ifdef CPP1Y +namespace PR24473 { +struct Value +{ + template<class T> + static constexpr T value = 0; +}; + +template<typename TValue> +struct Something +{ + void foo() { + static_assert(TValue::template value<int> == 0, ""); // error + } +}; + +int main() { + Something<Value>{}.foo(); + return 0; +} + +} // end ns PR24473 +#endif // CPP1Y + diff --git a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp index 787868fae176..496ae888732f 100644 --- a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp +++ b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11 +// RUN: %clang_cc1 -std=c++98 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s @@ -458,3 +458,9 @@ namespace PR19169 { template<> int g<double>; // expected-error {{no variable template matches specialization; did you mean to use 'g' as function template instead?}} } +#ifndef PRECXX11 +template <typename... Args> struct Variadic_t { }; +template <typename... Args> Variadic_t<Args...> Variadic; +auto variadic1 = Variadic<>; +auto variadic2 = Variadic<int, int>; +#endif diff --git a/test/SemaCXX/cxx1z-constexpr-lambdas.cpp b/test/SemaCXX/cxx1z-constexpr-lambdas.cpp new file mode 100644 index 000000000000..8e7657fb6e8d --- /dev/null +++ b/test/SemaCXX/cxx1z-constexpr-lambdas.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s +// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s +// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s +// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s + +namespace test_constexpr_checking { + +namespace ns1 { + struct NonLit { ~NonLit(); }; //expected-note{{not literal}} + auto L = [](NonLit NL) constexpr { }; //expected-error{{not a literal type}} +} // end ns1 + +namespace ns2 { + auto L = [](int I) constexpr { asm("non-constexpr"); }; //expected-error{{not allowed in constexpr function}} +} // end ns1 + +} // end ns test_constexpr_checking + +namespace test_constexpr_call { + +namespace ns1 { + auto L = [](int I) { return I; }; + static_assert(L(3) == 3); +} // end ns1 +namespace ns2 { + auto L = [](auto a) { return a; }; + static_assert(L(3) == 3); + static_assert(L(3.14) == 3.14); +} +namespace ns3 { + auto L = [](auto a) { asm("non-constexpr"); return a; }; //expected-note{{declared here}} + constexpr int I = //expected-error{{must be initialized by a constant expression}} + L(3); //expected-note{{non-constexpr function}} +} + +} // end ns test_constexpr_call
\ No newline at end of file diff --git a/test/SemaCXX/cxx1z-init-statement-warn-unused.cpp b/test/SemaCXX/cxx1z-init-statement-warn-unused.cpp new file mode 100644 index 000000000000..5390da4f3f5a --- /dev/null +++ b/test/SemaCXX/cxx1z-init-statement-warn-unused.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++1z -verify -Wuninitialized %s + +void testIf() { + if (bool b; b) // expected-warning {{uninitialized}} expected-note {{to silence}} + ; + if (int a, b = 2; a) // expected-warning {{uninitialized}} expected-note {{to silence}} + ; + int a; + if (a = 0; a) {} // OK +} + +void testSwitch() { + switch (bool b; b) { // expected-warning {{uninitialized}} expected-warning {{boolean value}} expected-note {{to silence}} + case 0: + break; + } + switch (int a, b = 7; a) { // expected-warning {{uninitialized}} expected-note {{to silence}} + case 0: + break; + } + int c; + switch (c = 0; c) { // OK + case 0: + break; + } +} diff --git a/test/SemaCXX/cxx1z-init-statement.cpp b/test/SemaCXX/cxx1z-init-statement.cpp new file mode 100644 index 000000000000..4afe0402d13f --- /dev/null +++ b/test/SemaCXX/cxx1z-init-statement.cpp @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -std=c++1z -verify %s + +void testIf() { + int x = 0; + if (x; x) ++x; + if (int t = 0; t) ++t; else --t; + + if (int x, y = 0; y) // expected-note 2 {{previous definition is here}} + int x = 0; // expected-error {{redefinition of 'x'}} + else + int x = 0; // expected-error {{redefinition of 'x'}} + + if (x; int a = 0) ++a; + if (x, +x; int a = 0) // expected-note 2 {{previous definition is here}} expected-warning {{unused}} + int a = 0; // expected-error {{redefinition of 'a'}} + else + int a = 0; // expected-error {{redefinition of 'a'}} + + if (int b = 0; b) + ; + b = 2; // expected-error {{use of undeclared identifier}} +} + +void testSwitch() { + int x = 0; + switch (x; x) { + case 1: + ++x; + } + + switch (int x, y = 0; y) { + case 1: + ++x; + default: + ++y; + } + + switch (int x, y = 0; y) { // expected-note 2 {{previous definition is here}} + case 0: + int x = 0; // expected-error {{redefinition of 'x'}} + case 1: + int y = 0; // expected-error {{redefinition of 'y'}} + }; + + switch (x; int a = 0) { + case 0: + ++a; + } + + switch (x, +x; int a = 0) { // expected-note {{previous definition is here}} expected-warning {{unused}} + case 0: + int a = 0; // expected-error {{redefinition of 'a'}} // expected-note {{previous definition is here}} + case 1: + int a = 0; // expected-error {{redefinition of 'a'}} + } + + switch (int b = 0; b) { + case 0: + break; + } + b = 2; // expected-error {{use of undeclared identifier}} +} + +constexpr bool constexpr_if_init(int n) { + if (int a = n; ++a > 0) + return true; + else + return false; +} + +constexpr int constexpr_switch_init(int n) { + switch (int p = n + 2; p) { + case 0: + return 0; + case 1: + return 1; + default: + return -1; + } +} + +void test_constexpr_init_stmt() { + constexpr bool a = constexpr_if_init(-2); + static_assert(!a, ""); + static_assert(constexpr_if_init(1), ""); + + constexpr int b = constexpr_switch_init(-1); + static_assert(b == 1, ""); + static_assert(constexpr_switch_init(-2) == 0, ""); + static_assert(constexpr_switch_init(-5) == -1, ""); +} diff --git a/test/SemaCXX/cxx1z-lambda-star-this.cpp b/test/SemaCXX/cxx1z-lambda-star-this.cpp new file mode 100644 index 000000000000..c23dd7b42719 --- /dev/null +++ b/test/SemaCXX/cxx1z-lambda-star-this.cpp @@ -0,0 +1,231 @@ +// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -emit-llvm-only %s +// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING +// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS +// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING + +template<class, class> constexpr bool is_same = false; +template<class T> constexpr bool is_same<T, T> = true; + +namespace test_star_this { +namespace ns1 { +class A { + int x = 345; + auto foo() { + (void) [*this, this] { }; //expected-error{{'this' can appear only once}} + (void) [this] { ++x; }; + (void) [*this] { ++x; }; //expected-error{{read-only variable}} + (void) [*this] () mutable { ++x; }; + (void) [=] { return x; }; + (void) [&, this] { return x; }; + (void) [=, *this] { return x; }; + (void) [&, *this] { return x; }; + } +}; +} // end ns1 + +namespace ns2 { + class B { + B(const B&) = delete; //expected-note{{deleted here}} + int *x = (int *) 456; + void foo() { + (void)[this] { return x; }; + (void)[*this] { return x; }; //expected-error{{call to deleted}} + } + }; +} // end ns2 +namespace ns3 { + class B { + B(const B&) = delete; //expected-note2{{deleted here}} + + int *x = (int *) 456; + public: + template<class T = int> + void foo() { + (void)[this] { return x; }; + (void)[*this] { return x; }; //expected-error2{{call to deleted}} + } + + B() = default; + } b; + B *c = (b.foo(), nullptr); //expected-note{{in instantiation}} +} // end ns3 + +namespace ns4 { +template<class U> +class B { + B(const B&) = delete; //expected-note{{deleted here}} + double d = 3.14; + public: + template<class T = int> + auto foo() { + const auto &L = [*this] (auto a) mutable { //expected-error{{call to deleted}} + d += a; + return [this] (auto b) { return d +=b; }; + }; + } + + B() = default; +}; +void main() { + B<int*> b; + b.foo(); //expected-note{{in instantiation}} +} // end main +} // end ns4 +namespace ns5 { + +struct X { + double d = 3.14; + X(const volatile X&); + void foo() { + + } + + void foo() const { //expected-note{{const}} + + auto L = [*this] () mutable { + static_assert(is_same<decltype(this), X*>); + ++d; + auto M = [this] { + static_assert(is_same<decltype(this), X*>); + ++d; + auto N = [] { + static_assert(is_same<decltype(this), X*>); + }; + }; + }; + + auto L1 = [*this] { + static_assert(is_same<decltype(this), const X*>); + auto M = [this] () mutable { + static_assert(is_same<decltype(this), const X*>); + auto N = [] { + static_assert(is_same<decltype(this), const X*>); + }; + }; + auto M2 = [*this] () mutable { + static_assert(is_same<decltype(this), X*>); + auto N = [] { + static_assert(is_same<decltype(this), X*>); + }; + }; + }; + + auto GL1 = [*this] (auto a) { + static_assert(is_same<decltype(this), const X*>); + auto M = [this] (auto b) mutable { + static_assert(is_same<decltype(this), const X*>); + auto N = [] (auto c) { + static_assert(is_same<decltype(this), const X*>); + }; + return N; + }; + + auto M2 = [*this] (auto a) mutable { + static_assert(is_same<decltype(this), X*>); + auto N = [] (auto b) { + static_assert(is_same<decltype(this), X*>); + }; + return N; + }; + return [=](auto a) mutable { M(a)(a); M2(a)(a); }; + }; + + GL1("abc")("abc"); + + + auto L2 = [this] () mutable { + static_assert(is_same<decltype(this), const X*>); + ++d; //expected-error{{cannot assign}} + }; + auto GL = [*this] (auto a) mutable { + static_assert(is_same<decltype(this), X*>); + ++d; + auto M = [this] (auto b) { + static_assert(is_same<decltype(this), X*>); + ++d; + auto N = [] (auto c) { + static_assert(is_same<decltype(this), X*>); + }; + N(3.14); + }; + M("abc"); + }; + GL(3.14); + + } + void foo() volatile const { + auto L = [this] () { + static_assert(is_same<decltype(this), const volatile X*>); + auto M = [*this] () mutable { + static_assert(is_same<decltype(this), X*>); + auto N = [this] { + static_assert(is_same<decltype(this), X*>); + auto M = [] { + static_assert(is_same<decltype(this), X*>); + }; + }; + auto N2 = [*this] { + static_assert(is_same<decltype(this), const X*>); + }; + }; + auto M2 = [*this] () { + static_assert(is_same<decltype(this), const X*>); + auto N = [this] { + static_assert(is_same<decltype(this), const X*>); + }; + }; + }; + } + +}; + +} //end ns5 +namespace ns6 { +struct X { + double d; + auto foo() const { + auto L = [*this] () mutable { + auto M = [=] (auto a) { + auto N = [this] { + ++d; + static_assert(is_same<decltype(this), X*>); + auto O = [*this] { + static_assert(is_same<decltype(this), const X*>); + }; + }; + N(); + static_assert(is_same<decltype(this), X*>); + }; + return M; + }; + return L; + } +}; + +int main() { + auto L = X{}.foo(); + auto M = L(); + M(3.14); +} +} // end ns6 +namespace ns7 { + +struct X { + double d; + X(); + X(const X&); + X(X&) = delete; + auto foo() const { + //OK - the object used to initialize our capture is a const object and so prefers the non-deleted ctor. + const auto &&L = [*this] { }; + } + +}; +int main() { + X x; + x.foo(); +} +} // end ns7 + +} //end ns test_star_this + diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp index 432c11646611..2b5149cf278f 100644 --- a/test/SemaCXX/dcl_init_aggr.cpp +++ b/test/SemaCXX/dcl_init_aggr.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++11 %s // C++ [dcl.init.aggr]p2 struct A { int x; @@ -9,14 +11,29 @@ struct A { } a1 = { 1, { 2, 3 } }; struct NonAggregate { +#if __cplusplus >= 201103L +// expected-note@-2 3 {{candidate constructor (the implicit copy constructor) not viable}} +// expected-note@-3 3 {{candidate constructor (the implicit move constructor) not viable}} +#endif NonAggregate(); - +#if __cplusplus >= 201103L +// expected-note@-2 3 {{candidate constructor not viable: requires 0 arguments, but 2 were provided}} +#endif int a, b; }; -NonAggregate non_aggregate_test = { 1, 2 }; // expected-error{{non-aggregate type 'NonAggregate' cannot be initialized with an initializer list}} - -NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; // expected-error 2 {{non-aggregate type 'NonAggregate' cannot be initialized with an initializer list}} - +NonAggregate non_aggregate_test = { 1, 2 }; +#if __cplusplus <= 199711L +// expected-error@-2 {{non-aggregate type 'NonAggregate' cannot be initialized with an initializer list}} +#else +// expected-error@-4 {{no matching constructor for initialization of 'NonAggregate'}} +#endif + +NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; +#if __cplusplus <= 199711L +// expected-error@-2 2 {{non-aggregate type 'NonAggregate' cannot be initialized with an initializer list}} +#else +// expected-error@-4 2 {{no matching constructor for initialization of 'NonAggregate'}} +#endif // C++ [dcl.init.aggr]p3 A a_init = A(); @@ -38,20 +55,55 @@ char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-error{{excess elements in ar // C++ [dcl.init.aggr]p7 struct TooFew { int a; char* b; int c; }; -TooFew too_few = { 1, "asdf" }; // expected-warning{{conversion from string literal to 'char *' is deprecated}} +TooFew too_few = { 1, "asdf" }; +#if __cplusplus <= 199711L +// expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}} +#else +// expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}} +#endif + +struct NoDefaultConstructor { +#if __cplusplus <= 199711L +// expected-note@-2 3 {{candidate constructor (the implicit copy constructor)}} +// expected-note@-3 {{declared here}} +#else +// expected-note@-5 4 {{candidate constructor (the implicit copy constructor)}} +// expected-note@-6 4 {{candidate constructor (the implicit move constructor)}} +#endif + + NoDefaultConstructor(int); +#if __cplusplus <= 199711L + // expected-note@-2 3 {{candidate constructor not viable: requires 1 argument, but 0 were provided}} +#else + // expected-note@-4 4 {{candidate constructor not viable: requires 1 argument, but 0 were provided}} +#endif -struct NoDefaultConstructor { // expected-note 3 {{candidate constructor (the implicit copy constructor)}} \ - // expected-note{{declared here}} - NoDefaultConstructor(int); // expected-note 3 {{candidate constructor}} }; -struct TooFewError { // expected-error{{implicit default constructor for}} +struct TooFewError { +#if __cplusplus <= 199711L +// expected-error@-2 {{implicit default constructor for}} +#endif + int a; - NoDefaultConstructor nodef; // expected-note{{member is declared here}} expected-note 2{{in implicit initialization of field 'nodef'}} + NoDefaultConstructor nodef; +#if __cplusplus <= 199711L +// expected-note@-2 {{member is declared here}} +// expected-note@-3 2{{in implicit initialization of field 'nodef' with omitted initializer}} +#else +// expected-note@-5 3{{in implicit initialization of field 'nodef' with omitted initializer}} +#endif }; TooFewError too_few_okay = { 1, 1 }; TooFewError too_few_error = { 1 }; // expected-error{{no matching constructor}} -TooFewError too_few_okay2[2] = { 1, 1 }; // expected-note{{implicit default constructor for 'TooFewError' first required here}} +TooFewError too_few_okay2[2] = { 1, 1 }; +#if __cplusplus <= 199711L +// expected-note@-2 {{implicit default constructor for 'TooFewError' first required here}} +#else +// expected-error@-4 {{no matching constructor for initialization of 'NoDefaultConstructor'}} +// expected-note@-5 {{in implicit initialization of array element 1 with omitted initializer}} +#endif + TooFewError too_few_error2[2] = { 1 }; // expected-error{{no matching constructor}} NoDefaultConstructor too_few_error3[3] = { }; // expected-error {{no matching constructor}} expected-note {{implicit initialization of array element 0}} @@ -116,6 +168,10 @@ B2 b2_3 = { c2, a2, a2 }; // C++ [dcl.init.aggr]p15: union u { int a; char* b; }; // expected-note{{candidate constructor (the implicit copy constructor)}} +#if __cplusplus >= 201103L +// expected-note@-2 {{candidate constructor (the implicit move constructor)}} +#endif + u u1 = { 1 }; u u2 = u1; u u3 = 1; // expected-error{{no viable conversion}} diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp index c4d40b4280e9..8f77f300572b 100644 --- a/test/SemaCXX/default2.cpp +++ b/test/SemaCXX/default2.cpp @@ -128,3 +128,7 @@ S<1> s; template <int I1 = I2, int I2 = 1> struct T {}; // expected-error-re {{use of undeclared identifier 'I2'{{$}}}} T<0, 1> t; + +struct PR28105 { + PR28105 (int = 0, int = 0, PR28105 = 0); // expected-error{{recursive evaluation of default argument}} +}; diff --git a/test/SemaCXX/delete-and-function-templates.cpp b/test/SemaCXX/delete-and-function-templates.cpp new file mode 100644 index 000000000000..22e95cb7937a --- /dev/null +++ b/test/SemaCXX/delete-and-function-templates.cpp @@ -0,0 +1,133 @@ +// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -emit-llvm-only %s +// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -fdelayed-template-parsing %s +// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -fms-extensions %s +// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -fdelayed-template-parsing -fms-extensions %s + +template<class T, class U> struct is_same { enum { value = false }; }; +template<class T> struct is_same<T, T> { enum { value = true }; }; + +namespace test_sfinae_and_delete { + +namespace ns1 { +template<class T> double f(T) = delete; //expected-note{{candidate}} +char f(...); //expected-note{{candidate}} + +static_assert(is_same<decltype(f(3)),char>::value, ""); //expected-error{{call to deleted function}} expected-error{{static_assert failed}} + +template<class T> decltype(f(T{})) g(T); // this one sfinae's out. +template<class T> int *g(T); +void foo() { + int *ip = g(3); +} +} //end ns1 + +namespace ns2 { +template<class T> double* f(T); +template<> double* f(double) = delete; + +template<class T> decltype(f(T{})) g(T); // expected-note{{candidate}} +template<class T> int *g(T); //expected-note{{candidate}} +void foo() { + double *dp = g(3); //expected-error{{ambiguous}} + int *ip = g(3.14); // this is OK - because the explicit specialization is deleted and sfinae's out one of the template candidates +} + +} // end ns2 + +namespace ns3 { +template<class T> double* f(T) = delete; +template<> double* f(double); + +template<class T> decltype(f(T{})) g(T); // expected-note{{candidate}} +template<class T> int *g(T); //expected-note{{candidate}} + +void foo() { + int *dp = g(3); // this is OK - because the non-double specializations are deleted and sfinae's out one of the template candidates + double *ip = g(3.14); //expected-error{{ambiguous}} +} + +} // end ns3 +} // end ns test_sfinae_and_delete + +namespace test_explicit_specialization_of_member { +namespace ns1 { +template<class T> struct X { + int* f(T) = delete; +}; +template<> int* X<int>::f(int) { } + +template<class T> decltype(X<T>{}.f(T{})) g(T); // expected-note{{candidate}} +template<class T> int *g(T); //expected-note{{candidate}} + +void foo() { + int *ip2 = g(3.14); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates + int *ip = g(3); //expected-error{{ambiguous}} +} + +} // end ns1 + +namespace ns2 { +struct X { +template<class T> double* f(T) = delete; +}; +template<> double* X::f(int); + +template<class T> decltype(X{}.f(T{})) g(T); // expected-note{{candidate}} +template<class T> int *g(T); //expected-note{{candidate}} + +void foo() { + int *ip2 = g(3.14); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates + int *ip = g(3); //expected-error{{ambiguous}} +} + +} // end ns2 + +namespace ns3 { +template<class T> struct X { + template<class U> double *f1(U, T) = delete; + template<class U> double *f2(U, T) = delete; +}; +template<> template<> double* X<int>::f1(int, int); +template<> template<class U> double* X<int>::f2(U, int); + +template<class T, class U> decltype(X<T>{}.f1(U{}, T{})) g1(U, T); // expected-note{{candidate}} +template<class T, class U> int *g1(U, T); //expected-note{{candidate}} + +template<class T, class U> decltype(X<T>{}.f2(U{}, T{})) g2(U, T); // expected-note2{{candidate}} +template<class T, class U> int *g2(U, T); //expected-note2{{candidate}} + + +void foo() { + int *ip2 = g1(3.14, 3); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates + int *ip = g1(3, 3); //expected-error{{ambiguous}} + { + int *ip3 = g2(3.14, 3); //expected-error{{ambiguous}} + int *ip4 = g2(3, 3); //expected-error{{ambiguous}} + } + { + int *ip3 = g2(3.14, 3.14); + int *ip4 = g2(3, 3.14); + } +} + + +} // end ns3 + +namespace ns4 { +template < typename T> T* foo (T); +template <> int* foo(int) = delete; +template <> int* foo(int); //expected-note{{candidate}} + +int *IP = foo(2); //expected-error{{deleted}} +double *DP = foo(3.14); +} //end ns4 + +namespace ns5 { +template < typename T> T* foo (T); +template <> int* foo(int); //expected-note{{previous}} +template <> int* foo(int) = delete; //expected-error{{deleted definition must be first declaration}} + +} //end ns5 + + +} // end test_explicit_specializations_and_delete diff --git a/test/SemaCXX/deleted-operator.cpp b/test/SemaCXX/deleted-operator.cpp index df67978a36d6..f71e83aa2587 100644 --- a/test/SemaCXX/deleted-operator.cpp +++ b/test/SemaCXX/deleted-operator.cpp @@ -9,7 +9,7 @@ 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 121 {{built-in candidate}} + if(a1==a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 144 {{built-in candidate}} } struct DelOpDel { diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp index e7323f90b3f7..fe1dde5771ac 100644 --- a/test/SemaCXX/destructor.cpp +++ b/test/SemaCXX/destructor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s +// 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 class A { public: @@ -257,6 +257,7 @@ void nowarnnonpoly() { } } +// FIXME: Why are these supposed to not warn? void nowarnarray() { { B* b = new B[4]; @@ -311,6 +312,14 @@ void nowarn0() { } } +void nowarn0_explicit_dtor(F* f, VB* vb, VD* vd, VF* vf) { + f->~F(); + f->~F(); + vb->~VB(); + vd->~VD(); + vf->~VF(); +} + void warn0() { { B* b = new B(); @@ -326,6 +335,17 @@ void warn0() { } } +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. + + 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(); + + d->~D(); // expected-warning {{destructor called on non-final 'dnvd::D' that has virtual functions but non-virtual destructor}} expected-note{{qualify call to silence this warning}} + d->D::~D(); +} + void nowarn1() { { simple_ptr<F> f(new F()); @@ -403,3 +423,11 @@ void g(S s) { (s.~S); // expected-error{{reference to destructor must be called}} } } + +class Invalid { + ~Invalid(); + UnknownType xx; // expected-error{{unknown type name}} +}; + +// The constructor definition should not have errors +Invalid::~Invalid() {} diff --git a/test/SemaCXX/diagnostic-order.cpp b/test/SemaCXX/diagnostic-order.cpp new file mode 100644 index 000000000000..4ced22c92ac6 --- /dev/null +++ b/test/SemaCXX/diagnostic-order.cpp @@ -0,0 +1,73 @@ +// RUN: not %clang_cc1 -std=c++11 %s -fsyntax-only 2>&1 | FileCheck %s +// RUN: %clang_cc1 -std=c++11 %s -fsyntax-only -DWARN 2>&1 | FileCheck %s --check-prefix=CHECK-WARN + +#ifndef WARN + +// Ensure that the diagnostics we produce for this situation appear in a +// deterministic order. This requires ADL to provide lookup results in a +// deterministic order. +template<typename T, typename> struct Error { typedef typename T::error error; }; +struct X { template<typename T> friend typename Error<X, T>::error f(X, T); }; +struct Y { template<typename T> friend typename Error<Y, T>::error f(T, Y); }; + +void g() { + f(X(), Y()); +} + +// We don't really care which order these two diagnostics appear (although the +// order below is source order, which seems best). The crucial fact is that +// there is one single order that is stable across multiple runs of clang. +// +// CHECK: no type named 'error' in 'X' +// CHECK: no type named 'error' in 'Y' +// CHECK: no matching function for call to 'f' + + +struct Oper { + template<typename T, typename U = typename Error<Oper, T>::error> operator T(); + + operator int*(); + operator float*(); + operator X*(); + operator Y*(); + + operator int(*[1])(); + operator int(*[2])(); + operator int(*[3])(); + operator int(*[4])(); + operator int(*[5])(); + operator int(*[6])(); + operator int(*[7])(); + operator int(*[8])(); + operator float(*[1])(); + operator float(*[2])(); + operator float(*[3])(); + operator float(*[4])(); + operator float(*[5])(); + operator float(*[6])(); + operator float(*[7])(); + operator float(*[8])(); +}; +int *p = Oper() + 0; + +// CHECK: no type named 'error' in 'Oper' +// CHECK: in instantiation of template class 'Error<Oper, int *>' +// CHECK: no type named 'error' in 'Oper' +// CHECK: in instantiation of template class 'Error<Oper, float *>' +// CHECK: no type named 'error' in 'Oper' +// CHECK: in instantiation of template class 'Error<Oper, X *>' +// CHECK: no type named 'error' in 'Oper' +// CHECK: in instantiation of template class 'Error<Oper, Y *>' + +#endif + +template<typename T> struct UndefButUsed { + static inline int f(); + static int g() { return f(); } +}; +int undef_but_used = UndefButUsed<int>::g() + UndefButUsed<float>::g() + UndefButUsed<char>::g() + UndefButUsed<void>::g(); + +// CHECK-WARN: inline function 'UndefButUsed<int>::f' is not defined +// CHECK-WARN: inline function 'UndefButUsed<float>::f' is not defined +// CHECK-WARN: inline function 'UndefButUsed<char>::f' is not defined +// CHECK-WARN: inline function 'UndefButUsed<void>::f' is not defined diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp index 0bbf9b370b4d..b4850fc03d9b 100644 --- a/test/SemaCXX/dllexport.cpp +++ b/test/SemaCXX/dllexport.cpp @@ -16,13 +16,19 @@ struct External { int v; }; // Invalid usage. -__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} -typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} -typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} -typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} -enum __declspec(dllexport) Enum {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} +__declspec(dllexport) typedef int typedef1; +// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} +typedef __declspec(dllexport) int typedef2; +// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} +typedef int __declspec(dllexport) typedef3; +// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} +typedef __declspec(dllexport) void (*FunTy)(); +// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} +enum __declspec(dllexport) Enum {}; +// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} #if __has_feature(cxx_strong_enums) - enum class __declspec(dllexport) EnumClass {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} +enum class __declspec(dllexport) EnumClass {}; +// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}} #endif diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp index 5d8ce78f6cdc..36a8ac625ac3 100644 --- a/test/SemaCXX/dllimport.cpp +++ b/test/SemaCXX/dllimport.cpp @@ -15,13 +15,19 @@ namespace { struct Internal {}; } // Invalid usage. -__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} -typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} -typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} -typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} -enum __declspec(dllimport) Enum {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} +__declspec(dllimport) typedef int typedef1; +// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} +typedef __declspec(dllimport) int typedef2; +// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} +typedef int __declspec(dllimport) typedef3; +// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} +typedef __declspec(dllimport) void (*FunTy)(); +// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} +enum __declspec(dllimport) Enum {}; +// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} #if __has_feature(cxx_strong_enums) - enum class __declspec(dllimport) EnumClass {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} +enum class __declspec(dllimport) EnumClass {}; +// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} #endif @@ -44,17 +50,49 @@ __declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dlli int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}} // Declare, then reject definition. -__declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -int ExternGlobalDeclInit = 1; // expected-warning{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef GNU +// expected-note@+2{{previous attribute is here}} +#endif +__declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} +#ifdef MS +// expected-warning@+4{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else +// expected-warning@+2{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +int ExternGlobalDeclInit = 1; -__declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -int GlobalDeclInit = 1; // expected-warning{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef GNU +// expected-note@+2{{previous attribute is here}} +#endif +__declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} +#ifdef MS +// expected-warning@+4{{'GlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else +// expected-warning@+2{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +int GlobalDeclInit = 1; -int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -int *GlobalDeclChunkAttrInit = 0; // expected-warning{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef GNU +// expected-note@+2{{previous attribute is here}} +#endif +int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} +#ifdef MS +// expected-warning@+4{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else +// expected-warning@+2{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +int *GlobalDeclChunkAttrInit = 0; -int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -int GlobalDeclAttrInit = 1; // expected-warning{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef GNU +// expected-note@+2{{previous attribute is here}} +#endif +int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} +#ifdef MS +// expected-warning@+4{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else +// expected-warning@+2{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +int GlobalDeclAttrInit = 1; // Redeclarations __declspec(dllimport) extern int GlobalRedecl1; @@ -69,8 +107,6 @@ int *__attribute__((dllimport)) GlobalRedecl2b; int GlobalRedecl2c __attribute__((dllimport)); int GlobalRedecl2c __attribute__((dllimport)); -// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC -// and drop the dllimport with a warning. __declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} @@ -135,11 +171,31 @@ template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-err template<typename T> int __declspec(dllimport) VarTmplInit2 = 1; // expected-error{{definition of dllimport data}} // Declare, then reject definition. -template<typename T> __declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -template<typename T> int ExternVarTmplDeclInit = 1; // expected-warning{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef GNU +// expected-note@+3{{previous attribute is here}} +#endif +template <typename T> +__declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}} +#ifdef MS +// expected-warning@+5{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else +// expected-warning@+3{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +template <typename T> +int ExternVarTmplDeclInit = 1; -template<typename T> __declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -template<typename T> int VarTmplDeclInit = 1; // expected-warning{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef GNU +// expected-note@+3{{previous attribute is here}} +#endif +template <typename T> +__declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}} +#ifdef MS +// expected-warning@+5{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else +// expected-warning@+3{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +template <typename T> +int VarTmplDeclInit = 1; // Redeclarations template<typename T> __declspec(dllimport) extern int VarTmplRedecl1; @@ -238,13 +294,20 @@ __declspec(dllimport) void inlineDef(); __declspec(dllimport) void redecl1(); __declspec(dllimport) void redecl1(); -// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC -// and drop the dllimport with a warning. __declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -__declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} - void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef GNU + // expected-note@+2{{previous attribute is here}} +#endif + __declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} + // NB: Both MSVC and Clang issue a warning and make redecl3 dllexport. +#ifdef MS + // expected-warning@+4{{'redecl3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else + // expected-warning@+2{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif + void redecl3() {} void redecl4(); // expected-note{{previous declaration is here}} __declspec(dllimport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllimport' attribute}} @@ -266,7 +329,10 @@ __declspec(dllimport) inline void redecl6() {} // expected-warning{{'dllimport' struct FuncFriend { friend __declspec(dllimport) void friend1(); friend __declspec(dllimport) void friend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} - friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} +#ifdef GNU +// expected-note@+2{{previous attribute is here}} +#endif + friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}} friend void friend4(); // expected-note{{previous declaration is here}} #ifdef MS // expected-note@+2{{previous declaration is here}} @@ -275,7 +341,12 @@ struct FuncFriend { }; __declspec(dllimport) void friend1(); void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} - void friend3() {} // expected-warning{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef MS + // expected-warning@+4{{'friend3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else + // expected-warning@+2{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif + void friend3() {} __declspec(dllimport) void friend4(); // expected-warning{{redeclaration of 'friend4' should not add 'dllimport' attribute}} #ifdef MS __declspec(dllimport) inline void friend5() {} // expected-warning{{redeclaration of 'friend5' should not add 'dllimport' attribute}} @@ -447,33 +518,39 @@ template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imp struct ImportMembers { struct Nested { __declspec(dllimport) void normalDecl(); - __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} +#ifdef GNU +// expected-note@+2{{previous attribute is here}} +#endif + __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} }; #ifdef GNU +// expected-note@+5{{previous attribute is here}} // expected-warning@+5{{'dllimport' attribute ignored on inline function}} // expected-warning@+6{{'dllimport' attribute ignored on inline function}} #endif __declspec(dllimport) void normalDecl(); - __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} + __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} __declspec(dllimport) void normalInclass() {} __declspec(dllimport) void normalInlineDef(); __declspec(dllimport) inline void normalInlineDecl(); #ifdef GNU +// expected-note@+5{{previous attribute is here}} // expected-warning@+5{{'dllimport' attribute ignored on inline function}} // expected-warning@+6{{'dllimport' attribute ignored on inline function}} #endif __declspec(dllimport) virtual void virtualDecl(); - __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} + __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} __declspec(dllimport) virtual void virtualInclass() {} __declspec(dllimport) virtual void virtualInlineDef(); __declspec(dllimport) virtual inline void virtualInlineDecl(); #ifdef GNU +// expected-note@+5{{previous attribute is here}} // expected-warning@+5{{'dllimport' attribute ignored on inline function}} // expected-warning@+6{{'dllimport' attribute ignored on inline function}} #endif __declspec(dllimport) static void staticDecl(); - __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} + __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} __declspec(dllimport) static void staticInclass() {} __declspec(dllimport) static void staticInlineDef(); __declspec(dllimport) static inline void staticInlineDecl(); @@ -495,20 +572,40 @@ public: __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}} }; - void ImportMembers::Nested::normalDef() {} // expected-warning{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} - void ImportMembers::normalDef() {} // expected-warning{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef MS +// expected-warning@+4{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else + // expected-warning@+2{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +void ImportMembers::Nested::normalDef() {} +#ifdef MS +// expected-warning@+4{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else + // expected-warning@+2{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +void ImportMembers::normalDef() {} #ifdef GNU // expected-warning@+2{{'ImportMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} #endif inline void ImportMembers::normalInlineDef() {} void ImportMembers::normalInlineDecl() {} - void ImportMembers::virtualDef() {} // expected-warning{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef MS + // expected-warning@+4{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else + // expected-warning@+2{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif + void ImportMembers::virtualDef() {} #ifdef GNU // expected-warning@+2{{'ImportMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}} #endif inline void ImportMembers::virtualInlineDef() {} void ImportMembers::virtualInlineDecl() {} - void ImportMembers::staticDef() {} // expected-warning{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef MS + // expected-warning@+4{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else + // expected-warning@+2{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif + void ImportMembers::staticDef() {} #ifdef GNU // expected-warning@+2{{'ImportMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} #endif @@ -620,7 +717,10 @@ struct ImportDefaulted { // Import defaulted member function definitions. struct ImportDefaultedDefs { __declspec(dllimport) ImportDefaultedDefs(); - __declspec(dllimport) ~ImportDefaultedDefs(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} +#ifdef GNU +// expected-note@+2{{previous attribute is here}} +#endif + __declspec(dllimport) ~ImportDefaultedDefs(); // expected-note{{previous declaration is here}} #ifdef GNU // expected-warning@+3{{'dllimport' attribute ignored on inline function}} @@ -630,14 +730,22 @@ struct ImportDefaultedDefs { __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&); __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&); - __declspec(dllimport) ImportDefaultedDefs& operator=(ImportDefaultedDefs&&); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} +#ifdef GNU +// expected-note@+2{{previous attribute is here}} +#endif + __declspec(dllimport) ImportDefaultedDefs &operator=(ImportDefaultedDefs &&); // expected-note{{previous declaration is here}} }; // Not allowed on definitions. __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default; // expected-error{{dllimport cannot be applied to non-inline function definition}} +#ifdef MS +// expected-warning@+5{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else +// expected-warning@+3{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif // dllimport cannot be dropped. -ImportDefaultedDefs::~ImportDefaultedDefs() = default; // expected-warning{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +ImportDefaultedDefs::~ImportDefaultedDefs() = default; // Import inline declaration and definition. #ifdef GNU @@ -648,8 +756,12 @@ __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefau inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default; __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // expected-error{{dllimport cannot be applied to non-inline function definition}} -ImportDefaultedDefs& ImportDefaultedDefs::operator=(ImportDefaultedDefs&&) = default; // expected-warning{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} - +#ifdef MS +// expected-warning@+4{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else +// expected-warning@+2{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +ImportDefaultedDefs &ImportDefaultedDefs::operator=(ImportDefaultedDefs &&) = default; // Redeclarations cannot add dllimport. struct MemberRedecl { @@ -970,13 +1082,22 @@ template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_De template<typename T> struct ImportClassTmplMembers { __declspec(dllimport) void normalDecl(); - __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} +#ifdef GNU +// expected-note@+2{{previous attribute is here}} +#endif + __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} __declspec(dllimport) void normalInlineDef(); __declspec(dllimport) virtual void virtualDecl(); - __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} +#ifdef GNU +// expected-note@+2{{previous attribute is here}} +#endif + __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} __declspec(dllimport) virtual void virtualInlineDef(); __declspec(dllimport) static void staticDecl(); - __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} +#ifdef GNU +// expected-note@+2{{previous attribute is here}} +#endif + __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} __declspec(dllimport) static void staticInlineDef(); #ifdef GNU @@ -1013,19 +1134,37 @@ public: // NB: MSVC is inconsistent here and disallows *InlineDef on class templates, // but allows it on classes. We allow both. -template<typename T> void ImportClassTmplMembers<T>::normalDef() {} // expected-warning{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef MS +// expected-warning@+5{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else +// expected-warning@+3{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +template <typename T> +void ImportClassTmplMembers<T>::normalDef() {} #ifdef GNU // expected-warning@+2{{'ImportClassTmplMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} #endif template<typename T> inline void ImportClassTmplMembers<T>::normalInlineDef() {} template<typename T> void ImportClassTmplMembers<T>::normalInlineDecl() {} -template<typename T> void ImportClassTmplMembers<T>::virtualDef() {} // expected-warning{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef MS +// expected-warning@+5{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else +// expected-warning@+3{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +template <typename T> +void ImportClassTmplMembers<T>::virtualDef() {} #ifdef GNU // expected-warning@+2{{'ImportClassTmplMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}} #endif template<typename T> inline void ImportClassTmplMembers<T>::virtualInlineDef() {} template<typename T> void ImportClassTmplMembers<T>::virtualInlineDecl() {} -template<typename T> void ImportClassTmplMembers<T>::staticDef() {} // expected-warning{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#ifdef MS +// expected-warning@+5{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} +#else +// expected-warning@+3{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} +#endif +template <typename T> +void ImportClassTmplMembers<T>::staticDef() {} #ifdef GNU // expected-warning@+2{{'ImportClassTmplMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} #endif diff --git a/test/SemaCXX/enable_if.cpp b/test/SemaCXX/enable_if.cpp index cd8241808c94..7ec07aa8b0ca 100644 --- a/test/SemaCXX/enable_if.cpp +++ b/test/SemaCXX/enable_if.cpp @@ -116,9 +116,9 @@ template <typename T> class C { void g() { f(); } }; -int fn3(bool b) __attribute__((enable_if(b, ""))); +int fn3(bool b) __attribute__((enable_if(b, ""))); // FIXME: This test should net 0 error messages. template <class T> void test3() { - fn3(sizeof(T) == 1); + fn3(sizeof(T) == 1); // expected-error{{no matching function for call to 'fn3'}} expected-note@-2{{candidate disabled}} } template <typename T> @@ -138,7 +138,7 @@ void test4() { void h(int); template <typename T> void outer() { void local_function() __attribute__((enable_if(::h(T()), ""))); - local_function(); + local_function(); // expected-error{{no matching function for call to 'local_function'}} expected-note@-1{{candidate disabled}} }; namespace PR20988 { @@ -158,9 +158,9 @@ namespace PR20988 { fn2(expr); // expected-error{{no matching function for call to 'fn2'}} } - int fn3(bool b) __attribute__((enable_if(b, ""))); + int fn3(bool b) __attribute__((enable_if(b, ""))); // FIXME: This test should net 0 error messages. template <class T> void test3() { - fn3(sizeof(T) == 1); + fn3(sizeof(T) == 1); // expected-error{{no matching function for call to 'fn3'}} expected-note@-2{{candidate disabled}} } } @@ -253,3 +253,167 @@ namespace FnPtrs { a = &noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' becuase it has one or more non-tautological enable_if conditions}} } } + +namespace casting { +using VoidFnTy = void (*)(); + +void foo(void *c) __attribute__((enable_if(0, ""))); +void foo(int *c) __attribute__((enable_if(c, ""))); +void foo(char *c) __attribute__((enable_if(1, ""))); + +void testIt() { + auto A = reinterpret_cast<VoidFnTy>(foo); + auto AAmp = reinterpret_cast<VoidFnTy>(&foo); + + using VoidFooTy = void (*)(void *); + auto B = reinterpret_cast<VoidFooTy>(foo); + auto BAmp = reinterpret_cast<VoidFooTy>(&foo); + + using IntFooTy = void (*)(int *); + auto C = reinterpret_cast<IntFooTy>(foo); + auto CAmp = reinterpret_cast<IntFooTy>(&foo); + + using CharFooTy = void (*)(void *); + auto D = reinterpret_cast<CharFooTy>(foo); + auto DAmp = reinterpret_cast<CharFooTy>(&foo); +} + +void testItCStyle() { + auto A = (VoidFnTy)foo; + auto AAmp = (VoidFnTy)&foo; + + using VoidFooTy = void (*)(void *); + auto B = (VoidFooTy)foo; + auto BAmp = (VoidFooTy)&foo; + + using IntFooTy = void (*)(int *); + auto C = (IntFooTy)foo; + auto CAmp = (IntFooTy)&foo; + + using CharFooTy = void (*)(void *); + auto D = (CharFooTy)foo; + auto DAmp = (CharFooTy)&foo; +} +} + +namespace casting_templates { +template <typename T> void foo(T) {} // expected-note 4 {{candidate function}} + +void foo(int *c) __attribute__((enable_if(c, ""))); //expected-note 4 {{candidate function}} +void foo(char *c) __attribute__((enable_if(c, ""))); //expected-note 4 {{candidate function}} + +void testIt() { + using IntFooTy = void (*)(int *); + auto A = reinterpret_cast<IntFooTy>(foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} + auto ARef = reinterpret_cast<IntFooTy>(&foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} + auto AExplicit = reinterpret_cast<IntFooTy>(foo<int*>); + + using CharFooTy = void (*)(char *); + auto B = reinterpret_cast<CharFooTy>(foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} + auto BRef = reinterpret_cast<CharFooTy>(&foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} + auto BExplicit = reinterpret_cast<CharFooTy>(foo<char*>); +} + +void testItCStyle() { + // constexpr is usable here because all of these should become static_casts. + using IntFooTy = void (*)(int *); + constexpr auto A = (IntFooTy)foo; + constexpr auto ARef = (IntFooTy)&foo; + constexpr auto AExplicit = (IntFooTy)foo<int*>; + + using CharFooTy = void (*)(char *); + constexpr auto B = (CharFooTy)foo; + constexpr auto BRef = (CharFooTy)&foo; + constexpr auto BExplicit = (CharFooTy)foo<char*>; + + static_assert(A == ARef && ARef == AExplicit, ""); + static_assert(B == BRef && BRef == BExplicit, ""); +} +} + +namespace multiple_matches { +using NoMatchTy = void (*)(); + +void foo(float *c); //expected-note 4 {{candidate function}} +void foo(int *c) __attribute__((enable_if(1, ""))); //expected-note 4 {{candidate function}} +void foo(char *c) __attribute__((enable_if(1, ""))); //expected-note 4 {{candidate function}} + +void testIt() { + auto A = reinterpret_cast<NoMatchTy>(foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} + auto ARef = reinterpret_cast<NoMatchTy>(&foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} + + auto C = (NoMatchTy)foo; // expected-error{{address of overloaded function 'foo' does not match required type 'void ()'}} + auto CRef = (NoMatchTy)&foo; // expected-error{{address of overloaded function 'foo' does not match required type 'void ()'}} +} +} + +namespace PR27122 { +// (slightly reduced) code that motivated the bug... +namespace ns { +void Function(int num) + __attribute__((enable_if(num != 0, ""))); +void Function(int num, int a0) + __attribute__((enable_if(num != 1, ""))); +} // namespace ns + +using ns::Function; // expected-note 3{{declared here}} +void Run() { + Functioon(0); // expected-error{{use of undeclared identifier}} expected-error{{too few arguments}} + Functioon(0, 1); // expected-error{{use of undeclared identifier}} + Functioon(0, 1, 2); // expected-error{{use of undeclared identifier}} +} + +// Extra tests +void regularEnableIf(int a) __attribute__((enable_if(a, ""))); // expected-note 3{{declared here}} expected-note 3{{candidate function not viable}} +void runRegularEnableIf() { + regularEnableIf(0, 2); // expected-error{{no matching function}} + regularEnableIf(1, 2); // expected-error{{no matching function}} + regularEnableIf(); // expected-error{{no matching function}} + + // Test without getting overload resolution involved + ::PR27122::regularEnableIf(0, 2); // expected-error{{too many arguments}} + ::PR27122::regularEnableIf(1, 2); // expected-error{{too many arguments}} + ::PR27122::regularEnableIf(); // expected-error{{too few arguments}} +} + +struct Foo { + void bar(int i) __attribute__((enable_if(i, ""))); // expected-note 2{{declared here}} +}; + +void runFoo() { + Foo f; + f.bar(); // expected-error{{too few arguments}} + f.bar(1, 2); // expected-error{{too many arguments}} +} +} + +// Ideally, we should be able to handle value-dependent expressions sanely. +// Sadly, that isn't the case at the moment. +namespace dependent { +int error(int N) __attribute__((enable_if(N, ""))); // expected-note{{candidate disabled}} +int error(int N) __attribute__((enable_if(!N, ""))); // expected-note{{candidate disabled}} +template <int N> int callUnavailable() { + return error(N); // expected-error{{no matching function for call to 'error'}} +} + +constexpr int noError(int N) __attribute__((enable_if(N, ""))) { return -1; } +constexpr int noError(int N) __attribute__((enable_if(!N, ""))) { return -1; } +constexpr int noError(int N) { return 0; } + +template <int N> +constexpr int callNoError() { return noError(N); } +static_assert(callNoError<0>() == 0, ""); +static_assert(callNoError<1>() == 0, ""); + +template <int N> constexpr int templated() __attribute__((enable_if(N, ""))) { + return 1; +} + +constexpr int A = templated<0>(); // expected-error{{no matching function for call to 'templated'}} expected-note@-4{{candidate disabled}} +static_assert(templated<1>() == 1, ""); + +template <int N> constexpr int callTemplated() { return templated<N>(); } + +constexpr int B = callTemplated<0>(); // expected-error{{initialized by a constant expression}} expected-error@-2{{no matching function for call to 'templated'}} expected-note{{in instantiation of function template}} expected-note@-9{{candidate disabled}} +static_assert(callTemplated<1>() == 1, ""); +} diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp index 909802335e46..142edd3893aa 100644 --- a/test/SemaCXX/enum-scoped.cpp +++ b/test/SemaCXX/enum-scoped.cpp @@ -298,8 +298,8 @@ namespace PR18044 { int E::*p; // expected-error {{does not point into a class}} using E::f; // expected-error {{no member named 'f'}} - using E::a; // ok! - E b = a; + using E::a; // expected-error {{using declaration cannot refer to a scoped enumerator}} + E b = a; // expected-error {{undeclared}} } namespace test11 { diff --git a/test/SemaCXX/eval-sizeof-dependent-type.cpp b/test/SemaCXX/eval-sizeof-dependent-type.cpp new file mode 100644 index 000000000000..1a5564a477d8 --- /dev/null +++ b/test/SemaCXX/eval-sizeof-dependent-type.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -std=c++11 -x c++ %s + +typedef __SIZE_TYPE__ size_t; +template <typename _Tp, size_t _Nm> struct array { _Tp _M_elems[_Nm]; }; +template <typename T> struct s { + array<int, 1> v{static_cast<int>(sizeof (T) / sizeof(T))}; +}; + diff --git a/test/SemaCXX/exceptions.cpp b/test/SemaCXX/exceptions.cpp index 9802a1a1d620..9e76783ca8a9 100644 --- a/test/SemaCXX/exceptions.cpp +++ b/test/SemaCXX/exceptions.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s struct A; // expected-note 4 {{forward declaration of 'A'}} @@ -135,16 +137,29 @@ namespace Decay { void f() throw (int*, int()); template<typename T> struct C { - void f() throw (T); // expected-error {{pointer to incomplete type 'Decay::E' is not allowed in exception specification}} + void f() throw (T); +#if __cplusplus <= 199711L + // expected-error@-2 {{pointer to incomplete type 'Decay::E' is not allowed in exception specification}} +#endif }; struct D { C<D[10]> c; }; - struct E; // expected-note {{forward declaration}} - C<E[10]> e; // expected-note {{in instantiation of}} + struct E; +#if __cplusplus <= 199711L + // expected-note@-2 {{forward declaration of 'Decay::E'}} +#endif + + C<E[10]> e; +#if __cplusplus <= 199711L + // expected-note@-2 {{in instantiation of template class 'Decay::C<Decay::E [10]>' requested here}} +#endif } -void rval_ref() throw (int &&); // expected-error {{rvalue reference type 'int &&' is not allowed in exception specification}} expected-warning {{C++11}} +void rval_ref() throw (int &&); // expected-error {{rvalue reference type 'int &&' is not allowed in exception specification}} +#if __cplusplus <= 199711L +// expected-warning@-2 {{rvalue references are a C++11 extension}} +#endif namespace HandlerInversion { struct B {}; @@ -253,3 +268,17 @@ void g() { } } } + +namespace PR28047 { +void test1(int i) { + try { + } catch (int(*)[i]) { // expected-error{{cannot catch variably modified type}} + } +} +void test2() { + int i; + try { + } catch (int(*)[i]) { // expected-error{{cannot catch variably modified type}} + } +} +} diff --git a/test/SemaCXX/extern-c.cpp b/test/SemaCXX/extern-c.cpp index 295d1f305ee2..fa6c2b1990c0 100644 --- a/test/SemaCXX/extern-c.cpp +++ b/test/SemaCXX/extern-c.cpp @@ -204,3 +204,41 @@ extern "C" { struct pr5065_n6 : public virtual pr5065_3 {}; } struct pr5065_n7 {}; + +namespace tag_hiding { + namespace namespace_with_injected_name { + class Boo { + friend struct ExternCStruct1; + }; + void ExternCStruct4(); // expected-note 2{{candidate}} + } + + class Baz { + friend struct ExternCStruct2; + friend void ExternCStruct3(); + }; + + using namespace namespace_with_injected_name; + + extern "C" { + struct ExternCStruct1; + struct ExternCStruct2; + struct ExternCStruct3; + struct ExternCStruct4; // expected-note {{candidate}} + } + ExternCStruct1 *p1; + ExternCStruct2 *p2; + ExternCStruct3 *p3; + ExternCStruct4 *p4; // expected-error {{ambiguous}} + + extern "C" { + struct ExternCStruct1; + struct ExternCStruct2; + struct ExternCStruct3; + struct ExternCStruct4; // expected-note {{candidate}} + } + ExternCStruct1 *q1 = p1; + ExternCStruct2 *q2 = p2; + ExternCStruct3 *q3 = p3; + ExternCStruct4 *q4 = p4; // expected-error {{ambiguous}} +} diff --git a/test/SemaCXX/for-range-examples.cpp b/test/SemaCXX/for-range-examples.cpp index 9359ae63a60b..08a9982c6378 100644 --- a/test/SemaCXX/for-range-examples.cpp +++ b/test/SemaCXX/for-range-examples.cpp @@ -176,9 +176,9 @@ namespace test4 { // Make sure these don't crash. Better diagnostics would be nice. for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}} - for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}} + for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}} for (+x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}} - for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}} + for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}} } } @@ -226,7 +226,7 @@ namespace test7 { // we check the alignment attribute before we perform the auto // deduction. for (d alignas(1) : arr) {} // expected-error {{requires type for loop variable}} - for (e [[deprecated]] : arr) { e = 0; } // expected-warning{{use of the 'deprecated' attribute is a C++14 extension}} expected-warning {{deprecated}} expected-note {{here}} expected-error {{requires type for loop variable}} + for (e [[deprecated]] : arr) { e = 0; } // expected-warning {{deprecated}} expected-note {{here}} expected-error {{requires type for loop variable}} } } diff --git a/test/SemaCXX/format-strings-0x.cpp b/test/SemaCXX/format-strings-0x.cpp index ad57b773e0a0..7d37f8276f29 100644 --- a/test/SemaCXX/format-strings-0x.cpp +++ b/test/SemaCXX/format-strings-0x.cpp @@ -15,6 +15,7 @@ void f(char **sp, float *fp) { scanf("%afoobar", fp); printf(nullptr); printf(*sp); // expected-warning {{not a string literal}} + // expected-note@-1{{treat the string as an argument to avoid this}} // PR13099 printf( diff --git a/test/SemaCXX/format-strings.cpp b/test/SemaCXX/format-strings.cpp index fa7251d0dd76..b7ef1d709f21 100644 --- a/test/SemaCXX/format-strings.cpp +++ b/test/SemaCXX/format-strings.cpp @@ -54,6 +54,7 @@ void rdar8269537(const char *f) test_null_format(0); // no-warning test_null_format(__null); // no-warning test_null_format(f); // expected-warning {{not a string literal}} + // expected-note@-1{{treat the string as an argument to avoid this}} } int Foo::printf(const char *fmt, ...) { diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp index a8e20439419f..4f27f4df6c90 100644 --- a/test/SemaCXX/friend.cpp +++ b/test/SemaCXX/friend.cpp @@ -147,11 +147,13 @@ namespace test8 { } using ns2::f; // expected-note {{using declaration}} } - struct A { void f(); }; // expected-note {{target of using declaration}} + struct A { void f(); }; // expected-note 2{{target of using declaration}} struct B : public A { using A::f; }; // expected-note {{using declaration}} + template<typename T> struct C : A { using A::f; }; // expected-note {{using declaration}} struct X { template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}} friend void B::f(); // expected-error {{cannot befriend target of using declaration}} + friend void C<int>::f(); // expected-error {{cannot befriend target of using declaration}} }; } @@ -363,3 +365,17 @@ void g_pr6954() { f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}} } +namespace tag_redecl { + namespace N { + struct X *p; + namespace { + class K { + friend struct X; + }; + } + } + namespace N { + struct X; + X *q = p; + } +} diff --git a/test/SemaCXX/function-redecl.cpp b/test/SemaCXX/function-redecl.cpp index 2bc0d90cd627..f91e670c0c31 100644 --- a/test/SemaCXX/function-redecl.cpp +++ b/test/SemaCXX/function-redecl.cpp @@ -7,7 +7,7 @@ namespace N { void bar(int); // expected-note 2{{previous declaration is here}} } - void foo(int); // expected-note 2{{previous declaration is here}} + void foo(int); // expected-note 3{{previous declaration is here}} void f2() { int foo(int); // expected-error {{functions that differ only in their return type cannot be overloaded}} @@ -25,6 +25,13 @@ namespace N { } } } + + void f3() { + int foo(float); + { + float foo(int); // expected-error {{functions that differ only in their return type cannot be overloaded}} + } + } } class A { diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp index 9db95e80d03e..216ee240c838 100644 --- a/test/SemaCXX/functional-cast.cpp +++ b/test/SemaCXX/functional-cast.cpp @@ -126,14 +126,14 @@ void t_529_2() typedef A *Ap; (void)Ap((B*)0); typedef A &Ar; - (void)Ar(*((B*)0)); + (void)Ar(*((B*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}} typedef const B *cBp; (void)cBp((C1*)0); typedef B &Br; - (void)Br(*((C1*)0)); + (void)Br(*((C1*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}} (void)Ap((D*)0); typedef const A &cAr; - (void)cAr(*((D*)0)); + (void)cAr(*((D*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}} typedef int B::*Bmp; (void)Bmp((int A::*)0); typedef void (B::*Bmfp)(); diff --git a/test/SemaCXX/generalized-deprecated.cpp b/test/SemaCXX/generalized-deprecated.cpp index 8fa20d0a0f09..43efea1ea4e6 100644 --- a/test/SemaCXX/generalized-deprecated.cpp +++ b/test/SemaCXX/generalized-deprecated.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -fms-extensions -Wno-deprecated %s +// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -fms-extensions -Wno-deprecated -Wc++14-extensions %s // NOTE: use -Wno-deprecated to avoid cluttering the output with deprecated // warnings diff --git a/test/SemaCXX/illegal-member-initialization.cpp b/test/SemaCXX/illegal-member-initialization.cpp index 87069efaacc7..17faed7eff7e 100644 --- a/test/SemaCXX/illegal-member-initialization.cpp +++ b/test/SemaCXX/illegal-member-initialization.cpp @@ -7,6 +7,7 @@ struct A { }; struct B { + int field; }; struct X { diff --git a/test/SemaCXX/inline.cpp b/test/SemaCXX/inline.cpp index e569300faf77..b20bc18d0a3f 100644 --- a/test/SemaCXX/inline.cpp +++ b/test/SemaCXX/inline.cpp @@ -1,5 +1,18 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s -Wc++98-c++11-c++14-compat // Check that we don't allow illegal uses of inline // (checking C++-only constructs here) struct c {inline int a;}; // expected-error{{'inline' can only appear on functions}} + +void localVar() { + inline int a; // expected-error{{inline declaration of 'a' not allowed in block scope}} +} + +// Check that we warn appropriately. +#if __cplusplus <= 201402L +inline int a; // expected-warning{{inline variables are a C++1z extension}} +#else +inline int a; // expected-warning{{inline variables are incompatible with C++ standards before C++1z}} +#endif diff --git a/test/SemaCXX/integer-overflow.cpp b/test/SemaCXX/integer-overflow.cpp index 566bb05fa0cb..a119f0eabe3a 100644 --- a/test/SemaCXX/integer-overflow.cpp +++ b/test/SemaCXX/integer-overflow.cpp @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 %s -verify -fsyntax-only -std=gnu++98 +// RUN: %clang_cc1 %s -verify -fsyntax-only -std=gnu++98 -triple x86_64-pc-linux-gnu typedef unsigned long long uint64_t; -typedef unsigned long long uint32_t; +typedef unsigned int uint32_t; + +// Check integer sizes. +int array64[sizeof(uint64_t) == 8 ? 1 : -1]; +int array32[sizeof(uint32_t) == 4 ? 1 : -1]; +int arrayint[sizeof(int) < sizeof(uint64_t) ? 1 : -1]; uint64_t f0(uint64_t); uint64_t f1(uint64_t, uint32_t); diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp index 72adcdbce2fe..17808cef363a 100644 --- a/test/SemaCXX/lambda-expressions.cpp +++ b/test/SemaCXX/lambda-expressions.cpp @@ -476,3 +476,26 @@ int main() { A<int> a; } + +// rdar://22032373 +namespace rdar22032373 { +void foo() { + auto blk = [](bool b) { + if (b) + return undeclared_error; // expected-error {{use of undeclared identifier}} + return 0; + }; +} +} + +namespace nested_lambda { +template <int N> +class S {}; + +void foo() { + const int num = 18; // expected-note {{'num' declared here}} + auto outer = []() { + auto inner = [](S<num> &X) {}; // expected-error {{variable 'num' cannot be implicitly captured in a lambda with no capture-default specified}} + }; +} +} diff --git a/test/SemaCXX/literal-operators.cpp b/test/SemaCXX/literal-operators.cpp index ba571788b962..304aa7cab7f3 100644 --- a/test/SemaCXX/literal-operators.cpp +++ b/test/SemaCXX/literal-operators.cpp @@ -35,13 +35,14 @@ typedef const char c; void operator "" _good (c*); // Check extra cv-qualifiers -void operator "" _cv_good (volatile const char *, const size_t); // expected-error {{parameter declaration for literal operator 'operator""_cv_good' is not valid}} +void operator "" _cv_good (volatile const char *, const size_t); // expected-error {{invalid literal operator parameter type 'const volatile char *', did you mean 'const char *'?}} // Template declaration template <char...> void operator "" _good (); -// FIXME: Test some invalid decls that might crop up. -template <typename...> void operator "" _invalid(); // expected-error {{parameter declaration for literal operator 'operator""_invalid' is not valid}} +template <typename...> void operator "" _invalid(); // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}} +template <wchar_t...> void operator "" _invalid(); // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}} +template <unsigned long long...> void operator "" _invalid(); // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}} _Complex float operator""if(long double); // expected-warning {{reserved}} _Complex float test_if_1() { return 2.0f + 1.5if; }; diff --git a/test/SemaCXX/make_integer_seq.cpp b/test/SemaCXX/make_integer_seq.cpp index 4e15414cbe67..a9b8d2b23cb5 100644 --- a/test/SemaCXX/make_integer_seq.cpp +++ b/test/SemaCXX/make_integer_seq.cpp @@ -47,3 +47,7 @@ using illformed2 = ErrorSeq<int, -5>; template <typename T, T N> void f() {} __make_integer_seq<f, int, 0> x; // expected-error{{template template parameter must be a class template or type alias template}} + +__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-error{{different template parameters}} +// expected-note@make_integer_seq.cpp:* {{template parameter has a different kind}} +// expected-note@make_integer_seq.cpp:* {{previous template template parameter is here}} diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp index b3ee30b456ec..65c8873117ab 100644 --- a/test/SemaCXX/member-init.cpp +++ b/test/SemaCXX/member-init.cpp @@ -192,3 +192,13 @@ struct S { int x[3] = {[N] = 3}; }; } + +namespace PR28060 { +template <class T> +void foo(T v) { + struct s { + T *s = 0; + }; +} +template void foo(int); +} diff --git a/test/SemaCXX/ms-const-member-expr.cpp b/test/SemaCXX/ms-const-member-expr.cpp new file mode 100644 index 000000000000..72cfe76fbe43 --- /dev/null +++ b/test/SemaCXX/ms-const-member-expr.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 %s -std=c++11 -fms-compatibility -fsyntax-only -verify + +struct S { + enum { E = 1 }; + static const int sdm = 1; +}; + +void f(S *s) { + char array[s->E] = { 0 }; +} + +extern S *s; +constexpr int e1 = s->E; + +S *side_effect(); // expected-note{{declared here}} +constexpr int e2 = // expected-error{{must be initialized by a constant expression}} + side_effect()->E; // expected-note{{cannot be used in a constant expression}} + +constexpr int e4 = s->sdm; diff --git a/test/SemaCXX/ms-empty_bases.cpp b/test/SemaCXX/ms-empty_bases.cpp new file mode 100644 index 000000000000..69d9e2799b8f --- /dev/null +++ b/test/SemaCXX/ms-empty_bases.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple i386-pc-win32 %s -fsyntax-only -verify -fms-extensions -Wno-microsoft -std=c++11 + +struct __declspec(empty_bases) S {}; +enum __declspec(empty_bases) E {}; // expected-warning{{'empty_bases' attribute only applies to classes}} +int __declspec(empty_bases) I; // expected-warning{{'empty_bases' attribute only applies to classes}} +typedef struct T __declspec(empty_bases) U; // expected-warning{{'empty_bases' attribute only applies to classes}} +auto z = []() __declspec(empty_bases) { return nullptr; }; // expected-warning{{'empty_bases' attribute only applies to classes}} + +struct __declspec(empty_bases(1)) X {}; // expected-error{{'empty_bases' attribute takes no arguments}} diff --git a/test/SemaCXX/ms-exception-spec.cpp b/test/SemaCXX/ms-exception-spec.cpp index 1be8ec293690..07633791b9f3 100644 --- a/test/SemaCXX/ms-exception-spec.cpp +++ b/test/SemaCXX/ms-exception-spec.cpp @@ -1,4 +1,9 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions -// expected-no-diagnostics +// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions -fexceptions -fcxx-exceptions void f() throw(...) { } + +namespace PR28080 { +struct S; // expected-note {{forward declaration}} +void fn() throw(S); // expected-warning {{incomplete type}} expected-note{{previous declaration}} +void fn() throw(); // expected-warning {{does not match previous declaration}} +} diff --git a/test/SemaCXX/ms-layout_version.cpp b/test/SemaCXX/ms-layout_version.cpp new file mode 100644 index 000000000000..7f83b2d4473e --- /dev/null +++ b/test/SemaCXX/ms-layout_version.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple i386-pc-win32 %s -fsyntax-only -verify -fms-extensions -Wno-microsoft -std=c++11 + +struct __declspec(layout_version(19)) S {}; +enum __declspec(layout_version(19)) E {}; // expected-warning{{'layout_version' attribute only applies to classes}} +int __declspec(layout_version(19)) I; // expected-warning{{'layout_version' attribute only applies to classes}} +typedef struct T __declspec(layout_version(19)) U; // expected-warning{{'layout_version' attribute only applies to classes}} +auto z = []() __declspec(layout_version(19)) { return nullptr; }; // expected-warning{{'layout_version' attribute only applies to classes}} + +struct __declspec(layout_version(18)) X {}; // expected-error{{'layout_version' attribute parameter 18 is out of bounds}} +struct __declspec(layout_version(20)) Y {}; // expected-error{{'layout_version' attribute parameter 20 is out of bounds}} +struct __declspec(layout_version) Z {}; // expected-error{{attribute takes one argument}} diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp index 7bc724b21010..e96603d69e10 100644 --- a/test/SemaCXX/new-delete.cpp +++ b/test/SemaCXX/new-delete.cpp @@ -444,11 +444,11 @@ namespace r150682 { template<typename X> void tfn() { - new (*(PlacementArg*)0) T[1]; + new (*(PlacementArg*)0) T[1]; // expected-warning 2 {{binding dereferenced null pointer to reference has undefined behavior}} } void fn() { - tfn<int>(); + tfn<int>(); // expected-note {{in instantiation of function template specialization 'r150682::tfn<int>' requested here}} } } diff --git a/test/SemaCXX/no-wchar.cpp b/test/SemaCXX/no-wchar.cpp index 291b657f51ab..b6dcddf1f428 100644 --- a/test/SemaCXX/no-wchar.cpp +++ b/test/SemaCXX/no-wchar.cpp @@ -7,3 +7,24 @@ void foo(const wchar_t* x); void bar() { foo(L"wide string literal"); } + +void foo1(wchar_t * t = L""); +// expected-warning@-1 {{conversion from string literal to 'wchar_t *' (aka 'unsigned short *') is deprecated}} + +short *a = L""; +// expected-error@-1 {{cannot initialize a variable of type 'short *' with an lvalue of type 'const unsigned short [1]'}} +char *b = L""; +// expected-error@-1 {{cannot initialize a variable of type 'char *' with an lvalue of type 'const unsigned short [1]'}} + +// NOTE: MSVC allows deprecated conversion in conditional expression if at least +// one of the operand is a string literal but Clang doesn't allow it. +wchar_t *c = true ? L"a" : L""; +// expected-error@-1 {{cannot initialize a variable of type 'wchar_t *' (aka 'unsigned short *') with}} + +const wchar_t *d1 = 0; +const wchar_t *d2 = 0; +wchar_t *d = true ? d1 : d2; +// expected-error@-1 {{cannot initialize a variable of type 'wchar_t *' (aka 'unsigned short *') with}} + +wchar_t* e = (const wchar_t*)L""; +// expected-error@-1 {{cannot initialize a variable of type 'wchar_t *' (aka 'unsigned short *') with an rvalue of type 'const wchar_t *' (aka 'const unsigned short *')}} diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp index 3d286a94a045..7eaf98b601c1 100644 --- a/test/SemaCXX/overload-call.cpp +++ b/test/SemaCXX/overload-call.cpp @@ -375,16 +375,24 @@ namespace test2 { } // PR 6117 -namespace test3 { - struct Base {}; +namespace IncompleteConversion { + struct Complete {}; struct Incomplete; - void foo(Base *); // expected-note 2 {{cannot convert argument of incomplete type}} - void foo(Base &); // expected-note 2 {{cannot convert argument of incomplete type}} - - void test(Incomplete *P) { - foo(P); // expected-error {{no matching function for call to 'foo'}} - foo(*P); // expected-error {{no matching function for call to 'foo'}} + void completeFunction(Complete *); // expected-note 2 {{cannot convert argument of incomplete type}} + void completeFunction(Complete &); // expected-note 2 {{cannot convert argument of incomplete type}} + + void testTypeConversion(Incomplete *P) { + completeFunction(P); // expected-error {{no matching function for call to 'completeFunction'}} + completeFunction(*P); // expected-error {{no matching function for call to 'completeFunction'}} + } + + void incompletePointerFunction(Incomplete *); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'IncompleteConversion::Incomplete' to 'IncompleteConversion::Incomplete *' for 1st argument; take the address of the argument with &}} + void incompleteReferenceFunction(Incomplete &); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'IncompleteConversion::Incomplete *' to 'IncompleteConversion::Incomplete &' for 1st argument; dereference the argument with *}} + + void testPointerReferenceConversion(Incomplete &reference, Incomplete *pointer) { + incompletePointerFunction(reference); // expected-error {{no matching function for call to 'incompletePointerFunction'}} + incompleteReferenceFunction(pointer); // expected-error {{no matching function for call to 'incompleteReferenceFunction'}} } } diff --git a/test/SemaCXX/overloaded-builtin-operators.cpp b/test/SemaCXX/overloaded-builtin-operators.cpp index 4c2953b0b3fe..7a99a898e209 100644 --- a/test/SemaCXX/overloaded-builtin-operators.cpp +++ b/test/SemaCXX/overloaded-builtin-operators.cpp @@ -183,7 +183,7 @@ void test_dr425(A a) { // FIXME: lots of candidates here! (void)(1.0f * a); // expected-error{{ambiguous}} \ // expected-note 4{{candidate}} \ - // expected-note {{remaining 117 candidates omitted; pass -fshow-overloads=all to show them}} + // expected-note {{remaining 140 candidates omitted; pass -fshow-overloads=all to show them}} } // pr5432 diff --git a/test/SemaCXX/pr25181-crash-on-invalid.cpp b/test/SemaCXX/pr25181-crash-on-invalid.cpp new file mode 100644 index 000000000000..41178c95e8ad --- /dev/null +++ b/test/SemaCXX/pr25181-crash-on-invalid.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// Don't crash (PR25181). + +template <typename T> class Foo { // expected-note {{template parameter is declared here}} + template <typename T> // expected-error {{declaration of 'T' shadows template parameter}} + void Foo<T>::method(T *) const throw() {} // expected-error {{nested name specifier 'Foo<T>::' for declaration does not refer into a class, class template or class template partial specialization}} +}; diff --git a/test/SemaCXX/pr27047-default-init-expr-name-conflict.cpp b/test/SemaCXX/pr27047-default-init-expr-name-conflict.cpp new file mode 100644 index 000000000000..772db9935c07 --- /dev/null +++ b/test/SemaCXX/pr27047-default-init-expr-name-conflict.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s + +template <typename T> +struct A { + // Used to crash when field was named after class. + int A = 0; +}; +A<int> a; diff --git a/test/SemaCXX/pragma-optimize.cpp b/test/SemaCXX/pragma-optimize.cpp index 48a15460fc96..cda46c552a4e 100644 --- a/test/SemaCXX/pragma-optimize.cpp +++ b/test/SemaCXX/pragma-optimize.cpp @@ -151,14 +151,14 @@ int yet_another_normal(int x) { // CHECK-DAG: attributes [[ATTRYETANOTHEROPTNONE]] = { {{.*}}noinline{{.*}}optnone{{.*}} } // Check that the other functions do NOT have optnone. -// CHECK-DAG-NOT: attributes [[ATTRFOO]] = { {{.*}}optnone{{.*}} } -// CHECK-DAG-NOT: attributes [[ATTRBAZ]] = { {{.*}}optnone{{.*}} } -// CHECK-DAG-NOT: attributes [[ATTRBAX]] = { {{.*}}optnone{{.*}} } -// CHECK-DAG-NOT: attributes [[ATTRWOMBAT]] = { {{.*}}optnone{{.*}} } -// CHECK-DAG-NOT: attributes [[ATTRCONTAINER]] = { {{.*}}optnone{{.*}} } -// CHECK-DAG-NOT: attributes [[ATTRTWICE]] = { {{.*}}optnone{{.*}} } -// CHECK-DAG-NOT: attributes [[ATTRCONTAINER2]] = { {{.*}}optnone{{.*}} } -// CHECK-DAG-NOT: attributes [[ATTRCONTAINER3]] = { {{.*}}optnone{{.*}} } -// CHECK-DAG-NOT: attributes [[ATTRTHRICEINT]] = { {{.*}}optnone{{.*}} } -// CHECK-DAG-NOT: attributes [[ATTRANOTHERNORMAL]] = { {{.*}}optnone{{.*}} } -// CHECK-DAG-NOT: attributes [[ATTRYETANOTHERNORMAL]] = { {{.*}}optnone{{.*}} } +// CHECK-NOT: attributes [[ATTRFOO]] = { {{.*}}optnone{{.*}} } +// CHECK-NOT: attributes [[ATTRBAZ]] = { {{.*}}optnone{{.*}} } +// CHECK-NOT: attributes [[ATTRBAX]] = { {{.*}}optnone{{.*}} } +// CHECK-NOT: attributes [[ATTRWOMBAT]] = { {{.*}}optnone{{.*}} } +// CHECK-NOT: attributes [[ATTRCONTAINER]] = { {{.*}}optnone{{.*}} } +// CHECK-NOT: attributes [[ATTRTWICE]] = { {{.*}}optnone{{.*}} } +// CHECK-NOT: attributes [[ATTRCONTAINER2]] = { {{.*}}optnone{{.*}} } +// CHECK-NOT: attributes [[ATTRCONTAINER3]] = { {{.*}}optnone{{.*}} } +// CHECK-NOT: attributes [[ATTRTHRICEINT]] = { {{.*}}optnone{{.*}} } +// CHECK-NOT: attributes [[ATTRANOTHERNORMAL]] = { {{.*}}optnone{{.*}} } +// CHECK-NOT: attributes [[ATTRYETANOTHERNORMAL]] = { {{.*}}optnone{{.*}} } diff --git a/test/SemaCXX/pragma-vtordisp.cpp b/test/SemaCXX/pragma-vtordisp.cpp index 649c0ee9e686..1421c33db5d3 100644 --- a/test/SemaCXX/pragma-vtordisp.cpp +++ b/test/SemaCXX/pragma-vtordisp.cpp @@ -22,7 +22,8 @@ struct B : virtual A { int b; }; // Test a reset. #pragma vtordisp() -#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}} +#pragma vtordisp(pop) // stack should NOT be affected by reset. + // Now stack contains '1'. #pragma vtordisp( // expected-warning {{unknown action for '#pragma vtordisp' - ignored}} #pragma vtordisp(asdf) // expected-warning {{unknown action for '#pragma vtordisp' - ignored}} @@ -42,6 +43,7 @@ struct E { virtual void f(); }; +#pragma vtordisp(pop) // After this stack should be empty. #pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}} void g() { diff --git a/test/SemaCXX/qual-id-test.cpp b/test/SemaCXX/qual-id-test.cpp index 9994d75cac19..61e60ae82dfa 100644 --- a/test/SemaCXX/qual-id-test.cpp +++ b/test/SemaCXX/qual-id-test.cpp @@ -1,9 +1,15 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + namespace A { namespace B { - struct base // expected-note{{object type}} + struct base +#if __cplusplus <= 199711L + // expected-note@-2 {{lookup in the object type 'A::sub' refers here}} +#endif { void x() {} void y() {} @@ -85,8 +91,14 @@ namespace C void fun4a() { A::sub *a; - typedef A::member base; // expected-note{{current scope}} - a->base::x(); // expected-error{{ambiguous}} + typedef A::member base; +#if __cplusplus <= 199711L + // expected-note@-2 {{lookup from the current scope refers here}} +#endif + a->base::x(); +#if __cplusplus <= 199711L + // expected-error@-2 {{lookup of 'base' in member access expression is ambiguous}} +#endif } void fun4b() { diff --git a/test/SemaCXX/return-stack-addr-2.cpp b/test/SemaCXX/return-stack-addr-2.cpp new file mode 100644 index 000000000000..ad27567fcd64 --- /dev/null +++ b/test/SemaCXX/return-stack-addr-2.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -std=c++11 %s +// expected-no-diagnostics + +namespace PR26599 { +template <typename> +struct S; + +struct I {}; + +template <typename T> +void *&non_pointer() { + void *&r = S<T>()[I{}]; + return r; +} + +template <typename T> +void *&pointer() { + void *&r = S<T>()[nullptr]; + return r; +} +} + diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp index 8c1664516a71..db289240d1ce 100644 --- a/test/SemaCXX/return.cpp +++ b/test/SemaCXX/return.cpp @@ -118,5 +118,5 @@ void cxx_unresolved_expr() { // CXXUnresolvedConstructExpr, and the missing ')' gives it an invalid source // location for its rparen. Check that emitting a diag on the range of the // expr doesn't assert. - return int(undeclared, 4; // expected-error {{expected ')'}} expected-note{{to match this '('}} expected-error {{void function 'cxx_unresolved_expr' should not return a value}} expected-error {{use of undeclared identifier 'undeclared'}} + return int(undeclared, 4; // expected-error {{expected ')'}} expected-note{{to match this '('}} expected-error {{use of undeclared identifier 'undeclared'}} } diff --git a/test/SemaCXX/rval-references.cpp b/test/SemaCXX/rval-references.cpp index 9c79ad7b0b97..4c2050494b69 100644 --- a/test/SemaCXX/rval-references.cpp +++ b/test/SemaCXX/rval-references.cpp @@ -72,23 +72,17 @@ int&& should_not_warn(int&& i) { // But GCC 4.4 does // Test the return dance. This also tests IsReturnCopyElidable. struct MoveOnly { MoveOnly(); - MoveOnly(const MoveOnly&) = delete; // expected-note {{candidate constructor}} \ - // expected-note 3{{explicitly marked deleted here}} - MoveOnly(MoveOnly&&); // expected-note {{candidate constructor}} - MoveOnly(int&&); // expected-note {{candidate constructor}} + MoveOnly(const MoveOnly&) = delete; // expected-note 3{{explicitly marked deleted here}} }; MoveOnly gmo; MoveOnly returningNonEligible() { - int i; static MoveOnly mo; MoveOnly &r = mo; if (0) // Copy from global can't be elided return gmo; // expected-error {{call to deleted constructor}} else if (0) // Copy from local static can't be elided return mo; // expected-error {{call to deleted constructor}} - else if (0) // Copy from reference can't be elided + else // Copy from reference can't be elided return r; // expected-error {{call to deleted constructor}} - else // Construction from different type can't be elided - return i; // expected-error {{no viable conversion from returned value of type 'int' to function return type 'MoveOnly'}} } diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp index b3fe49a88c6b..ff47c0bb4dce 100644 --- a/test/SemaCXX/static-cast.cpp +++ b/test/SemaCXX/static-cast.cpp @@ -43,11 +43,11 @@ void t_529_2() (void)static_cast<void*>((int*)0); (void)static_cast<volatile const void*>((const int*)0); (void)static_cast<A*>((B*)0); - (void)static_cast<A&>(*((B*)0)); + (void)static_cast<A&>(*((B*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}} (void)static_cast<const B*>((C1*)0); - (void)static_cast<B&>(*((C1*)0)); + (void)static_cast<B&>(*((C1*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}} (void)static_cast<A*>((D*)0); - (void)static_cast<const A&>(*((D*)0)); + (void)static_cast<const A&>(*((D*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}} (void)static_cast<int B::*>((int A::*)0); (void)static_cast<void (B::*)()>((void (A::*)())0); diff --git a/test/SemaCXX/switch-implicit-fallthrough-macro.cpp b/test/SemaCXX/switch-implicit-fallthrough-macro.cpp index add212fcf5d8..11df2cbfb53f 100644 --- a/test/SemaCXX/switch-implicit-fallthrough-macro.cpp +++ b/test/SemaCXX/switch-implicit-fallthrough-macro.cpp @@ -1,4 +1,8 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough -DCOMMAND_LINE_FALLTHROUGH=[[clang::fallthrough]] %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough -DCLANG_PREFIX -DCOMMAND_LINE_FALLTHROUGH=[[clang::fallthrough]] -DUNCHOSEN=[[fallthrough]] %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough -DCOMMAND_LINE_FALLTHROUGH=[[fallthrough]] %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -Wimplicit-fallthrough -DCLANG_PREFIX -DCOMMAND_LINE_FALLTHROUGH=[[clang::fallthrough]] %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -Wimplicit-fallthrough -DCOMMAND_LINE_FALLTHROUGH=[[clang::fallthrough]] %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -Wimplicit-fallthrough -DCOMMAND_LINE_FALLTHROUGH=[[fallthrough]] -DUNCHOSEN=[[clang::fallthrough]] %s int fallthrough_compatibility_macro_from_command_line(int n) { switch (n) { @@ -10,15 +14,12 @@ int fallthrough_compatibility_macro_from_command_line(int n) { return n; } -#ifdef __clang__ -#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +#ifdef CLANG_PREFIX #define COMPATIBILITY_FALLTHROUGH [ [ /* test */ clang /* test */ \ :: fallthrough ] ] // testing whitespace and comments in macro definition -#endif -#endif - -#ifndef COMPATIBILITY_FALLTHROUGH -#define COMPATIBILITY_FALLTHROUGH do { } while (0) +#else +#define COMPATIBILITY_FALLTHROUGH [ [ /* test */ /* test */ \ + fallthrough ] ] // testing whitespace and comments in macro definition #endif int fallthrough_compatibility_macro_from_source(int n) { @@ -32,7 +33,11 @@ int fallthrough_compatibility_macro_from_source(int n) { } // Deeper macro substitution +#ifdef CLANG_PREFIX #define M1 [[clang::fallthrough]] +#else +#define M1 [[fallthrough]] +#endif #ifdef __clang__ #define M2 M1 #else @@ -59,12 +64,17 @@ int fallthrough_compatibility_macro_in_macro(int n) { #undef M2 #undef COMPATIBILITY_FALLTHROUGH #undef COMMAND_LINE_FALLTHROUGH +#undef UNCHOSEN int fallthrough_compatibility_macro_undefined(int n) { switch (n) { case 0: n = n * 20; +#if __cplusplus <= 201402L case 1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} +#else + case 1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} +#endif ; } #define TOO_LATE [[clang::fallthrough]] @@ -83,7 +93,11 @@ int fallthrough_compatibility_macro_history(int n) { case 0: n = n * 20; #undef MACRO_WITH_HISTORY +#if __cplusplus <= 201402L case 1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} +#else + case 1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} +#endif ; #define MACRO_WITH_HISTORY [[clang::fallthrough]] } diff --git a/test/SemaCXX/switch-implicit-fallthrough-off-by-default.cpp b/test/SemaCXX/switch-implicit-fallthrough-off-by-default.cpp new file mode 100644 index 000000000000..6ab6370069af --- /dev/null +++ b/test/SemaCXX/switch-implicit-fallthrough-off-by-default.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -DUNREACHABLE=1 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -DUNREACHABLE=0 -Wimplicit-fallthrough %s + +void fallthrough(int n) { + switch (n) { + case 1: + if (UNREACHABLE) + return; + [[fallthrough]]; // expected-no-diagnostics, only checked when UNREACHABLE=0 + case 2: + break; + } +} diff --git a/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp b/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp index 009c8180b1bb..6880bdd5f47d 100644 --- a/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp +++ b/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp @@ -41,9 +41,8 @@ int fallthrough2(int n) { void unscoped(int n) { switch (n % 2) { case 0: - // FIXME: This should be typo-corrected, probably. - [[fallthrough]]; // expected-warning{{unknown attribute 'fallthrough' ignored}} - case 2: // expected-warning{{unannotated fall-through}} expected-note{{clang::fallthrough}} expected-note{{break;}} + [[fallthrough]]; + case 2: [[clang::fallthrough]]; case 1: break; diff --git a/test/SemaCXX/switch-implicit-fallthrough.cpp b/test/SemaCXX/switch-implicit-fallthrough.cpp index 0bc43cdbd45b..9540b1ff2880 100644 --- a/test/SemaCXX/switch-implicit-fallthrough.cpp +++ b/test/SemaCXX/switch-implicit-fallthrough.cpp @@ -179,18 +179,15 @@ void fallthrough_cfgblock_with_null_successor(int x) { int fallthrough_position(int n) { switch (n) { - [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} n += 300; [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}} case 221: - [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} return 1; [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}} case 222: - [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} n += 400; case 223: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} - [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} + ; } long p = static_cast<long>(n) * n; @@ -282,6 +279,23 @@ namespace PR18983 { } } +int fallthrough_placement_error(int n) { + switch (n) { + [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}} + n += 300; + case 221: + [[clang::fallthrough]]; // expected-error{{fallthrough annotation does not directly precede switch label}} + return 1; + case 222: + [[clang::fallthrough]]; // expected-error{{fallthrough annotation does not directly precede switch label}} + n += 400; + [[clang::fallthrough]]; + case 223: + [[clang::fallthrough]]; // expected-error{{fallthrough annotation does not directly precede switch label}} + } + return n; +} + int fallthrough_targets(int n) { [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}} diff --git a/test/SemaCXX/type-convert-construct.cpp b/test/SemaCXX/type-convert-construct.cpp index 2dec50abebf2..7ae83638adb5 100644 --- a/test/SemaCXX/type-convert-construct.cpp +++ b/test/SemaCXX/type-convert-construct.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++11 %s void f() { float v1 = float(1); @@ -12,8 +14,21 @@ void f() { typedef int T; int *p; bool v6 = T(0) == p; +#if __cplusplus >= 201103L + // expected-error@-2 {{comparison between pointer and integer ('T' (aka 'int') and 'int *')}} +#endif char *str; - str = "a string"; // expected-warning{{conversion from string literal to 'char *' is deprecated}} + str = "a string"; +#if __cplusplus <= 199711L + // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}} +#else + // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}} +#endif wchar_t *wstr; - wstr = L"a wide string"; // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}} + wstr = L"a wide string"; +#if __cplusplus <= 199711L + // expected-warning@-2 {{conversion from string literal to 'wchar_t *' is deprecated}} +#else + // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'wchar_t *'}} +#endif } diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index 69760fd6bd06..c53b02774aca 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -1514,6 +1514,9 @@ void has_nothrow_move_assign() { { int arr[T(__is_nothrow_assignable(HasNoThrowMoveAssign, HasNoThrowMoveAssign))]; } { int arr[F(__is_nothrow_assignable(HasThrowMoveAssign, HasThrowMoveAssign))]; } + + { int arr[T(__is_assignable(HasNoThrowMoveAssign, HasNoThrowMoveAssign))]; } + { int arr[T(__is_assignable(HasThrowMoveAssign, HasThrowMoveAssign))]; } } void has_trivial_move_assign() { @@ -1974,6 +1977,46 @@ void trivial_checks() TrivialMoveButNotCopy)))]; } { int arr[T((__is_trivially_assignable(TrivialMoveButNotCopy&, TrivialMoveButNotCopy&&)))]; } + { int arr[T((__is_trivially_assignable(int&, int)))]; } + { int arr[T((__is_trivially_assignable(int&, int&)))]; } + { int arr[T((__is_trivially_assignable(int&, int&&)))]; } + { int arr[T((__is_trivially_assignable(int&, const int&)))]; } + { int arr[T((__is_trivially_assignable(POD&, POD)))]; } + { int arr[T((__is_trivially_assignable(POD&, POD&)))]; } + { int arr[T((__is_trivially_assignable(POD&, POD&&)))]; } + { int arr[T((__is_trivially_assignable(POD&, const POD&)))]; } + { int arr[T((__is_trivially_assignable(int*&, int*)))]; } + { int arr[T((__is_trivially_assignable(AllDefaulted, + const AllDefaulted &)))]; } + { int arr[T((__is_trivially_assignable(AllDefaulted, + AllDefaulted &&)))]; } + + { int arr[F((__is_assignable(int *&, float *)))]; } + { int arr[T((__is_assignable(HasCopyAssign &, HasCopyAssign)))]; } + { int arr[T((__is_assignable(HasCopyAssign &, HasCopyAssign &)))]; } + { int arr[T((__is_assignable(HasCopyAssign &, const HasCopyAssign &)))]; } + { int arr[T((__is_assignable(HasCopyAssign &, HasCopyAssign &&)))]; } + { int arr[T((__is_assignable(TrivialMoveButNotCopy &, + TrivialMoveButNotCopy &)))]; } + { int arr[T((__is_assignable(TrivialMoveButNotCopy &, + const TrivialMoveButNotCopy &)))]; } + { int arr[F((__is_assignable(AllDeleted, + const AllDeleted &)))]; } + { int arr[F((__is_assignable(AllDeleted, + AllDeleted &&)))]; } + { int arr[T((__is_assignable(ExtDefaulted, + const ExtDefaulted &)))]; } + { int arr[T((__is_assignable(ExtDefaulted, + ExtDefaulted &&)))]; } + + { int arr[T((__is_assignable(HasDefaultTrivialCopyAssign &, + HasDefaultTrivialCopyAssign &)))]; } + { int arr[T((__is_assignable(HasDefaultTrivialCopyAssign &, + const HasDefaultTrivialCopyAssign &)))]; } + { int arr[T((__is_assignable(TrivialMoveButNotCopy &, + TrivialMoveButNotCopy)))]; } + { int arr[T((__is_assignable(TrivialMoveButNotCopy &, + TrivialMoveButNotCopy &&)))]; } } void constructible_checks() { diff --git a/test/SemaCXX/type_pack_element.cpp b/test/SemaCXX/type_pack_element.cpp new file mode 100644 index 000000000000..d22d5fa2ba67 --- /dev/null +++ b/test/SemaCXX/type_pack_element.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +static_assert(__has_builtin(__type_pack_element), ""); + +using SizeT = decltype(sizeof(int)); + +template <SizeT i, typename ...T> +using TypePackElement = __type_pack_element<i, T...>; + +template <int i> +struct X; + +static_assert(__is_same(TypePackElement<0, X<0>>, X<0>), ""); + +static_assert(__is_same(TypePackElement<0, X<0>, X<1>>, X<0>), ""); +static_assert(__is_same(TypePackElement<1, X<0>, X<1>>, X<1>), ""); + +static_assert(__is_same(TypePackElement<0, X<0>, X<1>, X<2>>, X<0>), ""); +static_assert(__is_same(TypePackElement<1, X<0>, X<1>, X<2>>, X<1>), ""); +static_assert(__is_same(TypePackElement<2, X<0>, X<1>, X<2>>, X<2>), ""); + +static_assert(__is_same(TypePackElement<0, X<0>, X<1>, X<2>, X<3>>, X<0>), ""); +static_assert(__is_same(TypePackElement<1, X<0>, X<1>, X<2>, X<3>>, X<1>), ""); +static_assert(__is_same(TypePackElement<2, X<0>, X<1>, X<2>, X<3>>, X<2>), ""); +static_assert(__is_same(TypePackElement<3, X<0>, X<1>, X<2>, X<3>>, X<3>), ""); + +static_assert(__is_same(TypePackElement<0, X<0>, X<1>, X<2>, X<3>, X<4>>, X<0>), ""); +static_assert(__is_same(TypePackElement<1, X<0>, X<1>, X<2>, X<3>, X<4>>, X<1>), ""); +static_assert(__is_same(TypePackElement<2, X<0>, X<1>, X<2>, X<3>, X<4>>, X<2>), ""); +static_assert(__is_same(TypePackElement<3, X<0>, X<1>, X<2>, X<3>, X<4>>, X<3>), ""); +static_assert(__is_same(TypePackElement<4, X<0>, X<1>, X<2>, X<3>, X<4>>, X<4>), ""); + +static_assert(__is_same(TypePackElement<0, X<0>, X<1>, X<2>, X<3>, X<4>, X<5>>, X<0>), ""); +static_assert(__is_same(TypePackElement<1, X<0>, X<1>, X<2>, X<3>, X<4>, X<5>>, X<1>), ""); +static_assert(__is_same(TypePackElement<2, X<0>, X<1>, X<2>, X<3>, X<4>, X<5>>, X<2>), ""); +static_assert(__is_same(TypePackElement<3, X<0>, X<1>, X<2>, X<3>, X<4>, X<5>>, X<3>), ""); +static_assert(__is_same(TypePackElement<4, X<0>, X<1>, X<2>, X<3>, X<4>, X<5>>, X<4>), ""); +static_assert(__is_same(TypePackElement<5, X<0>, X<1>, X<2>, X<3>, X<4>, X<5>>, X<5>), ""); + +// Test __type_pack_element with more than 2 top-level template arguments. +static_assert(__is_same(__type_pack_element<5, X<0>, X<1>, X<2>, X<3>, X<4>, X<5>>, X<5>), ""); + +template <SizeT Index, typename ...T> +using ErrorTypePackElement1 = __type_pack_element<Index, T...>; // expected-error{{may not be accessed at an out of bounds index}} +using illformed1 = ErrorTypePackElement1<3, X<0>, X<1>>; // expected-note{{in instantiation}} diff --git a/test/SemaCXX/typo-correction-crash.cpp b/test/SemaCXX/typo-correction-crash.cpp new file mode 100644 index 000000000000..0b8383dbafef --- /dev/null +++ b/test/SemaCXX/typo-correction-crash.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s +auto check1() { + return 1; + return s; // expected-error {{use of undeclared identifier 's'}} +} + +int test = 11; // expected-note {{'test' declared here}} +auto check2() { + return "s"; + return tes; // expected-error {{use of undeclared identifier 'tes'; did you mean 'test'?}} +} + +namespace BarNamespace { +namespace NestedNamespace { // expected-note {{'BarNamespace::NestedNamespace' declared here}} +typedef int type; +} +} +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'}} diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp index 07c1634431ea..48597ded1528 100644 --- a/test/SemaCXX/typo-correction.cpp +++ b/test/SemaCXX/typo-correction.cpp @@ -663,3 +663,19 @@ class Bar : public A::B::Foofoo {}; using C::D::Foofoo; // expected-error {{no member named 'Foofoo' in namespace 'PR24781_using_crash::C::D'; did you mean 'A::B::Foofoo'?}} } + +int d = ? L : d; // expected-error {{expected expression}} expected-error {{undeclared identifier}} + +struct B0 { + int : 0 | // expected-error {{invalid operands to binary expression}} + (struct B0)e; // expected-error {{use of undeclared identifier}} +}; + +namespace { +struct a0is0 {}; +struct b0is0 {}; +int g() { + 0 [ // expected-error {{subscripted value is not an array}} + sizeof(c0is0)]; // expected-error {{use of undeclared identifier}} +}; +} diff --git a/test/SemaCXX/unaddressable-functions.cpp b/test/SemaCXX/unaddressable-functions.cpp new file mode 100644 index 000000000000..286cbee5ea9b --- /dev/null +++ b/test/SemaCXX/unaddressable-functions.cpp @@ -0,0 +1,147 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 + +namespace access_control { +class Private { + void check(int *) __attribute__((enable_if(false, ""))); + void check(double *) __attribute__((enable_if(true, ""))); + + static void checkStatic(int *) __attribute__((enable_if(false, ""))); + static void checkStatic(double *) __attribute__((enable_if(true, ""))); +}; + +auto Priv = reinterpret_cast<void (Private::*)(char *)>(&Private::check); // expected-error{{'check' is a private member of 'access_control::Private'}} expected-note@6{{implicitly declared private here}} + +auto PrivStatic = reinterpret_cast<void (*)(char *)>(&Private::checkStatic); // expected-error{{'checkStatic' is a private member of 'access_control::Private'}} expected-note@9{{implicitly declared private here}} + +class Protected { +protected: + void check(int *) __attribute__((enable_if(false, ""))); + void check(double *) __attribute__((enable_if(true, ""))); + + static void checkStatic(int *) __attribute__((enable_if(false, ""))); + static void checkStatic(double *) __attribute__((enable_if(true, ""))); +}; + +auto Prot = reinterpret_cast<void (Protected::*)(char *)>(&Protected::check); // expected-error{{'check' is a protected member of 'access_control::Protected'}} expected-note@19{{declared protected here}} + +auto ProtStatic = reinterpret_cast<void (*)(char *)>(&Protected::checkStatic); // expected-error{{'checkStatic' is a protected member of 'access_control::Protected'}} expected-note@22{{declared protected here}} +} + +namespace unavailable { +// Ensure that we check that the function can be called +void foo() __attribute__((unavailable("don't call this"))); +void foo(int) __attribute__((enable_if(false, ""))); + +void *Ptr = reinterpret_cast<void*>(foo); // expected-error{{'foo' is unavailable: don't call this}} expected-note@-3{{explicitly marked unavailable here}} +} + +namespace template_deduction { +void foo() __attribute__((enable_if(false, ""))); + +void bar() __attribute__((enable_if(true, ""))); +void bar() __attribute__((enable_if(false, ""))); + +void baz(int a) __attribute__((enable_if(true, ""))); +void baz(int a) __attribute__((enable_if(a, ""))); +void baz(int a) __attribute__((enable_if(false, ""))); + +void qux(int a) __attribute__((enable_if(1, ""))); +void qux(int a) __attribute__((enable_if(true, ""))); +void qux(int a) __attribute__((enable_if(a, ""))); +void qux(int a) __attribute__((enable_if(false, ""))); + +template <typename Fn, typename... Args> void call(Fn F, Args... As) { + F(As...); +} + +void test() { + call(foo); // expected-error{{cannot take address of function 'foo'}} + call(bar); + call(baz, 0); + call(qux, 0); // expected-error{{no matching function for call to 'call'}} expected-note@53{{candidate template ignored: couldn't infer template argument 'Fn'}} + + auto Ptr1 = foo; // expected-error{{cannot take address of function 'foo'}} + auto Ptr2 = bar; + auto Ptr3 = baz; + auto Ptr4 = qux; // expected-error{{variable 'Ptr4' with type 'auto' has incompatible initializer of type '<overloaded function type>'}} +} + +template <typename Fn, typename T, typename... Args> +void callMem(Fn F, T t, Args... As) { + (t.*F)(As...); +} + +class Foo { + void bar() __attribute__((enable_if(true, ""))); + void bar() __attribute__((enable_if(false, ""))); + + static void staticBar() __attribute__((enable_if(true, ""))); + static void staticBar() __attribute__((enable_if(false, ""))); +}; + +void testAccess() { + callMem(&Foo::bar, Foo()); // expected-error{{'bar' is a private member of 'template_deduction::Foo'}} expected-note@-8{{implicitly declared private here}} + call(&Foo::staticBar); // expected-error{{'staticBar' is a private member of 'template_deduction::Foo'}} expected-note@-6{{implicitly declared private here}} +} +} + +namespace template_template_deduction { +void foo() __attribute__((enable_if(false, ""))); +template <typename T> +T foo() __attribute__((enable_if(true, ""))); + +template <typename Fn, typename... Args> auto call(Fn F, Args... As) { + return F(As...); +} + +auto Ok = call(&foo<int>); +auto Fail = call(&foo); // expected-error{{no matching function for call to 'call'}} expected-note@-5{{candidate template ignored: couldn't infer template argument 'Fn'}} + +auto PtrOk = &foo<int>; +auto PtrFail = &foo; // expected-error{{variable 'PtrFail' with type 'auto' has incompatible initializer of type '<overloaded function type>'}} +} + +namespace pointer_equality { + using FnTy = void (*)(); + + void bothEnableIf() __attribute__((enable_if(false, ""))); + void bothEnableIf() __attribute__((enable_if(true, ""))); + + void oneEnableIf() __attribute__((enable_if(false, ""))); + void oneEnableIf(); + + void test() { + FnTy Fn; + (void)(Fn == bothEnableIf); + (void)(Fn == &bothEnableIf); + (void)(Fn == oneEnableIf); + (void)(Fn == &oneEnableIf); + } + + void unavailableEnableIf() __attribute__((enable_if(false, ""))); + void unavailableEnableIf() __attribute__((unavailable("noooo"))); // expected-note 2{{marked unavailable here}} + + void testUnavailable() { + FnTy Fn; + (void)(Fn == unavailableEnableIf); // expected-error{{is unavailable}} + (void)(Fn == &unavailableEnableIf); // expected-error{{is unavailable}} + } + + class Foo { + static void staticAccessEnableIf(); // expected-note 2{{declared private here}} + void accessEnableIf(); // expected-note{{declared private here}} + + public: + static void staticAccessEnableIf() __attribute__((enable_if(false, ""))); + void accessEnableIf() __attribute__((enable_if(false, ""))); + }; + + void testAccess() { + FnTy Fn; + (void)(Fn == Foo::staticAccessEnableIf); // expected-error{{is a private member}} + (void)(Fn == &Foo::staticAccessEnableIf); // expected-error{{is a private member}} + + void (Foo::*MemFn)(); + (void)(MemFn == &Foo::accessEnableIf); // expected-error{{is a private member}} + } +} diff --git a/test/SemaCXX/undefined-inline.cpp b/test/SemaCXX/undefined-inline.cpp index 18973ef8b79c..feb12f4552ca 100644 --- a/test/SemaCXX/undefined-inline.cpp +++ b/test/SemaCXX/undefined-inline.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -triple i686-pc-win32 -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple i686-pc-win32 -verify -std=c++11 %s // PR14993 namespace test1 { @@ -61,3 +61,8 @@ namespace test11 { inline void bar() __attribute__((dllimport)); void test() { foo(); bar(); } } + +namespace test12 { + template<typename> constexpr int _S_chk(int *); + decltype(_S_chk<int>(nullptr)) n; +} diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp index 29ca5de6d41c..59e6fdf9af06 100644 --- a/test/SemaCXX/undefined-internal.cpp +++ b/test/SemaCXX/undefined-internal.cpp @@ -82,6 +82,7 @@ namespace test5 { static int var; // expected-warning {{variable 'test5::B<test5::(anonymous namespace)::A>::var' has internal linkage but is not defined}} static void foo(); // expected-warning {{function 'test5::B<test5::(anonymous namespace)::A>::foo' has internal linkage but is not defined}} }; + extern template int B<A>::var; void test() { B<A>::var = 0; // expected-note {{used here}} diff --git a/test/SemaCXX/underlying_type.cpp b/test/SemaCXX/underlying_type.cpp index 61208c72af04..dd019ae6e277 100644 --- a/test/SemaCXX/underlying_type.cpp +++ b/test/SemaCXX/underlying_type.cpp @@ -55,3 +55,10 @@ namespace PR19966 { // expected-error@-2 {{constant expression}} }; } + +template<typename T> void f(__underlying_type(T)); +template<typename T> void f(__underlying_type(T)); +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'}} diff --git a/test/SemaCXX/unknown-anytype.cpp b/test/SemaCXX/unknown-anytype.cpp index a07ec83d10a0..95ad04093405 100644 --- a/test/SemaCXX/unknown-anytype.cpp +++ b/test/SemaCXX/unknown-anytype.cpp @@ -45,3 +45,14 @@ namespace test4 { int x = (int) test1; // expected-error {{function 'test1' with unknown type must be given a function type}} } } + +// rdar://problem/23959960 +namespace test5 { + template<typename T> struct X; // expected-note{{template is declared here}} + + extern __unknown_anytype test0(...); + + void test() { + (X<int>)test0(); // expected-error{{implicit instantiation of undefined template 'test5::X<int>'}} + } +} diff --git a/test/SemaCXX/unused.cpp b/test/SemaCXX/unused.cpp index fbaf8c8bf3c1..09a179e7bb85 100644 --- a/test/SemaCXX/unused.cpp +++ b/test/SemaCXX/unused.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s // PR4103 : Make sure we don't get a bogus unused expression warning namespace PR4103 { @@ -28,8 +30,14 @@ namespace PR4103 { namespace derefvolatile { void f(volatile char* x) { - *x; // expected-warning {{expression result unused; assign into a variable to force a volatile load}} - (void)*x; // expected-warning {{expression result unused; assign into a variable to force a volatile load}} + *x; +#if __cplusplus <= 199711L + // expected-warning@-2 {{expression result unused; assign into a variable to force a volatile load}} +#endif + (void)*x; +#if __cplusplus <= 199711L + // expected-warning@-2 {{expression result unused; assign into a variable to force a volatile load}} +#endif volatile char y = 10; (void)y; // don't warn here, because it's a common pattern. } diff --git a/test/SemaCXX/using-decl-1.cpp b/test/SemaCXX/using-decl-1.cpp index ec45b3109a0b..93f38f28e778 100644 --- a/test/SemaCXX/using-decl-1.cpp +++ b/test/SemaCXX/using-decl-1.cpp @@ -243,6 +243,41 @@ namespace PR19171 { struct F : E { using E::EE; // expected-error-re {{no member named 'EE' in 'PR19171::E'{{$}}}} }; + + struct TypoDuplicate { // expected-note 0-4{{here}} + TypoDuplicate(int); + void foobar(); // expected-note 2{{here}} + }; + struct TypoDuplicateDerived1 : TypoDuplicate { +#if __cplusplus >= 201103L + using TypoDuplicate::TypoFuplicate; // expected-error {{did you mean 'TypoDuplicate'}} expected-note {{previous}} + using TypoDuplicate::TypoDuplicate; // expected-error {{redeclaration}} +#endif + using TypoDuplicate::goobar; // expected-error {{did you mean 'foobar'}} expected-note {{previous}} + using TypoDuplicate::foobar; // expected-error {{redeclaration}} + }; + struct TypoDuplicateDerived2 : TypoDuplicate { +#if __cplusplus >= 201103L + using TypoFuplicate::TypoDuplicate; // expected-error {{did you mean 'TypoDuplicate'}} expected-note {{previous}} + using TypoDuplicate::TypoDuplicate; // expected-error {{redeclaration}} +#endif + }; + struct TypoDuplicateDerived3 : TypoDuplicate { +#if __cplusplus >= 201103L + // FIXME: Don't suggest a correction that would lead to a redeclaration + // error here... or at least diagnose the error. + using TypoDuplicate::TypoDuplicate; + using TypoDuplicate::TypoFuplicate; // expected-error {{did you mean 'TypoDuplicate'}} +#endif + using TypoDuplicate::foobar; + using TypoDuplicate::goobar; // expected-error {{did you mean 'foobar'}} + }; + struct TypoDuplicateDerived4 : TypoDuplicate { +#if __cplusplus >= 201103L + using TypoDuplicate::TypoDuplicate; // expected-note {{previous}} + using TypoFuplicate::TypoDuplicate; // expected-error {{did you mean 'TypoDuplicate'}} expected-error {{redeclaration}} +#endif + }; } namespace TypoCorrectTemplateMember { @@ -338,3 +373,26 @@ struct B : A { enum { X = sizeof(field) }; }; } + +namespace tag_vs_var { + namespace N { + struct X {}; + + struct Y {}; + int Y; + + int Z; + } + using N::X; + using N::Y; + using N::Z; + + namespace N { + int X; + + struct Z {}; + } + using N::X; + using N::Y; + using N::Z; +} diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp index 8314688bcbc7..d766bb3ac6bf 100644 --- a/test/SemaCXX/using-decl-templates.cpp +++ b/test/SemaCXX/using-decl-templates.cpp @@ -90,5 +90,5 @@ namespace aliastemplateinst { template<typename T> struct A { }; template<typename T> using APtr = A<T*>; // expected-note{{previous use is here}} - template struct APtr<int>; // expected-error{{elaborated type refers to a non-tag type}} + template struct APtr<int>; // expected-error{{elaborated type refers to a type alias template}} } diff --git a/test/SemaCXX/vararg-non-pod.cpp b/test/SemaCXX/vararg-non-pod.cpp index 39d4cccacd35..1b7f3b68dc97 100644 --- a/test/SemaCXX/vararg-non-pod.cpp +++ b/test/SemaCXX/vararg-non-pod.cpp @@ -1,7 +1,11 @@ // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-error=non-pod-varargs +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++98 %s -Wno-error=non-pod-varargs +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s -Wno-error=non-pod-varargs // Check that the warning is still there under -fms-compatibility. // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-error=non-pod-varargs -fms-compatibility +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++98 %s -Wno-error=non-pod-varargs -fms-compatibility +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s -Wno-error=non-pod-varargs -fms-compatibility extern char version[]; @@ -18,11 +22,19 @@ void t1() { C c(10); - g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} + g(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} +#endif + g(10, version); void (*ptr)(int, ...) = g; - ptr(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} + ptr(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} +#endif + ptr(10, version); } @@ -30,18 +42,34 @@ void t2() { C c(10); - c.g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} + c.g(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} +#endif + c.g(10, version); void (C::*ptr)(int, ...) = &C::g; - (c.*ptr)(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} + (c.*ptr)(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} +#endif + (c.*ptr)(10, version); - C::h(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} + C::h(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} +#endif + C::h(10, version); void (*static_ptr)(int, ...) = &C::h; - static_ptr(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} + static_ptr(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} +#endif + static_ptr(10, version); } @@ -51,7 +79,11 @@ void t3() { C c(10); - block(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} + block(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} +#endif + block(10, version); } @@ -66,7 +98,11 @@ void t4() D d; - d(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} + d(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} +#endif + d(10, version); } @@ -78,10 +114,16 @@ void t5() { C c(10); - E e(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} \ - // expected-error{{calling a private constructor of class 'E'}} - (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} \ - // expected-error{{calling a private constructor of class 'E'}} + E e(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} +#endif + // expected-error@-4 {{calling a private constructor of class 'E'}} + (void)E(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} +#endif + // expected-error@-4 {{calling a private constructor of class 'E'}} } @@ -103,7 +145,13 @@ Base &get_base(...); int eat_base(...); void test_typeid(Base &base) { - (void)typeid(get_base(base)); // expected-warning{{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}} expected-warning{{expression with side effects will be evaluated despite being used as an operand to 'typeid'}} + (void)typeid(get_base(base)); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}} +#else + // expected-warning@-4 {{cannot pass object of non-trivial type 'Base' through variadic function; call will abort at runtime}} +#endif + // expected-warning@-6 {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}} (void)typeid(eat_base(base)); // okay } @@ -136,7 +184,10 @@ void t8(int n, ...) { int t9(int n) { // Make sure the error works in potentially-evaluated sizeof - return (int)sizeof(*(Helper(Foo()), (int (*)[n])0)); // expected-warning{{cannot pass object of non-POD type}} + return (int)sizeof(*(Helper(Foo()), (int (*)[n])0)); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'Foo' through variadic function; call will abort at runtime}} +#endif } // PR14057 @@ -173,22 +224,43 @@ namespace t11 { void test() { C c(10); - (get_f_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} + (get_f_ptr())(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} +#endif (get_f_ptr())(10, version); - (c.*get_m_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} + (c.*get_m_ptr())(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} +#endif (c.*get_m_ptr())(10, version); - (get_b_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} + (get_b_ptr())(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} +#endif + (get_b_ptr())(10, version); - (arr_f_ptr[3])(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} + (arr_f_ptr[3])(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} +#endif + (arr_f_ptr[3])(10, version); - (c.*arr_m_ptr[3])(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} + (c.*arr_m_ptr[3])(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} +#endif + (c.*arr_m_ptr[3])(10, version); - (arr_b_ptr[3])(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} + (arr_b_ptr[3])(10, c); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} +#endif (arr_b_ptr[3])(10, version); } } diff --git a/test/SemaCXX/varargs.cpp b/test/SemaCXX/varargs.cpp new file mode 100644 index 000000000000..6a1883786a33 --- /dev/null +++ b/test/SemaCXX/varargs.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++03 -verify %s + +class string; +void f(const string& s, ...) { // expected-note {{parameter of type 'const string &' is declared here}} + __builtin_va_list ap; + __builtin_va_start(ap, s); // expected-warning {{passing an object of reference type to 'va_start' has undefined behavior}} +} + +void g(register int i, ...) { + __builtin_va_list ap; + __builtin_va_start(ap, i); // okay +} diff --git a/test/SemaCXX/vartemplate-lambda.cpp b/test/SemaCXX/vartemplate-lambda.cpp new file mode 100644 index 000000000000..9dab6da3d1e3 --- /dev/null +++ b/test/SemaCXX/vartemplate-lambda.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s +// expected-no-diagnostics + +template <class> auto fn0 = [] {}; +template <typename> void foo0() { fn0<char>(); } + +template<typename T> auto fn1 = [](auto a) { return a + T(1); }; + +template <typename X> +int foo2() { + X a = 0x61; + fn1<char>(a); + return 0; +} + +int main() { + foo2<int>(); +} diff --git a/test/SemaCXX/vla-consruct.cpp b/test/SemaCXX/vla-consruct.cpp new file mode 100644 index 000000000000..09b73704eb07 --- /dev/null +++ b/test/SemaCXX/vla-consruct.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -O0 -verify %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -pedantic-errors -DPE -O0 -verify %s + +# ifndef PE +// expected-no-diagnostics +# endif + +extern "C" int printf(const char*, ...); + +static int N; +struct S { + S() __attribute__ ((nothrow)) { printf("%d: S()\n", ++N); } + ~S() __attribute__ ((nothrow)) { printf("%d: ~S()\n", N--); } + int n[17]; +}; + +void print(int n, int a, int b, int c, int d) { + printf("n=%d\n,sizeof(S)=%d\nsizeof(array_t[0][0])=%d\nsizeof(array_t[0])=%d\nsizeof(array_t)=%d\n", + n, a, b, c, d); + if (n == 2) throw(n); +} + +void test(int n) { + S array_t[n][n+1]; +# ifdef PE + // expected-error@-2 {{variable length arrays are a C99 feature}} + // expected-error@-3 {{variable length arrays are a C99 feature}} +# endif + int sizeof_S = sizeof(S); + int sizeof_array_t_0_0 = sizeof(array_t[0][0]); + int sizeof_array_t_0 = sizeof(array_t[0]); + int sizeof_array_t = sizeof(array_t); + print(n, sizeof_S, sizeof_array_t_0_0, sizeof_array_t_0, sizeof_array_t); +} + +int main() +{ + try { + test(2); + } catch(int e) { + printf("expeption %d\n", e); + } + try { + test(3); + } catch(int e) { + printf("expeption %d", e); + } +} diff --git a/test/SemaCXX/warn-bad-memaccess.cpp b/test/SemaCXX/warn-bad-memaccess.cpp index 67cde10bf45d..55ce4a0da031 100644 --- a/test/SemaCXX/warn-bad-memaccess.cpp +++ b/test/SemaCXX/warn-bad-memaccess.cpp @@ -141,3 +141,16 @@ namespace N { N::memset(&x1, 0, sizeof x1); } } + +namespace recursive_class { +struct S { + S v; + // expected-error@-1{{field has incomplete type 'recursive_class::S'}} + // expected-note@-3{{definition of 'recursive_class::S' is not complete until the closing '}'}} +} a; + +int main() { + __builtin_memset(&a, 0, sizeof a); + return 0; +} +} diff --git a/test/SemaCXX/warn-comma-operator.cpp b/test/SemaCXX/warn-comma-operator.cpp new file mode 100644 index 000000000000..3192f688f1ba --- /dev/null +++ b/test/SemaCXX/warn-comma-operator.cpp @@ -0,0 +1,278 @@ +// RUN: %clang_cc1 -fsyntax-only -Wcomma -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wcomma -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +// Test builtin operators +void test1() { + int x = 0, y = 0; + for (; y < 10; x++, y++) {} + for (; y < 10; ++x, y++) {} + for (; y < 10; x++, ++y) {} + for (; y < 10; ++x, ++y) {} + for (; y < 10; x--, ++y) {} + for (; y < 10; --x, ++y) {} + for (; y < 10; x = 5, ++y) {} + for (; y < 10; x *= 5, ++y) {} + for (; y < 10; x /= 5, ++y) {} + for (; y < 10; x %= 5, ++y) {} + for (; y < 10; x += 5, ++y) {} + for (; y < 10; x -= 5, ++y) {} + for (; y < 10; x <<= 5, ++y) {} + for (; y < 10; x >>= 5, ++y) {} + for (; y < 10; x &= 5, ++y) {} + for (; y < 10; x |= 5, ++y) {} + for (; y < 10; x ^= 5, ++y) {} +} + +class S2 { +public: + void advance(); + + S2 operator++(); + S2 operator++(int); + S2 operator--(); + S2 operator--(int); + S2 operator=(int); + S2 operator*=(int); + S2 operator/=(int); + S2 operator%=(int); + S2 operator+=(int); + S2 operator-=(int); + S2 operator<<=(int); + S2 operator>>=(int); + S2 operator&=(int); + S2 operator|=(int); + S2 operator^=(int); +}; + +// Test overloaded operators +void test2() { + S2 x; + int y; + for (; y < 10; x++, y++) {} + for (; y < 10; ++x, y++) {} + for (; y < 10; x++, ++y) {} + for (; y < 10; ++x, ++y) {} + for (; y < 10; x--, ++y) {} + for (; y < 10; --x, ++y) {} + for (; y < 10; x = 5, ++y) {} + for (; y < 10; x *= 5, ++y) {} + for (; y < 10; x /= 5, ++y) {} + for (; y < 10; x %= 5, ++y) {} + for (; y < 10; x += 5, ++y) {} + for (; y < 10; x -= 5, ++y) {} + for (; y < 10; x <<= 5, ++y) {} + for (; y < 10; x >>= 5, ++y) {} + for (; y < 10; x &= 5, ++y) {} + for (; y < 10; x |= 5, ++y) {} + for (; y < 10; x ^= 5, ++y) {} +} + +// Test nested comma operators +void test3() { + int x1, x2, x3; + int y1, *y2 = 0, y3 = 5; + for (int z1 = 5, z2 = 4, z3 = 3; x1 <4; ++x1) {} +} + +class Stream { + public: + Stream& operator<<(int); +} cout; + +int return_four() { return 5; } + +// Confusing "," for "<<" +void test4() { + cout << 5 << return_four(); + cout << 5, return_four(); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:12-[[@LINE-4]]:12}:")" +} + +// Confusing "," for "==" +void test5() { + if (return_four(), 5) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:7-[[@LINE-3]]:7}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:20-[[@LINE-4]]:20}:")" + + if (return_four() == 5) {} +} + +// Confusing "," for "+" +int test6() { + return return_four(), return_four(); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" + + return return_four() + return_four(); +} + +void Concat(int); +void Concat(int, int); + +// Testing extra parentheses in function call +void test7() { + Concat((return_four() , 5)); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:24-[[@LINE-4]]:24}:")" + + Concat(return_four() , 5); +} + +// Be sure to look through parentheses +void test8() { + int x, y; + for (x = 0; return_four(), x;) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:15-[[@LINE-3]]:15}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:28-[[@LINE-4]]:28}:")" + + for (x = 0; (return_four()), (x) ;) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:15-[[@LINE-3]]:15}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:30-[[@LINE-4]]:30}:")" +} + +bool DoStuff(); +class S9 { +public: + bool Advance(); + bool More(); +}; + +// Ignore comma operator in for-loop initializations and increments. +void test9() { + int x, y; + for (x = 0, y = 5; x < y; ++x) {} + for (x = 0; x < 10; DoStuff(), ++x) {} + for (S9 s; s.More(); s.Advance(), ++x) {} +} + +void test10() { + int x, y; + ++x, ++y; + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:6-[[@LINE-4]]:6}:")" +} + +// Ignore comma operator in templates. +namespace test11 { +template <bool T> +struct B { static const bool value = T; }; + +typedef B<true> true_type; +typedef B<false> false_type; + +template <bool...> +struct bool_seq; + +template <typename... xs> +class Foo { + typedef bool_seq<(xs::value, true)...> all_true; + typedef bool_seq<(xs::value, false)...> all_false; + typedef bool_seq<xs::value...> seq; +}; + +const auto X = Foo<true_type>(); +} + +namespace test12 { +class Mutex { + public: + Mutex(); + ~Mutex(); +}; +class MutexLock { +public: + MutexLock(Mutex &); + MutexLock(); + ~MutexLock(); +}; +class BuiltinMutex { + Mutex M; +}; +Mutex StatusMutex; +bool Status; + +bool get_status() { + return (MutexLock(StatusMutex), Status); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:33-[[@LINE-4]]:33}:")" + return (MutexLock(), Status); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:22-[[@LINE-4]]:22}:")" + return (BuiltinMutex(), Status); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:25-[[@LINE-4]]:25}:")" +} +} + +// Check for comma operator in conditions. +void test13(int x) { + x = (return_four(), x); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:8-[[@LINE-3]]:8}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:21-[[@LINE-4]]:21}:")" + + int y = (return_four(), x); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:12-[[@LINE-3]]:12}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:25-[[@LINE-4]]:25}:")" + + for (; return_four(), x;) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" + + while (return_four(), x) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" + + if (return_four(), x) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:7-[[@LINE-3]]:7}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:20-[[@LINE-4]]:20}:")" + + do { } while (return_four(), x); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:17-[[@LINE-3]]:17}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:30-[[@LINE-4]]:30}:")" +} + +// Nested comma operator with fix-its. +void test14() { + return_four(), return_four(), return_four(), return_four(); + // expected-warning@-1 3{{comma operator}} + // expected-note@-2 3{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:16-[[@LINE-4]]:16}:")" + // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:18-[[@LINE-5]]:18}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:31-[[@LINE-6]]:31}:")" + // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:33-[[@LINE-7]]:33}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")" +} diff --git a/test/SemaCXX/warn-float-conversion.cpp b/test/SemaCXX/warn-float-conversion.cpp index 22c33040b26b..fc221893aeee 100644 --- a/test/SemaCXX/warn-float-conversion.cpp +++ b/test/SemaCXX/warn-float-conversion.cpp @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -verify -fsyntax-only %s -Wfloat-conversion +// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-pc-linux-gnu %s -Wno-literal-conversion -Wfloat-conversion -DFLOAT_CONVERSION -DZERO -DBOOL -DCONSTANT_BOOL -DOVERFLOW +// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-pc-linux-gnu %s -Wno-conversion -Wfloat-overflow-conversion -DOVERFLOW +// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-pc-linux-gnu %s -Wno-conversion -Wfloat-zero-conversion -DZERO +float ReturnFloat(); + +#ifdef FLOAT_CONVERSION bool ReturnBool(float f) { return f; //expected-warning{{conversion}} } @@ -36,3 +41,49 @@ void Convert(float f, double d, long double ld) { l = ld; //expected-warning{{conversion}} } +void Test() { + int a1 = 10.0/2.0; //expected-warning{{conversion}} + int a2 = 1.0/2.0; //expected-warning{{conversion}} + bool a3 = ReturnFloat(); //expected-warning{{conversion}} + int a4 = 1e30 + 1; //expected-warning{{conversion}} +} + +void TestConstantFloat() { + // Don't warn on exact floating literals. + int a1 = 5.0; + int a2 = 1e3; + + int a3 = 5.5; // caught by -Wliteral-conversion + int a4 = 500.44; // caught by -Wliteral-convserion + + int b1 = 5.0 / 1.0; //expected-warning{{conversion}} + int b2 = 5.0 / 2.0; //expected-warning{{conversion}} + + const float five = 5.0; + + int b3 = five / 1.0; //expected-warning{{conversion}} + int b4 = five / 2.0; //expected-warning{{conversion}} +} +#endif // FLOAT_CONVERSION + +#ifdef ZERO +void TestZero() { + const float half = .5; + int a1 = half; // expected-warning{{implicit conversion from 'const float' to 'int' changes non-zero value from 0.5 to 0}} + int a2 = 1.0 / 2.0; // expected-warning{{implicit conversion from 'double' to 'int' changes non-zero value from 0.5 to 0}} + int a3 = 5; +} +#endif // ZERO + +#ifdef OVERFLOW +void TestOverflow() { + char a = 500.0; // caught by -Wliteral-conversion + char b = -500.0; // caught by -Wliteral-conversion + + const float LargeNumber = 1024; + char c = LargeNumber; // expected-warning{{implicit conversion of out of range value from 'const float' to 'char' changes value from 1024 to 127}} + char d = 400.0 + 400.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'char' changes value from 800 to 127}} + + char e = 1.0 / 0.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'char' changes value from +Inf to 127}} +} +#endif // OVERFLOW diff --git a/test/SemaCXX/warn-literal-conversion.cpp b/test/SemaCXX/warn-literal-conversion.cpp index 5d4b6f7f5bf8..875aa1dec5ef 100644 --- a/test/SemaCXX/warn-literal-conversion.cpp +++ b/test/SemaCXX/warn-literal-conversion.cpp @@ -25,7 +25,7 @@ void test0() { // Test passing a literal floating-point value to a function that takes an integer. foo(1.2F); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}} - int y10 = -1.2F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}} + int y10 = -1.2F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from -1.2 to -1}} // -Wliteral-conversion does NOT catch const values. // (-Wconversion DOES catch them.) diff --git a/test/SemaCXX/warn-loop-analysis.cpp b/test/SemaCXX/warn-loop-analysis.cpp index c666c48fc017..25ec7a7862ed 100644 --- a/test/SemaCXX/warn-loop-analysis.cpp +++ b/test/SemaCXX/warn-loop-analysis.cpp @@ -260,3 +260,9 @@ void test8() { i--; } } + +int f(int); +void test9() { + // Don't warn when variable is defined by the loop condition. + for (int i = 0; int x = f(i); ++i) {} +} diff --git a/test/SemaCXX/warn-shadow.cpp b/test/SemaCXX/warn-shadow.cpp index 5ad2233d234a..9d68fe7c47a6 100644 --- a/test/SemaCXX/warn-shadow.cpp +++ b/test/SemaCXX/warn-shadow.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow %s +// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow-all %s namespace { int i; // expected-note {{previous declaration is here}} @@ -29,7 +29,23 @@ void foo() { class A { static int data; // expected-note {{previous declaration}} - int field; // expected-note {{previous declaration}} + // expected-note@+1 {{previous declaration}} + int field; + int f1, f2, f3, f4; // expected-note 8 {{previous declaration is here}} + + // The initialization is safe, but the modifications are not. + A(int f1, int f2, int f3, int f4) // expected-note-re 4 {{variable 'f{{[0-4]}}' is declared here}} + : f1(f1) { + f1 = 3; // expected-warning {{modifying constructor parameter 'f1' that shadows a field of 'A'}} + f1 = 4; // one warning per shadow + f2++; // expected-warning {{modifying constructor parameter 'f2' that shadows a field of 'A'}} + --f3; // expected-warning {{modifying constructor parameter 'f3' that shadows a field of 'A'}} + f4 += 2; // expected-warning {{modifying constructor parameter 'f4' that shadows a field of 'A'}} + } + + // The initialization is safe, but the modifications are not. + // expected-warning-re@+1 4 {{constructor parameter 'f{{[0-4]}}' shadows the field 'f{{[0-9]}}' of 'A'}} + A(int f1, int f2, int f3, int f4, double overload_dummy) {} void test() { char *field; // expected-warning {{declaration shadows a field of 'A'}} diff --git a/test/SemaCXX/warn-unused-private-field.cpp b/test/SemaCXX/warn-unused-private-field.cpp index 932a7dcea1da..fb34fa98eaf6 100644 --- a/test/SemaCXX/warn-unused-private-field.cpp +++ b/test/SemaCXX/warn-unused-private-field.cpp @@ -128,6 +128,7 @@ class EverythingUsed { int *use = &by_reference_; int test[2]; test[as_array_index_] = 42; + int EverythingUsed::*ptr = &EverythingUsed::by_pointer_to_member_; } template<class T> @@ -142,6 +143,7 @@ class EverythingUsed { int by_template_function_; int as_array_index_; int by_initializer_; + int by_pointer_to_member_; }; class HasFeatureTest { diff --git a/test/SemaCXX/warn-unused-value.cpp b/test/SemaCXX/warn-unused-value.cpp index efabd5063068..d6ec0fb5d1cd 100644 --- a/test/SemaCXX/warn-unused-value.cpp +++ b/test/SemaCXX/warn-unused-value.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -std=c++11 %s // PR4806 namespace test0 { @@ -12,7 +14,10 @@ namespace test0 { // pointer to volatile has side effect (thus no warning) Box* box = new Box; box->i; // expected-warning {{expression result unused}} - box->j; // expected-warning {{expression result unused}} + box->j; +#if __cplusplus <= 199711L + // expected-warning@-2 {{expression result unused}} +#endif } } |