diff options
author | dim <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 |
commit | 554bcb69c2d785a011a30e7db87a36a87fe7db10 (patch) | |
tree | 9abb1a658a297776086f4e0dfa6ca533de02104e /test/Sema | |
parent | bb67ca86b31f67faee50bd10c3b036d65751745a (diff) | |
download | FreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.zip FreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.tar.gz |
Vendor import of clang trunk r161861:
http://llvm.org/svn/llvm-project/cfe/trunk@161861
Diffstat (limited to 'test/Sema')
56 files changed, 1927 insertions, 95 deletions
diff --git a/test/Sema/128bitint.c b/test/Sema/128bitint.c index 89d3ee2..ddad835 100644 --- a/test/Sema/128bitint.c +++ b/test/Sema/128bitint.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-apple-darwin9 %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-apple-darwin9 -fms-extensions %s typedef int i128 __attribute__((__mode__(TI))); typedef unsigned u128 __attribute__((__mode__(TI))); @@ -11,3 +11,10 @@ __uint128_t b = (__uint128_t)-1; // PR11916: Support for libstdc++ 4.7 __int128 i = (__int128)0; unsigned __int128 u = (unsigned __int128)-1; + +long long SignedTooBig = 123456789012345678901234567890; // expected-warning {{integer constant is too large for its type}} +__int128_t Signed128 = 123456789012345678901234567890i128; +long long Signed64 = 123456789012345678901234567890i128; // expected-warning {{implicit conversion from '__int128' to 'long long' changes value from 123456789012345678901234567890 to -4362896299872285998}} +unsigned long long UnsignedTooBig = 123456789012345678901234567890; // expected-warning {{integer constant is too large for its type}} +__uint128_t Unsigned128 = 123456789012345678901234567890Ui128; +unsigned long long Unsigned64 = 123456789012345678901234567890Ui128; // expected-warning {{implicit conversion from 'unsigned __int128' to 'unsigned long long' changes value from 123456789012345678901234567890 to 14083847773837265618}} diff --git a/test/Sema/Inputs/format-unused-system-args.h b/test/Sema/Inputs/format-unused-system-args.h new file mode 100644 index 0000000..3a6b165 --- /dev/null +++ b/test/Sema/Inputs/format-unused-system-args.h @@ -0,0 +1,8 @@ +// "System header" for testing that -Wformat-extra-args does not apply to +// arguments specified in system headers. + +#define PRINT2(fmt, a1, a2) \ + printf((fmt), (a1), (a2)) + +#define PRINT1(fmt, a1) \ + PRINT2((fmt), (a1), 0) diff --git a/test/Sema/MicrosoftCompatibility.c b/test/Sema/MicrosoftCompatibility.c index f148e869..6b137a6 100644 --- a/test/Sema/MicrosoftCompatibility.c +++ b/test/Sema/MicrosoftCompatibility.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility -enum ENUM1; // expected-warning {{forward references to 'enum' types are a Microsoft extension}} +enum ENUM1; // expected-warning {{forward references to 'enum' types are a Microsoft extension}} enum ENUM1 var1 = 3; enum ENUM1* var2 = 0; @@ -14,3 +14,8 @@ enum ENUM2 { __declspec(noreturn) void f6( void ) { return; // expected-warning {{function 'f6' declared 'noreturn' should not return}} } + +__declspec(align(32768)) struct S1 { int a; } s; /* expected-error {{requested alignment must be 8192 bytes or smaller}} */ +struct __declspec(aligned) S2 {}; /* expected-warning {{unknown __declspec attribute 'aligned' ignored}} */ + +struct __declspec(appdomain) S3 {}; /* expected-warning {{__declspec attribute 'appdomain' is not supported}} */
\ No newline at end of file diff --git a/test/Sema/MicrosoftExtensions.c b/test/Sema/MicrosoftExtensions.c index fb0c6bd..5d7330e 100644 --- a/test/Sema/MicrosoftExtensions.c +++ b/test/Sema/MicrosoftExtensions.c @@ -87,11 +87,13 @@ typedef struct { AA; // expected-warning {{anonymous structs are a Microsoft extension}} } BB; -__declspec(deprecated("This is deprecated")) enum DE1 { one, two } e1; -struct __declspec(deprecated) DS1 { int i; float f; }; +__declspec(deprecated("This is deprecated")) enum DE1 { one, two } e1; // expected-note {{'e1' declared here}} +struct __declspec(deprecated) DS1 { int i; float f; }; // expected-note {{declared here}} #define MY_TEXT "This is also deprecated" -__declspec(deprecated(MY_TEXT)) void Dfunc1( void ) {} +__declspec(deprecated(MY_TEXT)) void Dfunc1( void ) {} // expected-note {{'Dfunc1' declared here}} + +struct __declspec(deprecated(123)) DS2 {}; // expected-error {{argument to deprecated attribute was not a string literal}} void test( void ) { e1 = one; // expected-warning {{'e1' is deprecated: This is deprecated}} diff --git a/test/Sema/alignas.c b/test/Sema/alignas.c index 5832393..d9a0164 100644 --- a/test/Sema/alignas.c +++ b/test/Sema/alignas.c @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c1x %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -Dalignof=__alignof %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -Dalignof=_Alignof %s _Alignas(3) int align_illegal; //expected-error {{requested alignment is not a power of 2}} _Alignas(int) char align_big; @@ -11,9 +12,9 @@ struct align_member { typedef _Alignas(8) char align_typedef; // FIXME: this should be rejected -_Static_assert(__alignof(align_big) == __alignof(int), "k's alignment is wrong"); -_Static_assert(__alignof(align_small) == 1, "j's alignment is wrong"); -_Static_assert(__alignof(align_multiple) == 8, "l's alignment is wrong"); -_Static_assert(__alignof(struct align_member) == 8, "quuux's alignment is wrong"); +_Static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong"); +_Static_assert(alignof(align_small) == 1, "j's alignment is wrong"); +_Static_assert(alignof(align_multiple) == 8, "l's alignment is wrong"); +_Static_assert(alignof(struct align_member) == 8, "quuux's alignment is wrong"); _Static_assert(sizeof(struct align_member) == 8, "quuux's size is wrong"); -_Static_assert(__alignof(align_typedef) == 8, "typedef's alignment is wrong"); +_Static_assert(alignof(align_typedef) == 8, "typedef's alignment is wrong"); diff --git a/test/Sema/alloc_size.c b/test/Sema/alloc_size.c new file mode 100644 index 0000000..e2f5298 --- /dev/null +++ b/test/Sema/alloc_size.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void* my_malloc(unsigned char) __attribute__((alloc_size(1))); +void* my_calloc(unsigned char, short) __attribute__((alloc_size(1,2))); +void* my_realloc(void*, unsigned) __attribute__((alloc_size(2))); + + +void* fn1(int) __attribute__((alloc_size("xpto"))); // expected-error{{attribute requires integer constant}} + +void* fn2(void*) __attribute__((alloc_size(1))); // expected-error{{attribute requires integer constant}} + +void* fn3(unsigned) __attribute__((alloc_size(0))); // expected-error{{attribute parameter 1 is out of bounds}} +void* fn4(unsigned) __attribute__((alloc_size(2))); // expected-error{{attribute parameter 1 is out of bounds}} + +void fn5(unsigned) __attribute__((alloc_size(1))); // expected-warning{{only applies to functions that return a pointer}} +char fn6(unsigned) __attribute__((alloc_size(1))); // expected-warning{{only applies to functions that return a pointer}} + +void* fn7(unsigned) __attribute__((alloc_size)); // expected-error {{attribute takes at least 1 argument}} + +void *fn8(int, int) __attribute__((alloc_size(1, 1))); // OK + +void* fn9(unsigned) __attribute__((alloc_size(12345678901234567890123))); // expected-warning {{integer constant is too large for its type}} // expected-error {{attribute parameter 1 is out of bounds}} + +void* fn10(size_t, size_t) __attribute__((alloc_size(1,2))); // expected-error{{redefinition of parameter}} \ + // expected-error{{a parameter list without types is only allowed in a function definition}} \ + // expected-warning{{alloc_size attribute only applies to functions and methods}} diff --git a/test/Sema/annotate.c b/test/Sema/annotate.c index 5b27277..ef878d4 100644 --- a/test/Sema/annotate.c +++ b/test/Sema/annotate.c @@ -4,7 +4,8 @@ void __attribute__((annotate("foo"))) foo(float *a) { __attribute__((annotate("bar"))) int x; __attribute__((annotate(1))) int y; // expected-error {{argument to annotate attribute was not a string literal}} __attribute__((annotate("bar", 1))) int z; // expected-error {{attribute takes one argument}} - int u = __builtin_annotation(z, (char*) 0); // expected-error {{__builtin_annotation requires a non wide string constant}} - int v = __builtin_annotation(z, (char*) L"bar"); // expected-error {{__builtin_annotation requires a non wide string constant}} + int u = __builtin_annotation(z, (char*) 0); // expected-error {{second argument to __builtin_annotation must be a non-wide string constant}} + int v = __builtin_annotation(z, (char*) L"bar"); // expected-error {{second argument to __builtin_annotation must be a non-wide string constant}} int w = __builtin_annotation(z, "foo"); + float b = __builtin_annotation(*a, "foo"); // expected-error {{first argument to __builtin_annotation must be an integer}} } diff --git a/test/Sema/array-bounds-ptr-arith.c b/test/Sema/array-bounds-ptr-arith.c index 022335b..e3de06a 100644 --- a/test/Sema/array-bounds-ptr-arith.c +++ b/test/Sema/array-bounds-ptr-arith.c @@ -19,3 +19,21 @@ void pr11594(struct S *s) { int a[10]; int *p = a - s->n; } + +// Test case reduced from <rdar://problem/11387038>. This resulted in +// an assertion failure because of the typedef instead of an explicit +// constant array type. +struct RDar11387038 {}; +typedef struct RDar11387038 RDar11387038Array[1]; +struct RDar11387038_Table { + RDar11387038Array z; +}; +typedef struct RDar11387038_Table * TPtr; +typedef TPtr *TabHandle; +struct RDar11387038_B { TabHandle x; }; +typedef struct RDar11387038_B RDar11387038_B; + +void radar11387038() { + RDar11387038_B *pRDar11387038_B; + struct RDar11387038* y = &(*pRDar11387038_B->x)->z[4]; +} diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c index 26c0b24..cfdf8e2 100644 --- a/test/Sema/array-init.c +++ b/test/Sema/array-init.c @@ -50,7 +50,7 @@ void func() { static long x2[3] = { 1.0, "abc", // expected-warning{{incompatible pointer to integer conversion initializing 'long' with an expression of type 'char [4]'}} - 5.8 }; // expected-warning {{implicit conversion turns literal floating-point number into integer}} + 5.8 }; // expected-warning {{implicit conversion from 'double' to 'long' changes value from 5.8 to 5}} } void test() { diff --git a/test/Sema/attr-aligned.c b/test/Sema/attr-aligned.c index c094ff1..92f2742 100644 --- a/test/Sema/attr-aligned.c +++ b/test/Sema/attr-aligned.c @@ -32,7 +32,7 @@ struct D { int member __attribute__((aligned(2))) __attribute__((packed)); } d; char d1[__alignof__(d) == 2 ?: -1] = {0}; char d2[__alignof__(d.member) == 2 ?: -1] = {0}; -struct E { int member __attribute__((aligned(2))); } __attribute__((packed)); +struct E { int member __attribute__((align(2))); } __attribute__((packed)); struct E e; char e1[__alignof__(e) == 2 ?: -1] = {0}; char e2[__alignof__(e.member) == 2 ?: -1] = {0}; diff --git a/test/Sema/attr-availability-ios.c b/test/Sema/attr-availability-ios.c index ea05e17..329068c 100644 --- a/test/Sema/attr-availability-ios.c +++ b/test/Sema/attr-availability-ios.c @@ -1,14 +1,14 @@ // RUN: %clang_cc1 "-triple" "x86_64-apple-ios3.0" -fsyntax-only -verify %s -void f0(int) __attribute__((availability(ios,introduced=2.0,deprecated=2.1))); +void f0(int) __attribute__((availability(ios,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' declared here}} void f1(int) __attribute__((availability(ios,introduced=2.1))); -void f2(int) __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); +void f2(int) __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' declared here}} void f3(int) __attribute__((availability(ios,introduced=3.0))); void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}} -void f5(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); +void f5(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5' declared here}} void f6(int) __attribute__((availability(ios,deprecated=3.0))); -void f6(int) __attribute__((availability(ios,introduced=2.0))); +void f6(int) __attribute__((availability(ios,introduced=2.0))); // expected-note {{'f6' declared here}} void test() { f0(0); // expected-warning{{'f0' is deprecated: first deprecated in iOS 2.1}} diff --git a/test/Sema/attr-availability-macosx.c b/test/Sema/attr-availability-macosx.c index 1de26e9..781523a 100644 --- a/test/Sema/attr-availability-macosx.c +++ b/test/Sema/attr-availability-macosx.c @@ -2,7 +2,7 @@ void f0(int) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6))); void f1(int) __attribute__((availability(macosx,introduced=10.5))); -void f2(int) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5))); +void f2(int) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5))); // expected-note {{'f2' declared here}} void f3(int) __attribute__((availability(macosx,introduced=10.6))); void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=3.0))); // expected-note{{explicitly marked unavailable}} void f5(int) __attribute__((availability(ios,introduced=3.2), availability(macosx,unavailable))); // expected-note{{function has been explicitly marked unavailable here}} diff --git a/test/Sema/attr-availability.c b/test/Sema/attr-availability.c index 0e6ea96..b4a6f96 100644 --- a/test/Sema/attr-availability.c +++ b/test/Sema/attr-availability.c @@ -8,7 +8,7 @@ void f3() __attribute__((availability(otheros,introduced=2.2))); // expected-war // rdar://10095131 extern void -ATSFontGetName(const char *oName) __attribute__((availability(macosx,introduced=8.0,deprecated=9.0, message="use CTFontCopyFullName"))); +ATSFontGetName(const char *oName) __attribute__((availability(macosx,introduced=8.0,deprecated=9.0, message="use CTFontCopyFullName"))); // expected-note {{'ATSFontGetName' declared here}} extern void ATSFontGetPostScriptName(int flags) __attribute__((availability(macosx,introduced=8.0,obsoleted=9.0, message="use ATSFontGetFullPostScriptName"))); // expected-note {{function has been explicitly marked unavailable here}} @@ -24,3 +24,22 @@ enum { NSDataWritingFileProtectionWriteOnly = 0x30000000, NSDataWritingFileProtectionCompleteUntilUserAuthentication = 0x40000000, }; + +void f4(int) __attribute__((availability(ios,deprecated=3.0))); +void f4(int) __attribute__((availability(ios,introduced=4.0))); // expected-warning {{feature cannot be deprecated in iOS version 3.0 before it was introduced in version 4.0; attribute ignored}} + +void f5(int) __attribute__((availability(ios,deprecated=3.0), + availability(ios,introduced=4.0))); // expected-warning {{feature cannot be deprecated in iOS version 3.0 before it was introduced in version 4.0; attribute ignored}} + +void f6(int) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{previous attribute is here}} +void f6(int) __attribute__((availability(ios,deprecated=4.0))); // expected-warning {{availability does not match previous declaration}} + +void f7(int) __attribute__((availability(ios,introduced=2.0))); +void f7(int) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{previous attribute is here}} +void f7(int) __attribute__((availability(ios,deprecated=4.0))); // expected-warning {{availability does not match previous declaration}} + + +// <rdar://problem/11886458> +#if !__has_feature(attribute_availability_with_message) +# error "Missing __has_feature" +#endif diff --git a/test/Sema/attr-coldhot.c b/test/Sema/attr-coldhot.c new file mode 100644 index 0000000..253b189 --- /dev/null +++ b/test/Sema/attr-coldhot.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int foo() __attribute__((__hot__)); +int bar() __attribute__((__cold__)); + +int var1 __attribute__((__cold__)); // expected-warning{{'__cold__' attribute only applies to functions}} +int var2 __attribute__((__hot__)); // expected-warning{{'__hot__' attribute only applies to functions}} + +int qux() __attribute__((__hot__)) __attribute__((__cold__)); // expected-error{{'__hot__' and cold attributes are not compatible}} +int baz() __attribute__((__cold__)) __attribute__((__hot__)); // expected-error{{'__cold__' and hot attributes are not compatible}} diff --git a/test/Sema/attr-decl-after-definition.c b/test/Sema/attr-decl-after-definition.c index 4d32e00..17b94cc 100644 --- a/test/Sema/attr-decl-after-definition.c +++ b/test/Sema/attr-decl-after-definition.c @@ -14,6 +14,26 @@ int bar __attribute__((weak)); int bar __attribute__((used)); extern int bar __attribute__((weak)); int bar = 0; // expected-note {{previous definition is here}} -int bar __attribute__((weak)); // expected-warning {{must precede definition}} +int bar __attribute__((weak)); // no warning as it matches the existing + // attribute. +int bar __attribute__((used, + visibility("hidden"))); // expected-warning {{must precede definition}} int bar; +struct zed { // expected-note {{previous definition is here}} +}; +struct __attribute__((visibility("hidden"))) zed; // expected-warning {{must precede definition}} + +struct __attribute__((visibility("hidden"))) zed2 { +}; +struct __attribute__((visibility("hidden"))) zed2; + +struct __attribute__((visibility("hidden"))) zed3 { // expected-note {{previous definition is here}} +}; +struct __attribute__((visibility("hidden"), + packed // expected-warning {{must precede definition}} + )) zed3; + +struct __attribute__((visibility("hidden"))) zed4 { // expected-note {{previous attribute is here}} +}; +struct __attribute__((visibility("default"))) zed4; // expected-error {{visibility does not match previous declaration}} diff --git a/test/Sema/attr-deprecated-message.c b/test/Sema/attr-deprecated-message.c index 5de31d0..f48d13e 100644 --- a/test/Sema/attr-deprecated-message.c +++ b/test/Sema/attr-deprecated-message.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only // rdar: // 6734520 -typedef int INT1 __attribute__((deprecated("Please avoid INT1"))); +typedef int INT1 __attribute__((deprecated("Please avoid INT1"))); // expected-note 3 {{'INT1' declared here}} typedef INT1 INT2 __attribute__ ((__deprecated__("Please avoid INT2"))); @@ -12,16 +12,16 @@ typedef INT1 INT1b __attribute__ ((deprecated("Please avoid INT1b"))); INT1 should_be_unavailable; // expected-warning {{'INT1' is deprecated: Please avoid INT1}} INT1a should_not_be_deprecated; -INT1 f1(void) __attribute__ ((deprecated("Please avoid f1"))); +INT1 f1(void) __attribute__ ((deprecated("Please avoid f1"))); // expected-note {{'f1' declared here}} INT1 f2(void); // expected-warning {{'INT1' is deprecated: Please avoid INT1}} -typedef enum {red, green, blue} Color __attribute__((deprecated("Please avoid Color"))); +typedef enum {red, green, blue} Color __attribute__((deprecated("Please avoid Color"))); // expected-note {{'Color' declared here}} Color c1; // expected-warning {{'Color' is deprecated: Please avoid Color}} int g1; -int g2 __attribute__ ((deprecated("Please avoid g2"))); +int g2 __attribute__ ((deprecated("Please avoid g2"))); // expected-note {{'g2' declared here}} int func1() { diff --git a/test/Sema/attr-deprecated.c b/test/Sema/attr-deprecated.c index 4760dab..565be7f 100644 --- a/test/Sema/attr-deprecated.c +++ b/test/Sema/attr-deprecated.c @@ -1,10 +1,10 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only -int f() __attribute__((deprecated)); +int f() __attribute__((deprecated)); // expected-note 2 {{declared here}} void g() __attribute__((deprecated)); -void g(); +void g(); // expected-note {{declared here}} -extern int var __attribute__((deprecated)); +extern int var __attribute__((deprecated)); // expected-note {{declared here}} int a() { int (*ptr)() = f; // expected-warning {{'f' is deprecated}} @@ -17,13 +17,13 @@ int a() { } // test if attributes propagate to variables -extern int var; +extern int var; // expected-note {{declared here}} int w() { return var; // expected-warning {{'var' is deprecated}} } int old_fn() __attribute__ ((deprecated)); -int old_fn(); +int old_fn(); // expected-note {{declared here}} int (*fn_ptr)() = old_fn; // expected-warning {{'old_fn' is deprecated}} int old_fn() { @@ -32,7 +32,7 @@ int old_fn() { struct foo { - int x __attribute__((deprecated)); + int x __attribute__((deprecated)); // expected-note 3 {{declared here}} }; void test1(struct foo *F) { @@ -41,11 +41,11 @@ void test1(struct foo *F) { struct foo f2 = { 17 }; // expected-warning {{'x' is deprecated}} } -typedef struct foo foo_dep __attribute__((deprecated)); +typedef struct foo foo_dep __attribute__((deprecated)); // expected-note 12 {{declared here}} foo_dep *test2; // expected-warning {{'foo_dep' is deprecated}} struct __attribute__((deprecated, - invalid_attribute)) bar_dep ; // expected-warning {{unknown attribute 'invalid_attribute' ignored}} + invalid_attribute)) bar_dep ; // expected-warning {{unknown attribute 'invalid_attribute' ignored}} expected-note 2 {{declared here}} struct bar_dep *test3; // expected-warning {{'bar_dep' is deprecated}} @@ -102,9 +102,9 @@ foo_dep test17, // expected-warning {{'foo_dep' is deprecated}} test19; // rdar://problem/8518751 -enum __attribute__((deprecated)) Test20 { - test20_a __attribute__((deprecated)), - test20_b +enum __attribute__((deprecated)) Test20 { // expected-note {{declared here}} + test20_a __attribute__((deprecated)), // expected-note {{declared here}} + test20_b // expected-note {{declared here}} }; void test20() { enum Test20 f; // expected-warning {{'Test20' is deprecated}} @@ -113,3 +113,10 @@ void test20() { } char test21[__has_feature(attribute_deprecated_with_message) ? 1 : -1]; + +struct test22 { + foo_dep a __attribute((deprecated)); + foo_dep b; // expected-warning {{'foo_dep' is deprecated}} + foo_dep c, d __attribute((deprecated)); // expected-warning {{'foo_dep' is deprecated}} + __attribute((deprecated)) foo_dep e, f; +}; diff --git a/test/Sema/attr-nodebug.c b/test/Sema/attr-nodebug.c index a66e961..3cc4088 100644 --- a/test/Sema/attr-nodebug.c +++ b/test/Sema/attr-nodebug.c @@ -1,8 +1,11 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only -int a __attribute__((nodebug)); // expected-warning {{'nodebug' attribute only applies to functions}} +int a __attribute__((nodebug)); + +void b() { + int b __attribute__((nodebug)); // expected-warning {{'nodebug' only applies to variables with static storage duration and functions}} +} void t1() __attribute__((nodebug)); void t2() __attribute__((nodebug(2))); // expected-error {{attribute takes no arguments}} - diff --git a/test/Sema/attr-section.c b/test/Sema/attr-section.c index a932525..69ca732 100644 --- a/test/Sema/attr-section.c +++ b/test/Sema/attr-section.c @@ -13,3 +13,7 @@ void test() { __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute is not valid on local variables}} __attribute__((section("NEAR,x"))) static int n2; // ok. } + +// pr9356 +void __attribute__((section("foo,zed"))) test2(void); // expected-note {{previous attribute is here}} +void __attribute__((section("bar,zed"))) test2(void) {} // expected-warning {{section does not match previous declaration}} diff --git a/test/Sema/attr-tls_model.c b/test/Sema/attr-tls_model.c new file mode 100644 index 0000000..e184ebc --- /dev/null +++ b/test/Sema/attr-tls_model.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -verify -fsyntax-only %s + +#if !__has_attribute(tls_model) +#error "Should support tls_model attribute" +#endif + +int f() __attribute((tls_model("global-dynamic"))); // expected-error {{'tls_model' attribute only applies to thread-local variables}} + +int x __attribute((tls_model("global-dynamic"))); // expected-error {{'tls_model' attribute only applies to thread-local variables}} +static __thread int y __attribute((tls_model("global-dynamic"))); // no-warning + +static __thread int y __attribute((tls_model("local", "dynamic"))); // expected-error {{attribute takes one argument}} +static __thread int y __attribute((tls_model(123))); // expected-error {{argument to tls_model attribute was not a string literal}} +static __thread int y __attribute((tls_model("foobar"))); // expected-error {{tls_model must be "global-dynamic", "local-dynamic", "initial-exec" or "local-exec"}} diff --git a/test/Sema/attr-unavailable-message.c b/test/Sema/attr-unavailable-message.c index b2956d8..9710496 100644 --- a/test/Sema/attr-unavailable-message.c +++ b/test/Sema/attr-unavailable-message.c @@ -29,8 +29,8 @@ void unavail(void) { // rdar://10201690 enum foo { - a = 1, - b __attribute__((deprecated())) = 2, + a = 1, // expected-note {{declared here}} + b __attribute__((deprecated())) = 2, // expected-note {{declared here}} c = 3 }__attribute__((deprecated())); diff --git a/test/Sema/attr-visibility.c b/test/Sema/attr-visibility.c index 5cf2695..77bc39c 100644 --- a/test/Sema/attr-visibility.c +++ b/test/Sema/attr-visibility.c @@ -7,3 +7,18 @@ void test2() __attribute__((visibility("internal"))); // rdar://problem/10753392 void test3() __attribute__((visibility("protected"))); // expected-warning {{target does not support 'protected' visibility; using 'default'}} +struct __attribute__((visibility("hidden"))) test4; // expected-note {{previous attribute is here}} +struct test4; +struct __attribute__((visibility("default"))) test4; // expected-error {{visibility does not match previous declaration}} + +struct test5; +struct __attribute__((visibility("hidden"))) test5; // expected-note {{previous attribute is here}} +struct __attribute__((visibility("default"))) test5; // expected-error {{visibility does not match previous declaration}} + +void test6() __attribute__((visibility("hidden"), // expected-note {{previous attribute is here}} + visibility("default"))); // expected-error {{visibility does not match previous declaration}} + +extern int test7 __attribute__((visibility("default"))); // expected-note {{previous attribute is here}} +extern int test7 __attribute__((visibility("hidden"))); // expected-error {{visibility does not match previous declaration}} + +typedef int __attribute__((visibility("default"))) bar; // expected-warning {{visibility attribute ignored}} diff --git a/test/Sema/c89-2.c b/test/Sema/c89-2.c index f6f6bd9..14b955a 100644 --- a/test/Sema/c89-2.c +++ b/test/Sema/c89-2.c @@ -1,4 +1,4 @@ -/* RUN: %clang_cc1 %s -std=c89 -pedantic-errors -verify +/* RUN: %clang_cc1 %s -std=c89 -pedantic-errors -Wno-empty-translation-unit -verify */ #if 1LL /* expected-error {{long long}} */ diff --git a/test/Sema/compare.c b/test/Sema/compare.c index 03aebb3..406ade8 100644 --- a/test/Sema/compare.c +++ b/test/Sema/compare.c @@ -333,3 +333,10 @@ struct test11S { unsigned x : 30; }; int test11(unsigned y, struct test11S *p) { return y > (p->x >> 24); // no-warning } + +typedef char one_char[1]; +typedef char two_chars[2]; + +void test12(unsigned a) { + if (0 && -1 > a) { } +} diff --git a/test/Sema/conditional-expr.c b/test/Sema/conditional-expr.c index 184ac4a..5ff58a2 100644 --- a/test/Sema/conditional-expr.c +++ b/test/Sema/conditional-expr.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wsign-conversion %s void foo() { *(0 ? (double *)0 : (void *)0) = 0; - // FIXME: GCC doesn't consider the the following two statements to be errors. + // FIXME: GCC doesn't consider the following two statements to be errors. *(0 ? (double *)0 : (void *)(int *)0) = 0; // expected-error {{incomplete type 'void' is not assignable}} *(0 ? (double *)0 : (void *)(double *)0) = 0; // expected-error {{incomplete type 'void' is not assignable}} *(0 ? (double *)0 : (int *)(void *)0) = 0; // expected-error {{incomplete type 'void' is not assignable}} expected-warning {{pointer type mismatch ('double *' and 'int *')}} diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c index bc8b227..16d028e 100644 --- a/test/Sema/const-eval.c +++ b/test/Sema/const-eval.c @@ -131,3 +131,6 @@ EVAL_EXPR(49, &x < &x - 100 ? 1 : -1) // expected-error {{must have a constant s extern struct Test50S Test50; EVAL_EXPR(50, &Test50 < (struct Test50S*)((unsigned)&Test50 + 10)) // expected-error {{must have a constant size}} + +// <rdar://problem/11874571> +EVAL_EXPR(51, 0 != (float)1e99) diff --git a/test/Sema/dllimport-dllexport.c b/test/Sema/dllimport-dllexport.c index 610059e..00c9df5 100644 --- a/test/Sema/dllimport-dllexport.c +++ b/test/Sema/dllimport-dllexport.c @@ -35,3 +35,9 @@ typedef int __declspec(dllimport) type2; // expected-warning{{'dllimport' attrib void __declspec(dllimport) foo12(); void foo12(){} // expected-warning {{'foo12' redeclared without dllimport attribute: previous dllimport ignored}} + +void __attribute__((dllimport)) foo13(); // expected-warning{{dllimport attribute ignored}} +void __attribute__((dllexport)) foo13(); + +extern int foo14 __attribute__((dllexport)); +extern int foo14 __attribute__((dllimport)); // expected-warning{{dllimport attribute ignored}} diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c index 72cff65..a93e12e 100644 --- a/test/Sema/exprs.c +++ b/test/Sema/exprs.c @@ -162,11 +162,20 @@ void test17(int x) { x = sizeof(x/0); // no warning. } -// PR6501 +// PR6501 & PR11857 void test18_a(int a); // expected-note 2 {{'test18_a' declared here}} +void test18_b(int); // expected-note {{'test18_b' declared here}} +void test18_c(int a, int b); // expected-note 2 {{'test18_c' declared here}} +void test18_d(int a, ...); // expected-note {{'test18_d' declared here}} +void test18_e(int a, int b, ...); // expected-note {{'test18_e' declared here}} void test18(int b) { - test18_a(b, b); // expected-error {{too many arguments to function call, expected 1, have 2}} - test18_a(); // expected-error {{too few arguments to function call, expected 1, have 0}} + test18_a(b, b); // expected-error {{too many arguments to function call, expected single argument 'a', have 2}} + test18_a(); // expected-error {{too few arguments to function call, single argument 'a' was not specified}} + test18_b(); // expected-error {{too few arguments to function call, expected 1, have 0}} + test18_c(b); // expected-error {{too few arguments to function call, expected 2, have 1}} + test18_c(b, b, b); // expected-error {{too many arguments to function call, expected 2, have 3}} + test18_d(); // expected-error {{too few arguments to function call, at least argument 'a' must be specified}} + test18_e(); // expected-error {{too few arguments to function call, expected at least 2, have 0}} } // PR7569 diff --git a/test/Sema/format-strings-enum-fixed-type.cpp b/test/Sema/format-strings-enum-fixed-type.cpp new file mode 100644 index 0000000..8b6b237 --- /dev/null +++ b/test/Sema/format-strings-enum-fixed-type.cpp @@ -0,0 +1,92 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -x c++ -std=c++11 -verify %s +// RUN: %clang_cc1 -triple i386-apple-darwin9 -x objective-c -verify %s +// RUN: %clang_cc1 -triple i386-apple-darwin9 -x objective-c++ -verify %s + +#ifdef __cplusplus +# define EXTERN_C extern "C" +#else +# define EXTERN_C extern +#endif + +EXTERN_C int printf(const char *,...); + +typedef enum : short { Constant = 0 } TestEnum; +// Note that in C (and Objective-C), the type of 'Constant' is 'short'. +// In C++ (and Objective-C++) it is 'TestEnum'. +// This is why we don't check for that in the expected output. + +void test(TestEnum input) { + printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has type 'TestEnum'}} + printf("%hhd", Constant); // expected-warning{{format specifies type 'char'}} + + printf("%hd", input); // no-warning + printf("%hd", Constant); // no-warning + + // While these are less correct, they are still safe. + printf("%d", input); // no-warning + printf("%d", Constant); // no-warning + + printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'TestEnum'}} + printf("%lld", Constant); // expected-warning{{format specifies type 'long long'}} +} + + +typedef enum : unsigned long { LongConstant = ~0UL } LongEnum; + +void testLong(LongEnum input) { + printf("%u", input); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'LongEnum'}} + printf("%u", LongConstant); // expected-warning{{format specifies type 'unsigned int'}} + + printf("%lu", input); + printf("%lu", LongConstant); +} + + +typedef short short_t; +typedef enum : short_t { ShortConstant = 0 } ShortEnum; + +void testUnderlyingTypedef(ShortEnum input) { + printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has type 'ShortEnum'}} + printf("%hhd", ShortConstant); // expected-warning{{format specifies type 'char'}} + + printf("%hd", input); // no-warning + printf("%hd", ShortConstant); // no-warning + + // While these are less correct, they are still safe. + printf("%d", input); // no-warning + printf("%d", ShortConstant); // no-warning + + printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'ShortEnum'}} + printf("%lld", ShortConstant); // expected-warning{{format specifies type 'long long'}} +} + + +typedef ShortEnum ShortEnum2; + +void testTypedefChain(ShortEnum2 input) { + printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has type 'ShortEnum2' (aka 'ShortEnum')}} + printf("%hd", input); // no-warning + printf("%d", input); // no-warning + printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'ShortEnum2' (aka 'ShortEnum')}} +} + + +typedef enum : char { CharConstant = 'a' } CharEnum; + +// %hhd is deliberately not required to be signed, because 'char' isn't either. +// This is a separate code path in FormatString.cpp. +void testChar(CharEnum input) { + printf("%hhd", input); // no-warning + printf("%hhd", CharConstant); // no-warning + + // This is not correct but it is safe. We warn because '%hd' shows intent. + printf("%hd", input); // expected-warning{{format specifies type 'short' but the argument has type 'CharEnum'}} + printf("%hd", CharConstant); // expected-warning{{format specifies type 'short'}} + + // This is not correct but it matches the promotion rules (and is safe). + printf("%d", input); // no-warning + printf("%d", CharConstant); // no-warning + + printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'CharEnum'}} + printf("%lld", CharConstant); // expected-warning{{format specifies type 'long long'}} +} diff --git a/test/Sema/format-strings-enum.c b/test/Sema/format-strings-enum.c new file mode 100644 index 0000000..a6c27d0 --- /dev/null +++ b/test/Sema/format-strings-enum.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x c++ -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x c++ -std=c++11 -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c++ -std=c++11 -verify %s + +#ifdef __cplusplus +# define EXTERN_C extern "C" +#else +# define EXTERN_C extern +#endif + +EXTERN_C int printf(const char *,...); + +typedef enum { Constant = 0 } TestEnum; +// Note that in C, the type of 'Constant' is 'int'. In C++ it is 'TestEnum'. +// This is why we don't check for that in the expected output. + +void test(TestEnum input) { + printf("%d", input); // no-warning + printf("%d", Constant); // no-warning + + printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'TestEnum'}} + printf("%lld", Constant); // expected-warning{{format specifies type 'long long'}} +} + + +typedef enum { LongConstant = ~0UL } LongEnum; + +void testLong(LongEnum input) { + printf("%u", input); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'LongEnum'}} + printf("%u", LongConstant); // expected-warning{{format specifies type 'unsigned int'}} + + printf("%lu", input); + printf("%lu", LongConstant); +} diff --git a/test/Sema/format-strings-fixit.c b/test/Sema/format-strings-fixit.c index 800691e..15ac713 100644 --- a/test/Sema/format-strings-fixit.c +++ b/test/Sema/format-strings-fixit.c @@ -64,6 +64,18 @@ void test() { printf("%f", (uintmax_t) 42); printf("%f", (ptrdiff_t) 42); + // Look beyond the first typedef. + typedef size_t my_size_type; + typedef intmax_t my_intmax_type; + typedef uintmax_t my_uintmax_type; + typedef ptrdiff_t my_ptrdiff_type; + typedef int my_int_type; + printf("%f", (my_size_type) 42); + printf("%f", (my_intmax_type) 42); + printf("%f", (my_uintmax_type) 42); + printf("%f", (my_ptrdiff_type) 42); + printf("%f", (my_int_type) 42); + // string printf("%ld", "foo"); @@ -122,6 +134,18 @@ void test2() { scanf("%f", &uIntmaxVar); scanf("%f", &ptrdiffVar); + // Look beyond the first typedef for named integer types. + typedef size_t my_size_type; + typedef intmax_t my_intmax_type; + typedef uintmax_t my_uintmax_type; + typedef ptrdiff_t my_ptrdiff_type; + typedef int my_int_type; + scanf("%f", (my_size_type*)&sizeVar); + scanf("%f", (my_intmax_type*)&intmaxVar); + scanf("%f", (my_uintmax_type*)&uIntmaxVar); + scanf("%f", (my_ptrdiff_type*)&ptrdiffVar); + scanf("%f", (my_int_type*)&intVar); + // Preserve the original formatting. scanf("%o", &longVar); scanf("%u", &longVar); @@ -162,6 +186,11 @@ void test2() { // CHECK: printf("%jd", (intmax_t) 42); // CHECK: printf("%ju", (uintmax_t) 42); // CHECK: printf("%td", (ptrdiff_t) 42); +// CHECK: printf("%zu", (my_size_type) 42); +// CHECK: printf("%jd", (my_intmax_type) 42); +// CHECK: printf("%ju", (my_uintmax_type) 42); +// CHECK: printf("%td", (my_ptrdiff_type) 42); +// CHECK: printf("%d", (my_int_type) 42); // CHECK: printf("%s", "foo"); // CHECK: printf("%lo", (long) 42); // CHECK: printf("%lu", (long) 42); @@ -193,6 +222,11 @@ void test2() { // CHECK: scanf("%jd", &intmaxVar); // CHECK: scanf("%ju", &uIntmaxVar); // CHECK: scanf("%td", &ptrdiffVar); +// CHECK: scanf("%zu", (my_size_type*)&sizeVar); +// CHECK: scanf("%jd", (my_intmax_type*)&intmaxVar); +// CHECK: scanf("%ju", (my_uintmax_type*)&uIntmaxVar); +// CHECK: scanf("%td", (my_ptrdiff_type*)&ptrdiffVar); +// CHECK: scanf("%d", (my_int_type*)&intVar); // CHECK: scanf("%lo", &longVar); // CHECK: scanf("%lu", &longVar); // CHECK: scanf("%lx", &longVar); diff --git a/test/Sema/format-strings-scanf.c b/test/Sema/format-strings-scanf.c index e94af5a..235ac11 100644 --- a/test/Sema/format-strings-scanf.c +++ b/test/Sema/format-strings-scanf.c @@ -33,6 +33,12 @@ void test(const char *s, int *i) { scanf("%*d", i); // // expected-warning{{data argument not used by format string}} scanf("%*d", i); // // expected-warning{{data argument not used by format string}} scanf("%*d%1$d", i); // no-warning + + scanf("%s", (char*)0); // no-warning + scanf("%s", (volatile char*)0); // no-warning + scanf("%s", (signed char*)0); // no-warning + scanf("%s", (unsigned char*)0); // no-warning + scanf("%hhu", (signed char*)0); // no-warning } void bad_length_modifiers(char *s, void *p, wchar_t *ws, long double *ld) { @@ -121,3 +127,52 @@ void test_quad(int *x, long long *llx) { scanf("%qd", x); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}} scanf("%qd", llx); // no-warning } + +void test_writeback(int *x) { + scanf("%n", (void*)0); // expected-warning{{format specifies type 'int *' but the argument has type 'void *'}} + scanf("%n %c", x, x); // expected-warning{{format specifies type 'char *' but the argument has type 'int *'}} + + scanf("%hhn", (signed char*)0); // no-warning + scanf("%hhn", (char*)0); // no-warning + scanf("%hhn", (unsigned char*)0); // no-warning + scanf("%hhn", (int*)0); // expected-warning{{format specifies type 'signed char *' but the argument has type 'int *'}} + + scanf("%hn", (short*)0); // no-warning + scanf("%hn", (unsigned short*)0); // no-warning + scanf("%hn", (int*)0); // expected-warning{{format specifies type 'short *' but the argument has type 'int *'}} + + scanf("%n", (int*)0); // no-warning + scanf("%n", (unsigned int*)0); // no-warning + scanf("%n", (char*)0); // expected-warning{{format specifies type 'int *' but the argument has type 'char *'}} + + scanf("%ln", (long*)0); // no-warning + scanf("%ln", (unsigned long*)0); // no-warning + scanf("%ln", (int*)0); // expected-warning{{format specifies type 'long *' but the argument has type 'int *'}} + + scanf("%lln", (long long*)0); // no-warning + scanf("%lln", (unsigned long long*)0); // no-warning + scanf("%lln", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}} + + scanf("%qn", (long long*)0); // no-warning + scanf("%qn", (unsigned long long*)0); // no-warning + scanf("%qn", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}} + +} + +void test_qualifiers(const int *cip, volatile int* vip, + const char *ccp, volatile char* vcp, + const volatile int *cvip) { + scanf("%d", cip); // expected-warning{{format specifies type 'int *' but the argument has type 'const int *'}} + scanf("%n", cip); // expected-warning{{format specifies type 'int *' but the argument has type 'const int *'}} + scanf("%s", ccp); // expected-warning{{format specifies type 'char *' but the argument has type 'const char *'}} + scanf("%d", cvip); // expected-warning{{format specifies type 'int *' but the argument has type 'const volatile int *'}} + + scanf("%d", vip); // No warning. + scanf("%n", vip); // No warning. + scanf("%c", vcp); // No warning. + + typedef int* ip_t; + typedef const int* cip_t; + scanf("%d", (ip_t)0); // No warning. + scanf("%d", (cip_t)0); // expected-warning{{format specifies type 'int *' but the argument has type 'cip_t' (aka 'const int *')}} +} diff --git a/test/Sema/format-strings-size_t.c b/test/Sema/format-strings-size_t.c index 7f88ff3..5058a76 100644 --- a/test/Sema/format-strings-size_t.c +++ b/test/Sema/format-strings-size_t.c @@ -13,3 +13,16 @@ void test(void) { // ptrdiff_t printf("%td", (double)42); // expected-warning {{format specifies type 'ptrdiff_t' (aka 'long') but the argument has type 'double'}} } + +void test_writeback(void) { + printf("%jn", (long*)0); // no-warning + printf("%jn", (unsigned long*)0); // no-warning + printf("%jn", (int*)0); // expected-warning{{format specifies type 'intmax_t *' (aka 'long *') but the argument has type 'int *'}} + + printf("%zn", (long*)0); // no-warning + // FIXME: Warn about %zn with non-ssize_t argument. + + printf("%tn", (long*)0); // no-warning + printf("%tn", (unsigned long*)0); // no-warning + printf("%tn", (int*)0); // expected-warning{{format specifies type 'ptrdiff_t *' (aka 'long *') but the argument has type 'int *'}} +} diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c index 086c5c6..86b9296 100644 --- a/test/Sema/format-strings.c +++ b/test/Sema/format-strings.c @@ -1,7 +1,10 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs -fno-signed-char %s +#define __need_wint_t #include <stdarg.h> -typedef __typeof(sizeof(int)) size_t; +#include <stddef.h> // For wint_t and wchar_t + typedef struct _FILE FILE; int fprintf(FILE *, const char *restrict, ...); int printf(const char *restrict, ...); // expected-note{{passing argument to parameter here}} @@ -85,9 +88,35 @@ void check_writeback_specifier() { int x; char *b; + printf("%n", b); // expected-warning{{format specifies type 'int *' but the argument has type 'char *'}} + printf("%n", &x); // no-warning + + printf("%hhn", (signed char*)0); // no-warning + printf("%hhn", (char*)0); // no-warning + printf("%hhn", (unsigned char*)0); // no-warning + printf("%hhn", (int*)0); // expected-warning{{format specifies type 'signed char *' but the argument has type 'int *'}} + + printf("%hn", (short*)0); // no-warning + printf("%hn", (unsigned short*)0); // no-warning + printf("%hn", (int*)0); // expected-warning{{format specifies type 'short *' but the argument has type 'int *'}} + + printf("%n", (int*)0); // no-warning + printf("%n", (unsigned int*)0); // no-warning + printf("%n", (char*)0); // expected-warning{{format specifies type 'int *' but the argument has type 'char *'}} + + printf("%ln", (long*)0); // no-warning + printf("%ln", (unsigned long*)0); // no-warning + printf("%ln", (int*)0); // expected-warning{{format specifies type 'long *' but the argument has type 'int *'}} + + printf("%lln", (long long*)0); // no-warning + printf("%lln", (unsigned long long*)0); // no-warning + printf("%lln", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}} + + printf("%qn", (long long*)0); // no-warning + printf("%qn", (unsigned long long*)0); // no-warning + printf("%qn", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}} - printf("%n",&x); // expected-warning {{'%n' in format string discouraged}} - sprintf(b,"%d%%%n",1, &x); // expected-warning {{'%n' in format string dis}} + printf("%Ln", 0); // expected-warning{{length modifier 'L' results in undefined behavior or no effect with 'n' conversion specifier}} } void check_invalid_specifier(FILE* fp, char *buf) @@ -164,7 +193,6 @@ void test9(char *P) { int x; printf(P); // expected-warning {{format string is not a string literal (potentially insecure)}} printf(P, 42); - printf("%n", &x); // expected-warning {{use of '%n' in format string discouraged }} } void torture(va_list v8) { @@ -182,7 +210,6 @@ void test10(int x, float f, int i, long long lli) { printf("%*d\n", f, x); // expected-warning{{field width should have type 'int', but argument has type 'double'}} printf("%*.*d\n", x, f, x); // expected-warning{{field precision should have type 'int', but argument has type 'double'}} printf("%**\n"); // expected-warning{{invalid conversion specifier '*'}} - printf("%n", &i); // expected-warning{{use of '%n' in format string discouraged (potentially insecure)}} printf("%d%d\n", x); // expected-warning{{more '%' conversions than data arguments}} printf("%d\n", x, x); // expected-warning{{data argument not used by format string}} printf("%W%d%Z\n", x, x, x); // expected-warning{{invalid conversion specifier 'W'}} expected-warning{{invalid conversion specifier 'Z'}} @@ -258,7 +285,6 @@ void f0(int_t x) { printf("%d\n", x); } // Unicode test cases. These are possibly specific to Mac OS X. If so, they should // eventually be moved into a separate test. -typedef __WCHAR_TYPE__ wchar_t; void test_unicode_conversions(wchar_t *s) { printf("%S", s); // no-warning @@ -314,14 +340,14 @@ void bug7377_bad_length_mod_usage() { // Bad flag usage printf("%#p", (void *) 0); // expected-warning{{flag '#' results in undefined behavior with 'p' conversion specifier}} printf("%0d", -1); // no-warning - printf("%#n", (void *) 0); // expected-warning{{flag '#' results in undefined behavior with 'n' conversion specifier}} expected-warning{{use of '%n' in format string discouraged (potentially insecure)}} - printf("%-n", (void *) 0); // expected-warning{{flag '-' results in undefined behavior with 'n' conversion specifier}} expected-warning{{use of '%n' in format string discouraged (potentially insecure)}} + printf("%#n", (int *) 0); // expected-warning{{flag '#' results in undefined behavior with 'n' conversion specifier}} + printf("%-n", (int *) 0); // expected-warning{{flag '-' results in undefined behavior with 'n' conversion specifier}} printf("%-p", (void *) 0); // no-warning // Bad optional amount use printf("%.2c", 'a'); // expected-warning{{precision used with 'c' conversion specifier, resulting in undefined behavior}} - printf("%1n", (void *) 0); // expected-warning{{field width used with 'n' conversion specifier, resulting in undefined behavior}} expected-warning{{use of '%n' in format string discouraged (potentially insecure)}} - printf("%.9n", (void *) 0); // expected-warning{{precision used with 'n' conversion specifier, resulting in undefined behavior}} expected-warning{{use of '%n' in format string discouraged (potentially insecure)}} + printf("%1n", (int *) 0); // expected-warning{{field width used with 'n' conversion specifier, resulting in undefined behavior}} + printf("%.9n", (int *) 0); // expected-warning{{precision used with 'n' conversion specifier, resulting in undefined behavior}} // Ignored flags printf("% +f", 1.23); // expected-warning{{flag ' ' is ignored when flag '+' is present}} @@ -332,17 +358,18 @@ void bug7377_bad_length_mod_usage() { } // PR 7981 - handle '%lc' (wint_t) -#ifndef wint_t -typedef int __darwin_wint_t; -typedef __darwin_wint_t wint_t; -#endif void pr7981(wint_t c, wchar_t c2) { printf("%lc", c); // no-warning printf("%lc", 1.0); // expected-warning{{the argument has type 'double'}} printf("%lc", (char) 1); // no-warning - printf("%lc", &c); // expected-warning{{the argument has type 'wint_t *' (aka 'int *')}} + printf("%lc", &c); // expected-warning{{the argument has type 'wint_t *'}} + // If wint_t and wchar_t are the same width and wint_t is signed where + // wchar_t is unsigned, an implicit conversion isn't possible. +#if defined(__WINT_UNSIGNED__) || !defined(__WCHAR_UNSIGNED__) || \ + __WINT_WIDTH__ > __WCHAR_WIDTH__ printf("%lc", c2); // no-warning +#endif } // <rdar://problem/8269537> -Wformat-security says NULL is not a string literal @@ -432,10 +459,6 @@ void pr9751() { printf(kFormat2, 1, "foo"); // expected-warning{{data argument position '18' exceeds the number of data arguments (2)}} printf("%18$s\n", 1, "foo"); // expected-warning{{data argument position '18' exceeds the number of data arguments (2)}} - const char kFormat3[] = "%n"; // expected-note{{format string is defined here}} - printf(kFormat3, "as"); // expected-warning{{use of '%n' in format string discouraged}} - printf("%n", "as"); // expected-warning{{use of '%n' in format string discouraged}} - const char kFormat4[] = "%y"; // expected-note{{format string is defined here}} printf(kFormat4, 5); // expected-warning{{invalid conversion specifier 'y'}} printf("%y", 5); // expected-warning{{invalid conversion specifier 'y'}} @@ -497,6 +520,15 @@ void pr9751() { printf(kFormat17, (int[]){0}); // expected-warning{{format specifies type 'unsigned short' but the argument}} printf("%a", (long double)0); // expected-warning{{format specifies type 'double' but the argument has type 'long double'}} + + // Test braced char[] initializers. + const char kFormat18[] = { "%lld" }; // expected-note{{format string is defined here}} + printf(kFormat18, 0); // expected-warning{{format specifies type}} + + // Make sure we point at the offending argument rather than the format string. + const char kFormat19[] = "%d"; // expected-note{{format string is defined here}} + printf(kFormat19, + 0.0); // expected-warning{{format specifies}} } // PR 9466: clang: doesn't know about %Lu, %Ld, and %Lx @@ -521,3 +553,48 @@ void test_other_formats() { dateformat(""); // expected-warning{{format string is empty}} dateformat(str); // no-warning (using strftime non literal is not unsafe) } + +// Do not warn about unused arguments coming from system headers. +// <rdar://problem/11317765> +#include <format-unused-system-args.h> +void test_unused_system_args(int x) { + PRINT1("%d\n", x); // no-warning{{extra argument is system header is OK}} +} + +void pr12761(char c) { + // This should not warn even with -fno-signed-char. + printf("%hhx", c); +} + + +// Test that we correctly merge the format in both orders. +extern void test14_foo(const char *, const char *, ...) + __attribute__((__format__(__printf__, 1, 3))); +extern void test14_foo(const char *, const char *, ...) + __attribute__((__format__(__scanf__, 2, 3))); + +extern void test14_bar(const char *, const char *, ...) + __attribute__((__format__(__scanf__, 2, 3))); +extern void test14_bar(const char *, const char *, ...) + __attribute__((__format__(__printf__, 1, 3))); + +void test14_zed(int *p) { + test14_foo("%", "%d", p); // expected-warning{{incomplete format specifier}} + test14_bar("%", "%d", p); // expected-warning{{incomplete format specifier}} +} + +void test_qualifiers(volatile int *vip, const int *cip, + const volatile int *cvip) { + printf("%n", cip); // expected-warning{{format specifies type 'int *' but the argument has type 'const int *'}} + printf("%n", cvip); // expected-warning{{format specifies type 'int *' but the argument has type 'const volatile int *'}} + + printf("%n", vip); // No warning. + printf("%p", cip); // No warning. + printf("%p", cvip); // No warning. + + + typedef int* ip_t; + typedef const int* cip_t; + printf("%n", (ip_t)0); // No warning. + printf("%n", (cip_t)0); // expected-warning{{format specifies type 'int *' but the argument has type 'cip_t' (aka 'const int *')}} +} diff --git a/test/Sema/fpack-struct.c b/test/Sema/fpack-struct.c index 37c8444..63766e9 100644 --- a/test/Sema/fpack-struct.c +++ b/test/Sema/fpack-struct.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -DEXPECTED_STRUCT_SIZE=5 -fpack-struct 1 %s -// RUN: %clang_cc1 -DEXPECTED_STRUCT_SIZE=6 -fpack-struct 2 %s +// RUN: %clang_cc1 -DEXPECTED_STRUCT_SIZE=5 -fpack-struct=1 %s +// RUN: %clang_cc1 -DEXPECTED_STRUCT_SIZE=6 -fpack-struct=2 %s struct s0 { int x; diff --git a/test/Sema/implicit-builtin-decl.c b/test/Sema/implicit-builtin-decl.c index 8cdd365..d7ec169 100644 --- a/test/Sema/implicit-builtin-decl.c +++ b/test/Sema/implicit-builtin-decl.c @@ -55,3 +55,5 @@ void snprintf() { } // PR8316 void longjmp(); // expected-warning{{declaration of built-in function 'longjmp' requires inclusion of the header <setjmp.h>}} + +extern float fmaxf(float, float); diff --git a/test/Sema/inline.c b/test/Sema/inline.c index 3c99f24..c27c00e 100644 --- a/test/Sema/inline.c +++ b/test/Sema/inline.c @@ -1,6 +1,78 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +#if defined(INCLUDE) +// ------- +// This section acts like a header file. +// ------- + +// Check the use of static variables in non-static inline functions. +static int staticVar; // expected-note + {{'staticVar' declared here}} +static int staticFunction(); // expected-note + {{'staticFunction' declared here}} +static struct { int x; } staticStruct; // expected-note + {{'staticStruct' declared here}} + +inline int useStatic () { // expected-note 3 {{use 'static' to give inline function 'useStatic' internal linkage}} + staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}} + (void)staticStruct.x; // expected-warning{{static variable 'staticStruct' is used in an inline function with external linkage}} + return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}} +} + +extern inline int useStaticFromExtern () { // no suggestions + staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}} + return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}} +} + +static inline int useStaticFromStatic () { + staticFunction(); // no-warning + return staticVar; // no-warning +} + +extern inline int useStaticInlineFromExtern () { + // Heuristic: if the function we're using is also inline, don't warn. + // This can still be wrong (in this case, we end up inlining calls to + // staticFunction and staticVar) but this got very noisy even using + // standard headers. + return useStaticFromStatic(); // no-warning +} + +static int constFunction() __attribute__((const)); + +inline int useConst () { + return constFunction(); // no-warning +} + +#else +// ------- +// This is the main source file. +// ------- + +#define INCLUDE +#include "inline.c" + // Check that we don't allow illegal uses of inline inline int a; // expected-error{{'inline' can only appear on functions}} typedef inline int b; // expected-error{{'inline' can only appear on functions}} int d(inline int a); // expected-error{{'inline' can only appear on functions}} + +// Check that the warnings from the "header file" aren't on by default in +// the main source file. + +inline int useStaticMainFile () { + staticFunction(); // no-warning + return staticVar; // no-warning +} + +// Check that the warnings show up when explicitly requested. + +#pragma clang diagnostic push +#pragma clang diagnostic warning "-Wstatic-in-inline" + +inline int useStaticAgain () { // expected-note 2 {{use 'static' to give inline function 'useStaticAgain' internal linkage}} + staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}} + return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}} +} + +#pragma clang diagnostic pop + +#endif + + diff --git a/test/Sema/invalid-decl.c b/test/Sema/invalid-decl.c index a5e7ad3..2699b25 100644 --- a/test/Sema/invalid-decl.c +++ b/test/Sema/invalid-decl.c @@ -20,3 +20,12 @@ zend_module_entry openssl_module_entry = { sizeof(zend_module_entry) }; +// <rdar://problem/11067144> +typedef int (FunctionType)(int *value); +typedef struct { + UndefinedType undef; // expected-error {{unknown type name 'UndefinedType'}} + FunctionType fun; // expected-error {{field 'fun' declared as a function}} +} StructType; +void f(StructType *buf) { + buf->fun = 0; +} diff --git a/test/Sema/knr-def-call.c b/test/Sema/knr-def-call.c index f41275d..80ad0d8 100644 --- a/test/Sema/knr-def-call.c +++ b/test/Sema/knr-def-call.c @@ -36,6 +36,6 @@ void proto(x) } void use_proto() { - proto(42.1); // expected-warning{{implicit conversion turns literal floating-point number into integer}} - (&proto)(42.1); // expected-warning{{implicit conversion turns literal floating-point number into integer}} + proto(42.1); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 42.1 to 42}} + (&proto)(42.1); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 42.1 to 42}} } diff --git a/test/Sema/ms_class_layout.cpp b/test/Sema/ms_class_layout.cpp index ea3f899..f484947 100644 --- a/test/Sema/ms_class_layout.cpp +++ b/test/Sema/ms_class_layout.cpp @@ -97,6 +97,48 @@ struct P : public M, public virtual L { struct R {}; +class IA { +public: + virtual ~IA(){} + virtual void ia() = 0; +}; + +class ICh : public virtual IA { +public: + virtual ~ICh(){} + virtual void ia(){} + virtual void iCh(){} +}; + +struct f { + virtual int asd() {return -90;} +}; + +struct s : public virtual f { + virtual ~s(){} + int r; + virtual int asd() {return -9;} +}; + +struct sd : virtual s, virtual ICh { + virtual ~sd(){} + int q; + char y; + virtual int asd() {return -1;} +}; +struct AV { + virtual void foo(); +}; +struct BV : AV { +}; +struct CV : virtual BV { + CV(); + virtual void foo(); +}; +struct DV : BV { +}; +struct EV : CV, DV { +}; #pragma pack(pop) // This needs only for building layouts. @@ -113,6 +155,8 @@ int main() { O* o; P* p; R* r; + sd *h; + EV *j; return 0; } @@ -333,3 +377,132 @@ int main() { // CHECK-NEXT: nvsize=0, nvalign=1 //CHECK: %struct.R = type { i8 } + +// CHECK: 0 | struct f +// CHECK-NEXT: 0 | (f vftable pointer) +// CHECK-NEXT: sizeof=4, dsize=4, align=4 +// CHECK-NEXT: nvsize=4, nvalign=4 + +// CHECK: 0 | struct s +// CHECK-NEXT: 0 | (s vftable pointer) +// CHECK-NEXT: 4 | (s vbtable pointer) +// CHECK-NEXT: 8 | int r +// CHECK-NEXT: 12 | (vtordisp for vbase f) +// CHECK-NEXT: 16 | struct f (virtual base) +// CHECK-NEXT: 16 | (f vftable pointer) +// CHECK-NEXT: sizeof=20, dsize=20, align=4 +// CHECK-NEXT: nvsize=12, nvalign=4 + +// CHECK: 0 | class IA +// CHECK-NEXT: 0 | (IA vftable pointer) +// CHECK-NEXT: sizeof=4, dsize=4, align=4 +// CHECK-NEXT: nvsize=4, nvalign=4 + +// CHECK: 0 | class ICh +// CHECK-NEXT: 0 | (ICh vftable pointer) +// CHECK-NEXT: 4 | (ICh vbtable pointer) +// CHECK-NEXT: 8 | (vtordisp for vbase IA) +// CHECK-NEXT: 12 | class IA (virtual base) +// CHECK-NEXT: 12 | (IA vftable pointer) +// CHECK-NEXT: sizeof=16, dsize=16, align=4 +// CHECK-NEXT: nvsize=8, nvalign=4 + +// CHECK: 0 | struct sd +// CHECK-NEXT: 0 | (sd vbtable pointer) +// CHECK-NEXT: 4 | int q +// CHECK-NEXT: 8 | char y +// CHECK-NEXT: 12 | (vtordisp for vbase f) +// CHECK-NEXT: 16 | struct f (virtual base) +// CHECK-NEXT: 16 | (f vftable pointer) +// CHECK-NEXT: 20 | struct s (virtual base) +// CHECK-NEXT: 20 | (s vftable pointer) +// CHECK-NEXT: 24 | (s vbtable pointer) +// CHECK-NEXT: 28 | int r +// CHECK-NEXT: 32 | (vtordisp for vbase IA) +// CHECK-NEXT: 36 | class IA (virtual base) +// CHECK-NEXT: 36 | (IA vftable pointer) +// CHECK-NEXT: 40 | class ICh (virtual base) +// CHECK-NEXT: 40 | (ICh vftable pointer) +// CHECK-NEXT: 44 | (ICh vbtable pointer) +// CHECK-NEXT: sizeof=48, dsize=48, align=4 +// CHECK-NEXT: nvsize=12, nvalign=4 + +// CHECK: %struct.f = type { i32 (...)** } +// CHECK: %struct.s = type { i32 (...)**, i32*, i32, [4 x i8], %struct.f } +// CHECK: %class.IA = type { i32 (...)** } +// CHECK: %class.ICh = type { i32 (...)**, i32*, [4 x i8], %class.IA } +// CHECK: %struct.sd = type { i32*, i32, i8, [7 x i8], %struct.f, %struct.s.base, [4 x i8], %class.IA, %class.ICh.base } + +// CHECK: 0 | struct AV +// CHECK-NEXT: 0 | (AV vftable pointer) +// CHECK-NEXT: sizeof=4, dsize=4, align=4 +// CHECK-NEXT: nvsize=4, nvalign=4 + + +// CHECK: 0 | struct BV +// CHECK-NEXT: 0 | struct AV (primary base) +// CHECK-NEXT: 0 | (AV vftable pointer) +// CHECK-NEXT: sizeof=4, dsize=4, align=4 +// CHECK-NEXT: nvsize=4, nvalign=4 + + +// CHECK: 0 | struct CV +// CHECK-NEXT: 0 | (CV vbtable pointer) +// CHECK-NEXT: 4 | (vtordisp for vbase BV) +// CHECK-NEXT: 8 | struct BV (virtual base) +// CHECK-NEXT: 8 | struct AV (primary base) +// CHECK-NEXT: 8 | (AV vftable pointer) +// CHECK-NEXT: sizeof=12, dsize=12, align=4 +// CHECK-NEXT: nvsize=4, nvalign=4 + +// CHECK: %struct.AV = type { i32 (...)** } +// CHECK: %struct.BV = type { %struct.AV } +// CHECK: %struct.CV = type { i32*, [4 x i8], %struct.BV } +// CHECK: %struct.CV.base = type { i32* } + +// CHECK: 0 | struct DV +// CHECK-NEXT: 0 | struct BV (primary base) +// CHECK-NEXT: 0 | struct AV (primary base) +// CHECK-NEXT: 0 | (AV vftable pointer) +// CHECK-NEXT: sizeof=4, dsize=4, align=4 +// CHECK-NEXT: nvsize=4, nvalign=4 + +// CHECK: %struct.DV = type { %struct.BV } + +// CHECK: 0 | struct EV +// CHECK-NEXT: 4 | struct CV (base) +// CHECK-NEXT: 4 | (CV vbtable pointer) +// CHECK-NEXT: 0 | struct DV (primary base) +// CHECK-NEXT: 0 | struct BV (primary base) +// CHECK-NEXT: 0 | struct AV (primary base) +// CHECK-NEXT: 0 | (AV vftable pointer) +// CHECK-NEXT: 8 | (vtordisp for vbase BV) +// CHECK-NEXT: 12 | struct BV (virtual base) +// CHECK-NEXT: 12 | struct AV (primary base) +// CHECK-NEXT: 12 | (AV vftable pointer) +// CHECK-NEXT: sizeof=16, dsize=16, align=4 +// CHECK-NEXT: nvsize=8, nvalign=4 + +// CHECK: %struct.EV = type { %struct.DV, %struct.CV.base, [4 x i8], %struct.BV } +// CHECK: %struct.EV.base = type { %struct.DV, %struct.CV.base } + +// Overriding a method means that all the vbases containing that +// method need a vtordisp. +namespace test1 { + struct A { virtual void foo(); }; + struct B : A {}; + struct C : virtual A, virtual B { C(); virtual void foo(); }; + void test() { C *c; } + +// CHECK: 0 | struct test1::C +// CHECK-NEXT: 0 | (C vbtable pointer) +// CHECK-NEXT: 4 | (vtordisp for vbase A) +// CHECK-NEXT: 8 | struct test1::A (virtual base) +// CHECK-NEXT: 8 | (A vftable pointer) +// CHECK-NEXT: 12 | (vtordisp for vbase B) +// CHECK-NEXT: 16 | struct test1::B (virtual base) +// CHECK-NEXT: 16 | struct test1::A (primary base) +// CHECK-NEXT: 16 | (A vftable pointer) +// CHECK-NEXT: sizeof=20, dsize=20, align=4 +// CHECK-NEXT: nvsize=4, nvalign=4 +} diff --git a/test/Sema/ms_wide_predefined_expr.cpp b/test/Sema/ms_wide_predefined_expr.cpp new file mode 100644 index 0000000..8e816e0 --- /dev/null +++ b/test/Sema/ms_wide_predefined_expr.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions + +// Wide character predefined identifiers +#define _STR2WSTR(str) L##str +#define STR2WSTR(str) _STR2WSTR(str) +void abcdefghi12(void) { + const wchar_t (*ss)[12] = &STR2WSTR(__FUNCTION__); + static int arr[sizeof(STR2WSTR(__FUNCTION__))==12*sizeof(wchar_t) ? 1 : -1]; +} + +namespace PR13206 { +void foo(const wchar_t *); + +template<class T> class A { +public: + void method() { + foo(L__FUNCTION__); + } +}; + +void bar() { + A<int> x; + x.method(); +} +} diff --git a/test/Sema/pragma-pack-6.c b/test/Sema/pragma-pack-6.c new file mode 100644 index 0000000..40659c2 --- /dev/null +++ b/test/Sema/pragma-pack-6.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple i686-apple-darwin9 %s -fsyntax-only -verify + +// Pragma pack handling with tag declarations + +struct X; + +#pragma pack(2) +struct X { int x; }; +struct Y; +#pragma pack() + +struct Y { int y; }; + +extern int check[__alignof(struct X) == 2 ? 1 : -1]; +extern int check[__alignof(struct Y) == 4 ? 1 : -1]; + diff --git a/test/Sema/switch.c b/test/Sema/switch.c index a7a7f60..e37d5da 100644 --- a/test/Sema/switch.c +++ b/test/Sema/switch.c @@ -9,7 +9,7 @@ void foo(int X) { switch (X) { case 42: ; // expected-note {{previous case}} case 5000000000LL: // expected-warning {{overflow}} - case 42: // expected-error {{duplicate case value}} + case 42: // expected-error {{duplicate case value '42'}} ; case 100 ... 99: ; // expected-warning {{empty case range}} @@ -320,3 +320,32 @@ void rdar110822110(Ints i) break; } } + +// PR9243 +#define TEST19MACRO 5 +void test19(int i) { + enum { + kTest19Enum1 = 7, + kTest19Enum2 = kTest19Enum1 + }; + const int a = 3; + switch (i) { + case 5: // expected-note {{previous case}} + case TEST19MACRO: // expected-error {{duplicate case value '5'}} + + case 7: // expected-note {{previous case}} + case kTest19Enum1: // expected-error {{duplicate case value: '7' and 'kTest19Enum1' both equal '7'}} \ + // expected-note {{previous case}} + case kTest19Enum1: // expected-error {{duplicate case value 'kTest19Enum1'}} \ + // expected-note {{previous case}} + case kTest19Enum2: // expected-error {{duplicate case value: 'kTest19Enum1' and 'kTest19Enum2' both equal '7'}} \ + // expected-note {{previous case}} + case (int)kTest19Enum2: //expected-error {{duplicate case value 'kTest19Enum2'}} + + case 3: // expected-note {{previous case}} + case a: // expected-error {{duplicate case value: '3' and 'a' both equal '3'}} \ + // expected-note {{previous case}} + case a: // expected-error {{duplicate case value 'a'}} + break; + } +} diff --git a/test/Sema/thread-specifier.c b/test/Sema/thread-specifier.c index 9ec88c5..0d439b1 100644 --- a/test/Sema/thread-specifier.c +++ b/test/Sema/thread-specifier.c @@ -1,19 +1,21 @@ -// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify -pedantic %s __thread int t1; -__thread extern int t2; -__thread static int t3; +__thread extern int t2; // expected-warning {{'__thread' before 'extern'}} +__thread static int t3; // expected-warning {{'__thread' before 'static'}} __thread __private_extern__ int t4; struct t5 { __thread int x; }; // expected-error {{type name does not allow storage class to be specified}} __thread int t6(); // expected-error {{'__thread' is only allowed on variable declarations}} + int f(__thread int t7) { // expected-error {{'__thread' is only allowed on variable declarations}} __thread int t8; // expected-error {{'__thread' variables must have global storage}} - __thread extern int t9; - __thread static int t10; + extern __thread int t9; + static __thread int t10; __thread __private_extern__ int t11; __thread auto int t12; // expected-error {{'__thread' variables must have global storage}} __thread register int t13; // expected-error {{'__thread' variables must have global storage}} } + __thread typedef int t14; // expected-error {{'__thread' is only allowed on variable declarations}} __thread int t15; // expected-note {{previous definition is here}} int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}} diff --git a/test/Sema/tls.c b/test/Sema/tls.c new file mode 100644 index 0000000..3b2a441 --- /dev/null +++ b/test/Sema/tls.c @@ -0,0 +1,20 @@ +// Test that TLS is correctly considered supported or unsupported for the +// different targets. + +// Linux supports TLS. +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only %s +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only %s + +// Darwin supports TLS since 10.7. +// RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only %s +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fsyntax-only %s + +// FIXME: I thought it was supported actually? +// RUN: not %clang_cc1 -triple x86_64-pc-win32 -fsyntax-only %s +// RUN: not %clang_cc1 -triple i386-pc-win32 -fsyntax-only %s + +// OpenBSD does not suppport TLS. +// RUN: not %clang_cc1 -triple x86_64-pc-openbsd -fsyntax-only %s +// RUN: not %clang_cc1 -triple i386-pc-openbsd -fsyntax-only %s + +__thread int x; diff --git a/test/Sema/typeof-use-deprecated.c b/test/Sema/typeof-use-deprecated.c index 238e501..1518c83 100644 --- a/test/Sema/typeof-use-deprecated.c +++ b/test/Sema/typeof-use-deprecated.c @@ -1,25 +1,25 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only -struct s { int a; } __attribute__((deprecated)) x; // expected-warning {{'s' is deprecated}} +struct s { int a; } __attribute__((deprecated)) x; // expected-warning {{'s' is deprecated}} expected-note 2 {{'s' declared here}} typeof(x) y; // expected-warning {{'s' is deprecated}} -union un{ int a; } __attribute__((deprecated)) u; // expected-warning {{'un' is deprecated}} +union un{ int a; } __attribute__((deprecated)) u; // expected-warning {{'un' is deprecated}} expected-note 2 {{'un' declared here}} typeof( u) z; // expected-warning {{'un' is deprecated}} -enum E{ one} __attribute__((deprecated)) e; // expected-warning {{'E' is deprecated}} +enum E{ one} __attribute__((deprecated)) e; // expected-warning {{'E' is deprecated}} expected-note 2 {{'E' declared here}} typeof( e) w; // expected-warning {{'E' is deprecated}} -struct foo { int x; } __attribute__((deprecated)); -typedef struct foo bar __attribute__((deprecated)); +struct foo { int x; } __attribute__((deprecated)); // expected-note {{'foo' declared here}} +typedef struct foo bar __attribute__((deprecated)); // expected-note {{'bar' declared here}} bar x1; // expected-warning {{'bar' is deprecated}} int main() { typeof(x1) y; } // expected-warning {{'foo' is deprecated}} struct gorf { int x; }; -typedef struct gorf T __attribute__((deprecated)); +typedef struct gorf T __attribute__((deprecated)); // expected-note {{'T' declared here}} T t; // expected-warning {{'T' is deprecated}} void wee() { typeof(t) y; } diff --git a/test/Sema/uninit-variables.c b/test/Sema/uninit-variables.c index d62186d..634ae0d 100644 --- a/test/Sema/uninit-variables.c +++ b/test/Sema/uninit-variables.c @@ -39,17 +39,19 @@ int test6() { int test7(int y) { int x; // expected-note{{initialize the variable 'x' to silence this warning}} - if (y) + if (y) // expected-warning{{variable 'x' is used uninitialized whenever 'if' condition is false}} \ + // expected-note{{remove the 'if' if its condition is always true}} x = 1; - return x; // expected-warning{{variable 'x' may be uninitialized when used here}} + return x; // expected-note{{uninitialized use occurs here}} } int test7b(int y) { int x = x; // expected-note{{variable 'x' is declared here}} if (y) x = 1; - // Warn with "may be uninitialized" here (not "is uninitialized"), since the - // self-initialization is intended to suppress a -Wuninitialized warning. + // Warn with "may be uninitialized" here (not "is sometimes uninitialized"), + // since the self-initialization is intended to suppress a -Wuninitialized + // warning. return x; // expected-warning{{variable 'x' may be uninitialized when used here}} } @@ -150,15 +152,15 @@ int test19() { int test20() { int z; // expected-note{{initialize the variable 'z' to silence this warning}} - if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z)) - return z; // expected-warning{{variable 'z' may be uninitialized when used here}} + if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z)) // expected-warning {{variable 'z' is used uninitialized whenever '||' condition is true}} expected-note {{remove the '||' if its condition is always false}} + return z; // expected-note {{uninitialized use occurs here}} return 0; } int test21(int x, int y) { int z; // expected-note{{initialize the variable 'z' to silence this warning}} - if ((x && y) || test19_aux3(&z) || test19_aux2()) - return z; // expected-warning{{variable 'z' may be uninitialized when used here}} + if ((x && y) || test19_aux3(&z) || test19_aux2()) // expected-warning {{variable 'z' is used uninitialized whenever '||' condition is true}} expected-note {{remove the '||' if its condition is always false}} + return z; // expected-note {{uninitialized use occurs here}} return 0; } @@ -293,8 +295,9 @@ int test40(int x) { int test41(int x) { int y; // expected-note{{initialize the variable 'y' to silence this warning}} - if (x) y = 1; // no-warning - return y; // expected-warning {{variable 'y' may be uninitialized when used here}} + if (x) y = 1; // expected-warning{{variable 'y' is used uninitialized whenever 'if' condition is false}} \ + // expected-note{{remove the 'if' if its condition is always true}} + return y; // expected-note{{uninitialized use occurs here}} } void test42() { @@ -424,3 +427,84 @@ void rdar9432305(float *P) { for (; i < 10000; ++i) // expected-warning {{variable 'i' is uninitialized when used here}} P[i] = 0.0f; } + +// Test that fixits are not emitted inside macros. +#define UNINIT(T, x, y) T x; T y = x; +#define ASSIGN(T, x, y) T y = x; +void test54() { + UNINIT(int, a, b); // expected-warning {{variable 'a' is uninitialized when used here}} \ + // expected-note {{variable 'a' is declared here}} + int c; // expected-note {{initialize the variable 'c' to silence this warning}} + ASSIGN(int, c, d); // expected-warning {{variable 'c' is uninitialized when used here}} +} + +// Taking the address is fine +struct { struct { void *p; } a; } test55 = { { &test55.a }}; // no-warning +struct { struct { void *p; } a; } test56 = { { &(test56.a) }}; // no-warning + +void uninit_in_loop() { + int produce(void); + void consume(int); + for (int n = 0; n < 100; ++n) { + int k; // expected-note {{initialize}} + consume(k); // expected-warning {{variable 'k' is uninitialized}} + k = produce(); + } +} + +void uninit_in_loop_goto() { + int produce(void); + void consume(int); + for (int n = 0; n < 100; ++n) { + goto skip_decl; + int k; // expected-note {{initialize}} +skip_decl: + // FIXME: This should produce the 'is uninitialized' diagnostic, but we + // don't have enough information in the CFG to easily tell that the + // variable's scope has been left and re-entered. + consume(k); // expected-warning {{variable 'k' may be uninitialized}} + k = produce(); + } +} + +typedef char jmp_buf[256]; +extern int setjmp(jmp_buf env); // implicitly returns_twice + +void do_stuff_and_longjmp(jmp_buf env, int *result) __attribute__((noreturn)); + +int returns_twice() { + int a; // expected-note {{initialize}} + if (!a) { // expected-warning {{variable 'a' is uninitialized}} + jmp_buf env; + int b; + if (setjmp(env) == 0) { + do_stuff_and_longjmp(env, &b); + } else { + a = b; // no warning + } + } + return a; +} + +int compound_assign(int *arr, int n) { + int sum; // expected-note {{initialize}} + for (int i = 0; i < n; ++i) + sum += arr[i]; // expected-warning {{variable 'sum' is uninitialized}} + return sum / n; +} + +int compound_assign_2() { + int x; // expected-note {{initialize}} + return x += 1; // expected-warning {{variable 'x' is uninitialized}} +} + +int compound_assign_3() { + int x; // expected-note {{initialize}} + x *= 0; // expected-warning {{variable 'x' is uninitialized}} + return x; +} + +int self_init_in_cond(int *p) { + int n = ((p && (0 || 1)) && (n = *p)) ? n : -1; // ok + return n; +} diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c index 9761116..056d09a 100644 --- a/test/Sema/unused-expr.c +++ b/test/Sema/unused-expr.c @@ -82,7 +82,7 @@ void t5() { int fn1() __attribute__ ((warn_unused_result)); int fn2() __attribute__ ((pure)); -int fn3() __attribute__ ((const)); +int fn3() __attribute__ ((__const)); // rdar://6587766 int t6() { if (fn1() < 0 || fn2(2,1) < 0 || fn3(2) < 0) // no warnings @@ -92,6 +92,7 @@ int t6() { fn2(92, 21); // expected-warning {{ignoring return value of function declared with pure attribute}} fn3(42); // expected-warning {{ignoring return value of function declared with const attribute}} __builtin_fabsf(0); // expected-warning {{ignoring return value of function declared with const attribute}} + (void)0, fn1(); // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}} return 0; } diff --git a/test/Sema/vector-ops.c b/test/Sema/vector-ops.c index 3ab75d0..652a076 100644 --- a/test/Sema/vector-ops.c +++ b/test/Sema/vector-ops.c @@ -13,7 +13,7 @@ void test1(v2u v2ua, v2s v2sa, v2f v2fa) { (void)(~v2fa); // expected-error{{invalid argument type 'v2f' to unary}} // Comparison operators - v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' from 'int __attribute__((ext_vector_type(2)))'}} + v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' from 'int __attribute__((ext_vector_type(2)))'}} v2sa = (v2ua==v2sa); // Arrays diff --git a/test/Sema/warn-documentation-almost-trailing.c b/test/Sema/warn-documentation-almost-trailing.c new file mode 100644 index 0000000..fa17cac --- /dev/null +++ b/test/Sema/warn-documentation-almost-trailing.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: cp %s %t +// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -fixit %t +// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -Werror %t + +struct a { + int x; //< comment // expected-warning {{not a Doxygen trailing comment}} + int y; /*< comment */ // expected-warning {{not a Doxygen trailing comment}} +}; + +// CHECK: fix-it:"{{.*}}":{8:10-8:13}:"///<" +// CHECK: fix-it:"{{.*}}":{9:10-9:13}:"/**<" + diff --git a/test/Sema/warn-documentation-fixits.cpp b/test/Sema/warn-documentation-fixits.cpp new file mode 100644 index 0000000..732b44d --- /dev/null +++ b/test/Sema/warn-documentation-fixits.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +// expected-warning@+1 {{parameter 'ZZZZZZZZZZ' not found in the function declaration}} expected-note@+1 {{did you mean 'a'?}} +/// \param ZZZZZZZZZZ Blah blah. +int test1(int a); + +// expected-warning@+1 {{parameter 'aab' not found in the function declaration}} expected-note@+1 {{did you mean 'aaa'?}} +/// \param aab Blah blah. +int test2(int aaa, int bbb); + +// expected-warning@+1 {{template parameter 'ZZZZZZZZZZ' not found in the template declaration}} expected-note@+1 {{did you mean 'T'?}} +/// \tparam ZZZZZZZZZZ Aaa +template<typename T> +void test3(T aaa); + +// expected-warning@+1 {{template parameter 'SomTy' not found in the template declaration}} expected-note@+1 {{did you mean 'SomeTy'?}} +/// \tparam SomTy Aaa +/// \tparam OtherTy Bbb +template<typename SomeTy, typename OtherTy> +void test4(SomeTy aaa, OtherTy bbb); + +// CHECK: fix-it:"{{.*}}":{5:12-5:22}:"a" +// CHECK: fix-it:"{{.*}}":{9:12-9:15}:"aaa" +// CHECK: fix-it:"{{.*}}":{13:13-13:23}:"T" +// CHECK: fix-it:"{{.*}}":{18:13-18:18}:"SomeTy" + diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp new file mode 100644 index 0000000..16ba429 --- /dev/null +++ b/test/Sema/warn-documentation.cpp @@ -0,0 +1,670 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -verify %s + +// This file contains lots of corner cases, so ensure that XML we generate is not invalid. +// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s | FileCheck %s -check-prefix=WRONG +// WRONG-NOT: CommentXMLInvalid + +// expected-warning@+1 {{expected quoted string after equals sign}} +/// <a href=> +int test_html1(int); + +// expected-warning@+1 {{expected quoted string after equals sign}} +/// <a href==> +int test_html2(int); + +// expected-warning@+2 {{expected quoted string after equals sign}} +// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} +/// <a href= blah +int test_html3(int); + +// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} +/// <a => +int test_html4(int); + +// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} +/// <a "aaa"> +int test_html5(int); + +// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} +/// <a a="b" => +int test_html6(int); + +// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} +/// <a a="b" "aaa"> +int test_html7(int); + +// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} +/// <a a="b" = +int test_html8(int); + +// expected-warning@+2 {{HTML start tag prematurely ended, expected attribute name or '>'}} expected-note@+1 {{HTML tag started here}} +/** Aaa bbb<ccc ddd eee + * fff ggg. + */ +int test_html9(int); + +// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} +/** Aaa bbb<ccc ddd eee 42% + * fff ggg. + */ +int test_html10(int); + +// expected-warning@+1 {{HTML end tag 'br' is forbidden}} +/// <br></br> +int test_html11(int); + +/// <blockquote>Meow</blockquote> +int test_html_nesting1(int); + +/// <b><i>Meow</i></b> +int test_html_nesting2(int); + +/// <p>Aaa<br> +/// Bbb</p> +int test_html_nesting3(int); + +/// <p>Aaa<br /> +/// Bbb</p> +int test_html_nesting4(int); + +// expected-warning@+1 {{HTML end tag does not match any start tag}} +/// <b><i>Meow</a> +int test_html_nesting5(int); + +// expected-warning@+2 {{HTML start tag 'i' closed by 'b'}} +// expected-warning@+1 {{HTML end tag does not match any start tag}} +/// <b><i>Meow</b></b> +int test_html_nesting6(int); + +// expected-warning@+2 {{HTML start tag 'i' closed by 'b'}} +// expected-warning@+1 {{HTML end tag does not match any start tag}} +/// <b><i>Meow</b></i> +int test_html_nesting7(int); + + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\returns Aaa +int test_block_command1(int); + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief \returns Aaa +int test_block_command2(int); + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief +/// \returns Aaa +int test_block_command3(int); + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief +/// +/// \returns Aaa +int test_block_command4(int); + +// There is trailing whitespace on one of the following lines, don't remove it! +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief +/// +/// \returns Aaa +int test_block_command5(int); + +/// \brief \c Aaa +int test_block_command6(int); + +// expected-warning@+5 {{duplicated command '\brief'}} expected-note@+1 {{previous command '\brief' here}} +/// \brief Aaa +/// +/// Bbb +/// +/// \brief Ccc +int test_duplicate_brief1(int); + +// expected-warning@+5 {{duplicated command '\short'}} expected-note@+1 {{previous command '\short' here}} +/// \short Aaa +/// +/// Bbb +/// +/// \short Ccc +int test_duplicate_brief2(int); + +// expected-warning@+5 {{duplicated command '\brief'}} expected-note@+1 {{previous command '\short' (an alias of '\brief') here}} +/// \short Aaa +/// +/// Bbb +/// +/// \brief Ccc +int test_duplicate_brief3(int); + + +// expected-warning@+5 {{duplicated command '\return'}} expected-note@+1 {{previous command '\return' here}} +/// \return Aaa +/// +/// Bbb +/// +/// \return Ccc +int test_duplicate_returns1(int); + +// expected-warning@+5 {{duplicated command '\returns'}} expected-note@+1 {{previous command '\returns' here}} +/// \returns Aaa +/// +/// Bbb +/// +/// \returns Ccc +int test_duplicate_returns2(int); + +// expected-warning@+5 {{duplicated command '\result'}} expected-note@+1 {{previous command '\result' here}} +/// \result Aaa +/// +/// Bbb +/// +/// \result Ccc +int test_duplicate_returns3(int); + +// expected-warning@+5 {{duplicated command '\return'}} expected-note@+1 {{previous command '\returns' (an alias of '\return') here}} +/// \returns Aaa +/// +/// Bbb +/// +/// \return Ccc +int test_duplicate_returns4(int); + + +// expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}} +/// \param a Blah blah. +int test_param1; + +// expected-warning@+1 {{empty paragraph passed to '\param' command}} +/// \param +/// \param a Blah blah. +int test_param2(int a); + +// expected-warning@+1 {{empty paragraph passed to '\param' command}} +/// \param a +int test_param3(int a); + +/// \param a Blah blah. +int test_param4(int a); + +/// \param [in] a Blah blah. +int test_param5(int a); + +/// \param [out] a Blah blah. +int test_param6(int a); + +/// \param [in,out] a Blah blah. +int test_param7(int a); + +// expected-warning@+1 {{whitespace is not allowed in parameter passing direction}} +/// \param [ in ] a Blah blah. +int test_param8(int a); + +// expected-warning@+1 {{whitespace is not allowed in parameter passing direction}} +/// \param [in, out] a Blah blah. +int test_param9(int a); + +// expected-warning@+1 {{unrecognized parameter passing direction, valid directions are '[in]', '[out]' and '[in,out]'}} +/// \param [ junk] a Blah blah. +int test_param10(int a); + +// expected-warning@+1 {{parameter 'a' not found in the function declaration}} +/// \param a Blah blah. +int test_param11(); + +// expected-warning@+1 {{parameter 'A' not found in the function declaration}} expected-note@+1 {{did you mean 'a'?}} +/// \param A Blah blah. +int test_param12(int a); + +// expected-warning@+1 {{parameter 'aab' not found in the function declaration}} expected-note@+1 {{did you mean 'aaa'?}} +/// \param aab Blah blah. +int test_param13(int aaa, int bbb); + +// expected-warning@+1 {{parameter 'aab' not found in the function declaration}} +/// \param aab Blah blah. +int test_param14(int bbb, int ccc); + +class C { + // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}} + /// \param aaa Blah blah. + C(int bbb, int ccc); + + // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}} + /// \param aaa Blah blah. + int test_param15(int bbb, int ccc); +}; + +// expected-warning@+1 {{parameter 'aab' not found in the function declaration}} +/// \param aab Blah blah. +template<typename T> +void test_param16(int bbb, int ccc); + +// expected-warning@+3 {{parameter 'a' is already documented}} +// expected-note@+1 {{previous documentation}} +/// \param a Aaa. +/// \param a Aaa. +int test_param17(int a); + +// expected-warning@+4 {{parameter 'x2' is already documented}} +// expected-note@+2 {{previous documentation}} +/// \param x1 Aaa. +/// \param x2 Bbb. +/// \param x2 Ccc. +int test_param18(int x1, int x2, int x3); + + +// expected-warning@+1 {{'\tparam' command used in a comment that is not attached to a template declaration}} +/// \tparam T Aaa +int test_tparam1; + +// expected-warning@+1 {{'\tparam' command used in a comment that is not attached to a template declaration}} +/// \tparam T Aaa +void test_tparam2(int aaa); + +// expected-warning@+1 {{empty paragraph passed to '\tparam' command}} +/// \tparam +/// \param aaa Blah blah +template<typename T> +void test_tparam3(T aaa); + +// expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TT'?}} +/// \tparam T Aaa +template<typename TT> +void test_tparam4(TT aaa); + +// expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TT'?}} +/// \tparam T Aaa +template<typename TT> +class test_tparam5 { + // expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TTT'?}} + /// \tparam T Aaa + template<typename TTT> + void test_tparam6(TTT aaa); +}; + +/// \tparam T1 Aaa +/// \tparam T2 Bbb +template<typename T1, typename T2> +void test_tparam7(T1 aaa, T2 bbb); + +// expected-warning@+1 {{template parameter 'SomTy' not found in the template declaration}} expected-note@+1 {{did you mean 'SomeTy'?}} +/// \tparam SomTy Aaa +/// \tparam OtherTy Bbb +template<typename SomeTy, typename OtherTy> +void test_tparam8(SomeTy aaa, OtherTy bbb); + +// expected-warning@+2 {{template parameter 'T1' is already documented}} expected-note@+1 {{previous documentation}} +/// \tparam T1 Aaa +/// \tparam T1 Bbb +template<typename T1, typename T2> +void test_tparam9(T1 aaa, T2 bbb); + +/// \tparam T Aaa +/// \tparam TT Bbb +template<template<typename T> class TT> +void test_tparam10(TT<int> aaa); + +/// \tparam T Aaa +/// \tparam TT Bbb +/// \tparam TTT Ccc +template<template<template<typename T> class TT, class C> class TTT> +void test_tparam11(); + +/// \tparam I Aaa +template<int I> +void test_tparam12(); + +template<typename T, typename U> +class test_tparam13 { }; + +/// \tparam T Aaa +template<typename T> +using test_tparam14 = test_tparam13<T, int>; + +// expected-warning@+1 {{template parameter 'U' not found in the template declaration}} expected-note@+1 {{did you mean 'T'?}} +/// \tparam U Aaa +template<typename T> +using test_tparam15 = test_tparam13<T, int>; + +// no-warning +/// \returns Aaa +int test_returns_right_decl_1(int); + +class test_returns_right_decl_2 { + // no-warning + /// \returns Aaa + int test_returns_right_decl_3(int); +}; + +// no-warning +/// \returns Aaa +template<typename T> +int test_returns_right_decl_4(T aaa); + +// no-warning +/// \returns Aaa +template<> +int test_returns_right_decl_4(int aaa); + +/// \returns Aaa +template<typename T> +T test_returns_right_decl_5(T aaa); + +// expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} +/// \returns Aaa +int test_returns_wrong_decl_1; + +// expected-warning@+1 {{'\return' command used in a comment that is not attached to a function or method declaration}} +/// \return Aaa +int test_returns_wrong_decl_2; + +// expected-warning@+1 {{'\result' command used in a comment that is not attached to a function or method declaration}} +/// \result Aaa +int test_returns_wrong_decl_3; + +// expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}} +/// \returns Aaa +void test_returns_wrong_decl_4(int); + +// expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}} +/// \returns Aaa +template<typename T> +void test_returns_wrong_decl_5(T aaa); + +// expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}} +/// \returns Aaa +template<> +void test_returns_wrong_decl_5(int aaa); + +// expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} +/// \returns Aaa +struct test_returns_wrong_decl_6 { }; + +// expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} +/// \returns Aaa +class test_returns_wrong_decl_7 { + // expected-warning@+1 {{'\returns' command used in a comment that is attached to a constructor}} + /// \returns Aaa + test_returns_wrong_decl_7(); + + // expected-warning@+1 {{'\returns' command used in a comment that is attached to a destructor}} + /// \returns Aaa + ~test_returns_wrong_decl_7(); +}; + +// expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} +/// \returns Aaa +enum test_returns_wrong_decl_8 { + // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} + /// \returns Aaa + test_returns_wrong_decl_9 +}; + +// expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} +/// \returns Aaa +namespace test_returns_wrong_decl_10 { }; + + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +int test1; ///< \brief\author Aaa + +// expected-warning@+2 {{empty paragraph passed to '\brief' command}} +// expected-warning@+2 {{empty paragraph passed to '\brief' command}} +int test2, ///< \brief\author Aaa + test3; ///< \brief\author Aaa + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +int test4; ///< \brief + ///< \author Aaa + + +// Check that we attach the comment to the declaration during parsing in the +// following cases. The test is based on the fact that we don't parse +// documentation comments that are not attached to anything. + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +int test_attach1; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +int test_attach2(int); + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +struct test_attach3 { + // expected-warning@+1 {{empty paragraph passed to '\brief' command}} + /// \brief\author Aaa + int test_attach4; + + // expected-warning@+1 {{empty paragraph passed to '\brief' command}} + int test_attach5; ///< \brief\author Aaa + + // expected-warning@+1 {{empty paragraph passed to '\brief' command}} + /// \brief\author Aaa + int test_attach6(int); +}; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +class test_attach7 { + // expected-warning@+1 {{empty paragraph passed to '\brief' command}} + /// \brief\author Aaa + int test_attach8; + + // expected-warning@+1 {{empty paragraph passed to '\brief' command}} + int test_attach9; ///< \brief\author Aaa + + // expected-warning@+1 {{empty paragraph passed to '\brief' command}} + /// \brief\author Aaa + int test_attach10(int); +}; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +enum test_attach9 { + // expected-warning@+1 {{empty paragraph passed to '\brief' command}} + /// \brief\author Aaa + test_attach10, + + // expected-warning@+1 {{empty paragraph passed to '\brief' command}} + test_attach11 ///< \brief\author Aaa +}; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +struct test_noattach12 *test_attach13; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +typedef struct test_noattach14 *test_attach15; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +typedef struct test_attach16 { int a; } test_attach17; + +struct S { int a; }; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +struct S *test_attach18; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +typedef struct S *test_attach19; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +struct test_attach20; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +typedef struct test_attach21 { + // expected-warning@+1 {{empty paragraph passed to '\brief' command}} + /// \brief\author Aaa + int test_attach22; +} test_attach23; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +namespace test_attach24 { + // expected-warning@+1 {{empty paragraph passed to '\brief' command}} + /// \brief\author Aaa + namespace test_attach25 { + } +} + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +/// \tparam T Aaa +template<typename T> +void test_attach26(T aaa); + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +/// \tparam T Aaa +template<typename T, typename U> +void test_attach27(T aaa, U bbb); + +// expected-warning@+2 {{empty paragraph passed to '\brief' command}} +// expected-warning@+2 {{template parameter 'T' not found in the template declaration}} +/// \brief\author Aaa +/// \tparam T Aaa +template<> +void test_attach27(int aaa, int bbb); + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +/// \tparam T Aaa +template<typename T> +class test_attach28 { + T aaa; +}; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +using test_attach29 = test_attach28<int>; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +/// \tparam T Aaa +template<typename T, typename U> +class test_attach30 { }; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +/// \tparam T Aaa +template<typename T> +class test_attach30<T, int> { }; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +template<> +class test_attach30<int, int> { }; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +template<typename T> +using test_attach31 = test_attach30<T, int>; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +/// \tparam T Aaa +template<typename T, typename U, typename V> +class test_attach32 { }; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +/// \tparam T Aaa +template<typename T, typename U> +class test_attach32<T, U, int> { }; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +/// \tparam T Aaa +template<typename T> +class test_attach32<T, int, int> { }; + +// expected-warning@+2 {{empty paragraph passed to '\brief' command}} +// expected-warning@+2 {{template parameter 'T' not found in the template declaration}} +/// \brief\author Aaa +/// \tparam T Aaa +template<> +class test_attach32<int, int, int> { }; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +class test_attach33 { + // expected-warning@+1 {{empty paragraph passed to '\brief' command}} + /// \brief\author Aaa + /// \tparam T Aaa + template<typename T, typename U> + void test_attach34(T aaa, U bbb); +}; + +template<typename T> +class test_attach35 { + // expected-warning@+2 {{empty paragraph passed to '\brief' command}} + // expected-warning@+2 {{template parameter 'T' not found in the template declaration}} + /// \brief\author Aaa + /// \tparam T Aaa + template<typename TT, typename UU> + void test_attach36(TT aaa, UU bbb); +}; + +// expected-warning@+2 {{empty paragraph passed to '\brief' command}} +// expected-warning@+2 {{template parameter 'T' not found in the template declaration}} +/// \brief\author Aaa +/// \tparam T Aaa +template<> template<> +void test_attach35<int>::test_attach36(int aaa, int bbb) {} + +template<typename T> +class test_attach37 { + // expected-warning@+2 {{empty paragraph passed to '\brief' command}} + // expected-warning@+2 {{'\tparam' command used in a comment that is not attached to a template declaration}} + /// \brief\author Aaa + /// \tparam T Aaa + void test_attach38(int aaa, int bbb); +}; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +/// \tparam T Aaa +template<typename T> +void test_attach37<T>::test_attach38(int aaa, int bbb) {} + +// expected-warning@+2 {{empty paragraph passed to '\brief' command}} +// expected-warning@+2 {{template parameter 'T' not found in the template declaration}} +/// \brief\author Aaa +/// \tparam T Aaa +template<> +void test_attach37<int>::test_attach38(int aaa, int bbb) {} + + +// PR13411, reduced. We used to crash on this. +/** + * @code Aaa. + */ +void test_nocrash1(int); + +// We used to crash on this. +// expected-warning@+2 {{empty paragraph passed to '\param' command}} +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \param\brief +void test_nocrash2(int); + +// PR13593 + +/** +* Bla. +*/ +template <typename> +void test_nocrash3(); + +/// Foo +template <typename, typename> +void test_nocrash4() { } + +template <typename> +void test_nocrash3() +{ +} diff --git a/test/Sema/warn-documentation.m b/test/Sema/warn-documentation.m new file mode 100644 index 0000000..d6af6ed --- /dev/null +++ b/test/Sema/warn-documentation.m @@ -0,0 +1,93 @@ +// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -Wdocumentation -Wdocumentation-pedantic -verify %s + +@class NSString; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +@interface Test1 +// expected-warning@+2 {{empty paragraph passed to '\brief' command}} +/** + * \brief\author Aaa + * \param aaa Aaa + * \param bbb Bbb + */ ++ (NSString *)test1:(NSString *)aaa suffix:(NSString *)bbb; + +// expected-warning@+2 {{parameter 'aab' not found in the function declaration}} expected-note@+2 {{did you mean 'aaa'?}} +/** + * \param aab Aaa + */ ++ (NSString *)test2:(NSString *)aaa; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +@property int test3; // a property: ObjCPropertyDecl + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +@property int test4; // a property: ObjCPropertyDecl +@end + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +@interface Test1() +@end + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +@implementation Test1 // a class implementation : ObjCImplementationDecl ++ (NSString *)test1:(NSString *)aaa suffix:(NSString *)bbb { + return 0; +} + ++ (NSString *)test2:(NSString *)aaa { + return 0; +} + +@synthesize test3; // a property implementation: ObjCPropertyImplDecl +@dynamic test4; // a property implementation: ObjCPropertyImplDecl + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +NSString *_test5; +@end + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +@interface Test1(Test1Category) // a category: ObjCCategoryDecl +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa ++ (NSString *)test3:(NSString *)aaa; +@end + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +@implementation Test1(Test1Category) // a category implementation: ObjCCategoryImplDecl ++ (NSString *)test3:(NSString *)aaa { + return 0; +} +@end + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +@protocol TestProto1 // a protocol: ObjCProtocolDecl +@end + +int a; + +// expected-warning@+1 {{empty paragraph passed to '\brief' command}} +/// \brief\author Aaa +@interface Test4 +@end + +int b; + +@interface TestReturns1 +/// \returns Aaa +- (int)test1:(NSString *)aaa; + +// expected-warning@+1 {{'\returns' command used in a comment that is attached to a method returning void}} +/// \returns Aaa +- (void)test2:(NSString *)aaa; +@end + diff --git a/test/Sema/warn-outof-range-assign-enum.c b/test/Sema/warn-outof-range-assign-enum.c new file mode 100644 index 0000000..2e79e66 --- /dev/null +++ b/test/Sema/warn-outof-range-assign-enum.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wassign-enum %s +// rdar://11824807 + +typedef enum CCTestEnum +{ + One, + Two=4, + Three +} CCTestEnum; + +CCTestEnum test = 50; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}} +CCTestEnum test1 = -50; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}} + +CCTestEnum foo(CCTestEnum r) { + return 20; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}} +} + +enum Test2 { K_zero, K_one }; +enum Test2 test2(enum Test2 *t) { + *t = 20; // expected-warning {{integer constant not in range of enumerated type 'enum Test2'}} + return 10; // expected-warning {{integer constant not in range of enumerated type 'enum Test2'}} +} + +int main() { + CCTestEnum test = 1; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}} + test = 600; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}} + foo(2); // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}} + foo(-1); // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}} + foo(4); + foo(Two+1); +} + diff --git a/test/Sema/warn-self-assign-field.mm b/test/Sema/warn-self-assign-field.mm new file mode 100644 index 0000000..3ba8d62 --- /dev/null +++ b/test/Sema/warn-self-assign-field.mm @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s + +class S { + public: + int a_; + void s(int a) { + a_ = a_; // expected-warning {{assigning field to itself}} + + // Don't really care about this one either way. + this->a_ = a_; // expected-warning {{assigning field to itself}} + + a_ += a_; // Shouldn't warn. + } +}; + +void f0(S* s) { + // Would be nice to have, but not important. + s->a_ = s->a_; +} + +void f1(S* s, S* t) { + // Shouldn't warn. + t->a_ = s->a_; +} + +struct T { + S* s_; +}; + +void f2(T* t) { + // Would be nice to have, but even less important. + t->s_->a_ = t->s_->a_; +} + +void f3(T* t, T* t2) { + // Shouldn't warn. + t2->s_->a_ = t->s_->a_; +} + +void f4(int i) { + // This is a common pattern to silence "parameter unused". Shouldn't warn. + i = i; + + int j = 0; + j = j; // Likewise. +} + +@interface I { + int a_; +} +@end + +@implementation I +- (void)setA:(int)a { + a_ = a_; // expected-warning {{assigning instance variable to itself}} +} + +- (void)foo:(I*)i { + // Don't care much about this warning. + i->a_ = i->a_; // expected-warning {{assigning instance variable to itself}} + + // Shouldn't warn. + a_ = i->a_; + i->a_ = a_; +} +@end diff --git a/test/Sema/warn-strncat-size.c b/test/Sema/warn-strncat-size.c index 7157edf..dcc3367 100644 --- a/test/Sema/warn-strncat-size.c +++ b/test/Sema/warn-strncat-size.c @@ -59,7 +59,7 @@ void size_1() { char z[1]; char str[] = "hi"; - strncat(z, str, sizeof(z)); // expected-warning{{the value of the size argument in 'strncat' is too large, might lead to a buffer overflow}} + strncat(z, str, sizeof(z)); // expected-warning{{the value of the size argument to 'strncat' is wrong}} } // Support VLAs. @@ -69,3 +69,8 @@ void vlas(int size) { strncat(z, str, sizeof(str)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}} } + +// Non-array type gets a different error message. +void f(char* s, char* d) { + strncat(d, s, sizeof(d)); // expected-warning {{the value of the size argument to 'strncat' is wrong}} +} |