summaryrefslogtreecommitdiffstats
path: root/test/Sema
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
committerdim <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
commit554bcb69c2d785a011a30e7db87a36a87fe7db10 (patch)
tree9abb1a658a297776086f4e0dfa6ca533de02104e /test/Sema
parentbb67ca86b31f67faee50bd10c3b036d65751745a (diff)
downloadFreeBSD-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')
-rw-r--r--test/Sema/128bitint.c9
-rw-r--r--test/Sema/Inputs/format-unused-system-args.h8
-rw-r--r--test/Sema/MicrosoftCompatibility.c7
-rw-r--r--test/Sema/MicrosoftExtensions.c8
-rw-r--r--test/Sema/alignas.c13
-rw-r--r--test/Sema/alloc_size.c26
-rw-r--r--test/Sema/annotate.c5
-rw-r--r--test/Sema/array-bounds-ptr-arith.c18
-rw-r--r--test/Sema/array-init.c2
-rw-r--r--test/Sema/attr-aligned.c2
-rw-r--r--test/Sema/attr-availability-ios.c8
-rw-r--r--test/Sema/attr-availability-macosx.c2
-rw-r--r--test/Sema/attr-availability.c21
-rw-r--r--test/Sema/attr-coldhot.c10
-rw-r--r--test/Sema/attr-decl-after-definition.c22
-rw-r--r--test/Sema/attr-deprecated-message.c8
-rw-r--r--test/Sema/attr-deprecated.c29
-rw-r--r--test/Sema/attr-nodebug.c7
-rw-r--r--test/Sema/attr-section.c4
-rw-r--r--test/Sema/attr-tls_model.c14
-rw-r--r--test/Sema/attr-unavailable-message.c4
-rw-r--r--test/Sema/attr-visibility.c15
-rw-r--r--test/Sema/c89-2.c2
-rw-r--r--test/Sema/compare.c7
-rw-r--r--test/Sema/conditional-expr.c2
-rw-r--r--test/Sema/const-eval.c3
-rw-r--r--test/Sema/dllimport-dllexport.c6
-rw-r--r--test/Sema/exprs.c15
-rw-r--r--test/Sema/format-strings-enum-fixed-type.cpp92
-rw-r--r--test/Sema/format-strings-enum.c36
-rw-r--r--test/Sema/format-strings-fixit.c34
-rw-r--r--test/Sema/format-strings-scanf.c55
-rw-r--r--test/Sema/format-strings-size_t.c13
-rw-r--r--test/Sema/format-strings.c117
-rw-r--r--test/Sema/fpack-struct.c4
-rw-r--r--test/Sema/implicit-builtin-decl.c2
-rw-r--r--test/Sema/inline.c72
-rw-r--r--test/Sema/invalid-decl.c9
-rw-r--r--test/Sema/knr-def-call.c4
-rw-r--r--test/Sema/ms_class_layout.cpp173
-rw-r--r--test/Sema/ms_wide_predefined_expr.cpp25
-rw-r--r--test/Sema/pragma-pack-6.c16
-rw-r--r--test/Sema/switch.c31
-rw-r--r--test/Sema/thread-specifier.c12
-rw-r--r--test/Sema/tls.c20
-rw-r--r--test/Sema/typeof-use-deprecated.c12
-rw-r--r--test/Sema/uninit-variables.c104
-rw-r--r--test/Sema/unused-expr.c3
-rw-r--r--test/Sema/vector-ops.c2
-rw-r--r--test/Sema/warn-documentation-almost-trailing.c14
-rw-r--r--test/Sema/warn-documentation-fixits.cpp27
-rw-r--r--test/Sema/warn-documentation.cpp670
-rw-r--r--test/Sema/warn-documentation.m93
-rw-r--r--test/Sema/warn-outof-range-assign-enum.c32
-rw-r--r--test/Sema/warn-self-assign-field.mm66
-rw-r--r--test/Sema/warn-strncat-size.c7
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}}
+}
OpenPOWER on IntegriCloud