summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Analysis/CFNumber.c6
-rw-r--r--test/Analysis/CheckNSError.m4
-rw-r--r--test/Analysis/array-struct.c2
-rw-r--r--test/Analysis/ctor-inlining.mm48
-rw-r--r--test/Analysis/dtor.cpp54
-rw-r--r--test/Analysis/func.c14
-rw-r--r--test/Analysis/html-diags.c6
-rw-r--r--test/Analysis/inline.cpp27
-rw-r--r--test/Analysis/inlining/DynDispatchBifurcate.m10
-rw-r--r--test/Analysis/inlining/InlineObjCClassMethod.m30
-rw-r--r--test/Analysis/inlining/dyn-dispatch-bifurcate.cpp17
-rw-r--r--test/Analysis/keychainAPI.m6
-rw-r--r--test/Analysis/malloc-annotations.c4
-rw-r--r--test/Analysis/malloc.c6
-rw-r--r--test/Analysis/method-call-path-notes.cpp85
-rw-r--r--test/Analysis/method-call.cpp20
-rw-r--r--test/Analysis/misc-ps-region-store.m2
-rw-r--r--test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m4
-rw-r--r--test/Analysis/ptr-arith.c6
-rw-r--r--test/Analysis/reinterpret-cast.cpp20
-rw-r--r--test/Analysis/security-syntax-checks.m8
-rw-r--r--test/Analysis/sizeofpointer.c2
-rw-r--r--test/Analysis/stack-addr-ps.cpp2
-rw-r--r--test/Analysis/stream.c16
-rw-r--r--test/Analysis/variadic-method-types.m2
-rw-r--r--test/CodeCompletion/objc-expr.m2
-rw-r--r--test/CodeGen/align-global-large.c18
-rw-r--r--test/CodeGen/alignment.c3
-rw-r--r--test/CodeGen/arm-neon-misc.c34
-rw-r--r--test/CodeGen/complex-builtints.c71
-rw-r--r--test/CodeGen/ms-inline-asm.c86
-rw-r--r--test/CodeGenCXX/devirtualize-virtual-function-calls.cpp17
-rw-r--r--test/CodeGenObjC/instance-method-metadata.m10
-rw-r--r--test/CodeGenObjC/ns_consume_null_check.m8
-rw-r--r--test/CodeGenOpenCL/vectorLoadStore.cl9
-rw-r--r--test/Driver/Xlinker-args.c11
-rw-r--r--test/Index/complete-enums.cpp4
-rw-r--r--test/Index/complete-exprs.m4
-rw-r--r--test/Index/complete-preamble.cpp8
-rw-r--r--test/Index/complete-preamble.h6
-rw-r--r--test/Parser/ms-inline-asm.c6
-rw-r--r--test/Sema/128bitint.c19
-rw-r--r--test/Sema/arm-asm.c7
-rw-r--r--test/Sema/builtins-decl.c5
-rw-r--r--test/Sema/callingconv.c8
-rw-r--r--test/Sema/static-array.c46
-rw-r--r--test/Sema/tentative-decls.c5
-rw-r--r--test/Sema/warn-documentation.cpp60
-rw-r--r--test/Sema/warn-type-safety-mpi-hdf5.c307
-rw-r--r--test/Sema/warn-type-safety.c152
-rw-r--r--test/Sema/warn-type-safety.cpp71
-rw-r--r--test/SemaCXX/convert-to-bool.cpp3
-rw-r--r--test/SemaCXX/pragma-pack.cpp23
-rw-r--r--test/SemaCXX/references.cpp2
-rw-r--r--test/SemaCXX/uninitialized.cpp81
-rw-r--r--test/SemaCXX/warn-thread-safety-parsing.cpp10
-rw-r--r--test/SemaObjC/warn-cast-of-sel-expr.m21
-rw-r--r--test/SemaObjCXX/abstract-class-type-ivar.mm29
-rw-r--r--test/Tooling/clang-check-ast-dump.cpp5
59 files changed, 1459 insertions, 93 deletions
diff --git a/test/Analysis/CFNumber.c b/test/Analysis/CFNumber.c
index fbbe4d15f49f..537e49785130 100644
--- a/test/Analysis/CFNumber.c
+++ b/test/Analysis/CFNumber.c
@@ -17,11 +17,11 @@ typedef const struct __CFNumber * CFNumberRef;
extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
CFNumberRef f1(unsigned char x) {
- return CFNumberCreate(0, kCFNumberSInt16Type, &x); // expected-warning{{An 8 bit integer is used to initialize a CFNumber object that represents a 16 bit integer. 8 bits of the CFNumber value will be garbage.}}
+ return CFNumberCreate(0, kCFNumberSInt16Type, &x); // expected-warning{{An 8 bit integer is used to initialize a CFNumber object that represents a 16 bit integer. 8 bits of the CFNumber value will be garbage}}
}
__attribute__((cf_returns_retained)) CFNumberRef f2(unsigned short x) {
- return CFNumberCreate(0, kCFNumberSInt8Type, &x); // expected-warning{{A 16 bit integer is used to initialize a CFNumber object that represents an 8 bit integer. 8 bits of the input integer will be lost.}}
+ return CFNumberCreate(0, kCFNumberSInt8Type, &x); // expected-warning{{A 16 bit integer is used to initialize a CFNumber object that represents an 8 bit integer. 8 bits of the input integer will be lost}}
}
// test that the attribute overrides the naming convention.
@@ -30,5 +30,5 @@ __attribute__((cf_returns_not_retained)) CFNumberRef CreateNum(unsigned char x)
}
CFNumberRef f3(unsigned i) {
- return CFNumberCreate(0, kCFNumberLongType, &i); // expected-warning{{A 32 bit integer is used to initialize a CFNumber object that represents a 64 bit integer.}}
+ return CFNumberCreate(0, kCFNumberLongType, &i); // expected-warning{{A 32 bit integer is used to initialize a CFNumber object that represents a 64 bit integer}}
}
diff --git a/test/Analysis/CheckNSError.m b/test/Analysis/CheckNSError.m
index d35b686ef1d9..cdec1d50f2ca 100644
--- a/test/Analysis/CheckNSError.m
+++ b/test/Analysis/CheckNSError.m
@@ -23,7 +23,7 @@ extern NSString * const NSXMLParserErrorDomain ;
@implementation A
- (void)myMethodWhichMayFail:(NSError **)error { // expected-warning {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occurred}}
- *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference.}}
+ *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference}}
}
- (BOOL)myMethodWhichMayFail2:(NSError **)error { // no-warning
@@ -36,7 +36,7 @@ struct __CFError {};
typedef struct __CFError* CFErrorRef;
void foo(CFErrorRef* error) { // expected-warning {{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occurred}}
- *error = 0; // expected-warning {{Potential null dereference.}}
+ *error = 0; // expected-warning {{Potential null dereference}}
}
int f1(CFErrorRef* error) {
diff --git a/test/Analysis/array-struct.c b/test/Analysis/array-struct.c
index c5bdb86a14ed..1b36190729b5 100644
--- a/test/Analysis/array-struct.c
+++ b/test/Analysis/array-struct.c
@@ -151,7 +151,7 @@ struct s3 p[1];
// an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and
// assigns to 'a'.
void f16(struct s3 *p) {
- struct s3 a = *((struct s3*) ((char*) &p[0])); // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}}
+ struct s3 a = *((struct s3*) ((char*) &p[0])); // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}}
}
void inv(struct s1 *);
diff --git a/test/Analysis/ctor-inlining.mm b/test/Analysis/ctor-inlining.mm
index 54d51b46dc5e..fe4781c16e28 100644
--- a/test/Analysis/ctor-inlining.mm
+++ b/test/Analysis/ctor-inlining.mm
@@ -39,3 +39,51 @@ void testNonPODCopyConstructor() {
clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
}
+
+namespace ConstructorVirtualCalls {
+ class A {
+ public:
+ int *out1, *out2, *out3;
+
+ virtual int get() { return 1; }
+
+ A(int *out1) {
+ *out1 = get();
+ }
+ };
+
+ class B : public A {
+ public:
+ virtual int get() { return 2; }
+
+ B(int *out1, int *out2) : A(out1) {
+ *out2 = get();
+ }
+ };
+
+ class C : public B {
+ public:
+ virtual int get() { return 3; }
+
+ C(int *out1, int *out2, int *out3) : B(out1, out2) {
+ *out3 = get();
+ }
+ };
+
+ void test() {
+ int a, b, c;
+
+ C obj(&a, &b, &c);
+ clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
+
+ clang_analyzer_eval(obj.get() == 3); // expected-warning{{TRUE}}
+
+ // Sanity check for devirtualization.
+ A *base = &obj;
+ clang_analyzer_eval(base->get() == 3); // expected-warning{{TRUE}}
+ }
+}
+
+
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
index 620994858c7c..1f45925561c9 100644
--- a/test/Analysis/dtor.cpp
+++ b/test/Analysis/dtor.cpp
@@ -173,3 +173,57 @@ void testDefaultArg() {
// Force a bug to be emitted.
*(char *)0 = 1; // expected-warning{{Dereference of null pointer}}
}
+
+
+namespace DestructorVirtualCalls {
+ class A {
+ public:
+ int *out1, *out2, *out3;
+
+ virtual int get() { return 1; }
+
+ ~A() {
+ *out1 = get();
+ }
+ };
+
+ class B : public A {
+ public:
+ virtual int get() { return 2; }
+
+ ~B() {
+ *out2 = get();
+ }
+ };
+
+ class C : public B {
+ public:
+ virtual int get() { return 3; }
+
+ ~C() {
+ *out3 = get();
+ }
+ };
+
+ void test() {
+ int a, b, c;
+
+ // New scope for the C object.
+ {
+ C obj;
+ clang_analyzer_eval(obj.get() == 3); // expected-warning{{TRUE}}
+
+ // Sanity check for devirtualization.
+ A *base = &obj;
+ clang_analyzer_eval(base->get() == 3); // expected-warning{{TRUE}}
+
+ obj.out1 = &a;
+ obj.out2 = &b;
+ obj.out3 = &c;
+ }
+
+ clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
+ }
+}
diff --git a/test/Analysis/func.c b/test/Analysis/func.c
index b6cebde81091..709ebf779376 100644
--- a/test/Analysis/func.c
+++ b/test/Analysis/func.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -verify %s
+
+void clang_analyzer_eval(int);
void f(void) {
void (*p)(void);
@@ -13,3 +15,13 @@ void g(void (*fp)(void));
void f2() {
g(f);
}
+
+void f3(void (*f)(void), void (*g)(void)) {
+ clang_analyzer_eval(!f); // expected-warning{{UNKNOWN}}
+ f();
+ clang_analyzer_eval(!f); // expected-warning{{FALSE}}
+
+ clang_analyzer_eval(!g); // expected-warning{{UNKNOWN}}
+ (*g)();
+ clang_analyzer_eval(!g); // expected-warning{{FALSE}}
+}
diff --git a/test/Analysis/html-diags.c b/test/Analysis/html-diags.c
index b9361f72c64c..7c15df65d750 100644
--- a/test/Analysis/html-diags.c
+++ b/test/Analysis/html-diags.c
@@ -1,6 +1,6 @@
-// RUN: mkdir %t.dir
-// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %t.dir %s
-// RUN: rm -fR %t.dir
+// RUN: mkdir %T/dir
+// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %T/dir %s
+// RUN: rm -fR %T/dir
// Currently this test mainly checks that the HTML diagnostics doesn't crash
// when handling macros will calls with macros. We should actually validate
diff --git a/test/Analysis/inline.cpp b/test/Analysis/inline.cpp
index 4eaed9fed13c..6b9a885f50f3 100644
--- a/test/Analysis/inline.cpp
+++ b/test/Analysis/inline.cpp
@@ -166,3 +166,30 @@ namespace PR13569_virtual {
x.interface();
}
}
+
+namespace Invalidation {
+ struct X {
+ void touch(int &x) const {
+ x = 0;
+ }
+
+ void touch2(int &x) const;
+
+ virtual void touchV(int &x) const {
+ x = 0;
+ }
+
+ virtual void touchV2(int &x) const;
+
+ int test() const {
+ // We were accidentally not invalidating under -analyzer-ipa=inlining
+ // at one point for virtual methods with visible definitions.
+ int a, b, c, d;
+ touch(a);
+ touch2(b);
+ touchV(c);
+ touchV2(d);
+ return a + b + c + d; // no-warning
+ }
+ };
+}
diff --git a/test/Analysis/inlining/DynDispatchBifurcate.m b/test/Analysis/inlining/DynDispatchBifurcate.m
index e78b90bb8c1f..6637dfdba571 100644
--- a/test/Analysis/inlining/DynDispatchBifurcate.m
+++ b/test/Analysis/inlining/DynDispatchBifurcate.m
@@ -160,17 +160,17 @@ int testCallToPublicAPICat(PublicSubClass *p) {
// weither they are "public" or private.
int testPublicProperty(PublicClass *p) {
int x = 0;
- [p setValue3:0];
- if ([p value3] != 0)
- return 5/x; // expected-warning {{Division by zero}} // TODO: no warning, we should always inline the property.
- return 5/[p value3];// expected-warning {{Division by zero}}
+ p.value3 = 0;
+ if (p.value3 != 0)
+ return 5/x;
+ return 5/p.value3;// expected-warning {{Division by zero}}
}
int testExtension(PublicClass *p) {
int x = 0;
[p setValue2:0];
if ([p value2] != 0)
- return 5/x; // expected-warning {{Division by zero}} // TODO: no warning, we should always inline the property.
+ return 5/x; // expected-warning {{Division by zero}}
return 5/[p value2]; // expected-warning {{Division by zero}}
}
diff --git a/test/Analysis/inlining/InlineObjCClassMethod.m b/test/Analysis/inlining/InlineObjCClassMethod.m
index 7e8b51fe0be0..814d437a52d0 100644
--- a/test/Analysis/inlining/InlineObjCClassMethod.m
+++ b/test/Analysis/inlining/InlineObjCClassMethod.m
@@ -179,3 +179,33 @@ int foo2() {
int y = [MyParentSelf testSelf];
return 5/y; // Should warn here.
}
+
+// TODO: We do not inline 'getNum' in the following case, where the value of
+// 'self' in call '[self getNum]' is available and evaualtes to
+// 'SelfUsedInParentChild' if it's called from fooA.
+// Self region should get created before we call foo and yje call to super
+// should keep it live.
+@interface SelfUsedInParent : NSObject
++ (int)getNum;
++ (int)foo;
+@end
+@implementation SelfUsedInParent
++ (int)getNum {return 5;}
++ (int)foo {
+ return [self getNum];
+}
+@end
+@interface SelfUsedInParentChild : SelfUsedInParent
++ (int)getNum;
++ (int)fooA;
+@end
+@implementation SelfUsedInParentChild
++ (int)getNum {return 0;}
++ (int)fooA {
+ return [super foo];
+}
+@end
+int checkSelfUsedInparentClassMethod() {
+ return 5/[SelfUsedInParentChild fooA];
+}
+
diff --git a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
new file mode 100644
index 000000000000..fa473aebce32
--- /dev/null
+++ b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic-bifurcate -verify %s
+
+void clang_analyzer_eval(bool);
+
+class A {
+public:
+ virtual int get() { return 0; }
+};
+
+void testBifurcation(A *a) {
+ clang_analyzer_eval(a->get() == 0); // expected-warning{{TRUE}} expected-warning{{UNKNOWN}}
+}
+
+void testKnown() {
+ A a;
+ clang_analyzer_eval(a.get() == 0); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/keychainAPI.m b/test/Analysis/keychainAPI.m
index cb4f72c9c454..585a32ddc342 100644
--- a/test/Analysis/keychainAPI.m
+++ b/test/Analysis/keychainAPI.m
@@ -76,7 +76,7 @@ void errRetVal() {
UInt32 length;
void *outData;
st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
- if (st == GenericError) // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'.}}
+ if (st == GenericError) // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
SecKeychainItemFreeContent(ptr, outData); // expected-warning{{Only call free if a valid (non-NULL) buffer was returned}}
}
@@ -220,7 +220,7 @@ int foo(CFTypeRef keychainOrArray, SecProtocolType protocol,
if (st == noErr)
SecKeychainItemFreeContent(ptr, outData[3]);
}
- if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'.}}
+ if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
length++;
}
return 0;
@@ -318,7 +318,7 @@ void radar10508828_2() {
UInt32 pwdLen = 0;
void* pwdBytes = 0;
OSStatus rc = SecKeychainFindGenericPassword(0, 3, "foo", 3, "bar", &pwdLen, &pwdBytes, 0);
- SecKeychainItemFreeContent(0, pwdBytes); // expected-warning {{Only call free if a valid (non-NULL) buffer was returned.}}
+ SecKeychainItemFreeContent(0, pwdBytes); // expected-warning {{Only call free if a valid (non-NULL) buffer was returned}}
}
//Example from bug 10797.
diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c
index 1dc0f7837bad..9c040b688d2b 100644
--- a/test/Analysis/malloc-annotations.c
+++ b/test/Analysis/malloc-annotations.c
@@ -208,11 +208,11 @@ void f7_realloc() {
}
void PR6123() {
- int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
+ int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
}
void PR7217() {
- int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
+ int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
buf[1] = 'c'; // not crash
}
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index f60271f39f4c..e3d92d9ad671 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -260,11 +260,11 @@ void f7_realloc() {
}
void PR6123() {
- int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
+ int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
}
void PR7217() {
- int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
+ int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
buf[1] = 'c'; // not crash
}
@@ -389,7 +389,7 @@ void mallocEscapeMalloc() {
void mallocMalloc() {
int *p = malloc(12);
- p = malloc(12); // expected-warning 2 {{Memory is never released; potential leak}}
+ p = malloc(12); // expected-warning {{Memory is never released; potential leak}}
}
void mallocFreeMalloc() {
diff --git a/test/Analysis/method-call-path-notes.cpp b/test/Analysis/method-call-path-notes.cpp
index fbf0cae7d8a6..17034b9b0001 100644
--- a/test/Analysis/method-call-path-notes.cpp
+++ b/test/Analysis/method-call-path-notes.cpp
@@ -36,6 +36,11 @@ void test_ic_member_ptr() {
(p->*bar)(); // expected-warning {{Called C++ object pointer is null}} expected-note{{Called C++ object pointer is null}}
}
+void test_cast(const TestInstanceCall *p) {
+ if (!p) // expected-note {{Assuming pointer value is null}} expected-note {{Taking true branch}}
+ const_cast<TestInstanceCall *>(p)->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note {{Called C++ object pointer is null}}
+}
+
// CHECK: <?xml version="1.0" encoding="UTF-8"?>
// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
// CHECK: <plist version="1.0">
@@ -659,6 +664,86 @@ void test_ic_member_ptr() {
// CHECK: <key>file</key><integer>0</integer>
// CHECK: </dict>
// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>40</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>40</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>41</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>41</integer>
+// CHECK: <key>col</key><integer>14</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>41</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>41</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>41</integer>
+// CHECK: <key>col</key><integer>37</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>depth</key><integer>0</integer>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Called C++ object pointer is null</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Called C++ object pointer is null</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Called C++ object pointer is null</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Called C++ object pointer is null</string>
+// CHECK: <key>issue_context_kind</key><string>function</string>
+// CHECK: <key>issue_context</key><string>test_cast</string>
+// CHECK: <key>issue_hash</key><integer>2</integer>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>41</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
// CHECK: </array>
// CHECK: </dict>
// CHECK: </plist>
diff --git a/test/Analysis/method-call.cpp b/test/Analysis/method-call.cpp
index 91da532456d7..912062739c34 100644
--- a/test/Analysis/method-call.cpp
+++ b/test/Analysis/method-call.cpp
@@ -1,25 +1,37 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-store region -verify %s
-// XFAIL: *
void clang_analyzer_eval(bool);
+
struct A {
int x;
A(int a) { x = a; }
int getx() const { return x; }
};
+void testNullObject(A *a) {
+ clang_analyzer_eval(a); // expected-warning{{UNKNOWN}}
+ (void)a->getx(); // assume we know what we're doing
+ clang_analyzer_eval(a); // expected-warning{{TRUE}}
+}
+
+
+// FIXME: These require constructor inlining to be enabled.
+
void f1() {
A x(3);
- clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
+ // should be TRUE
+ clang_analyzer_eval(x.getx() == 3); // expected-warning{{UNKNOWN}}
}
void f2() {
const A &x = A(3);
- clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
+ // should be TRUE
+ clang_analyzer_eval(x.getx() == 3); // expected-warning{{UNKNOWN}}
}
void f3() {
const A &x = (A)3;
- clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
+ // should be TRUE
+ clang_analyzer_eval(x.getx() == 3); // expected-warning{{UNKNOWN}}
}
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index 88860bbe10d3..2b481c4a558b 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -299,7 +299,7 @@ void test_handle_array_wrapper_helper();
int test_handle_array_wrapper() {
struct ArrayWrapper x;
test_handle_array_wrapper_helper(&x);
- struct WrappedStruct *p = (struct WrappedStruct*) x.y; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}}
+ struct WrappedStruct *p = (struct WrappedStruct*) x.y; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}}
return p->z; // no-warning
}
diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
index e4d5aaf82b2d..7cf2aee35fc0 100644
--- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
+++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
@@ -80,11 +80,11 @@ int handleVoidInComma() {
int marker(void) { // control reaches end of non-void function
}
+// CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage
// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
-// CHECK-darwin8: warning: The receiver of message 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' that will be garbage
// CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage
+// CHECK-darwin8: warning: The receiver of message 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' that will be garbage
// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
-// CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage
// CHECK-darwin9-NOT: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
// CHECK-darwin9-NOT: warning: The receiver of message 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' that will be garbage
diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c
index 6567000c735f..884ae5b9bbcd 100644
--- a/test/Analysis/ptr-arith.c
+++ b/test/Analysis/ptr-arith.c
@@ -36,7 +36,7 @@ domain_port (const char *domain_b, const char *domain_e,
void f3() {
int x, y;
- int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result.}}
+ int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result}}
int a[10];
int *p = &a[2];
@@ -46,13 +46,13 @@ void f3() {
void f4() {
int *p;
- p = (int*) 0x10000; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms.}}
+ p = (int*) 0x10000; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms}}
}
void f5() {
int x, y;
int *p;
- p = &x + 1; // expected-warning{{Pointer arithmetic done on non-array variables means reliance on memory layout, which is dangerous.}}
+ p = &x + 1; // expected-warning{{Pointer arithmetic done on non-array variables means reliance on memory layout, which is dangerous}}
int a[10];
p = a + 1; // no-warning
diff --git a/test/Analysis/reinterpret-cast.cpp b/test/Analysis/reinterpret-cast.cpp
new file mode 100644
index 000000000000..73f2e2de7381
--- /dev/null
+++ b/test/Analysis/reinterpret-cast.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
+
+void clang_analyzer_eval(bool);
+
+typedef struct Opaque *Data;
+struct IntWrapper {
+ int x;
+};
+
+struct Child : public IntWrapper {
+ void set() { x = 42; }
+};
+
+void test(Data data) {
+ Child *wrapper = reinterpret_cast<Child*>(data);
+ // Don't crash when upcasting here.
+ // We don't actually know if 'data' is a Child.
+ wrapper->set();
+ clang_analyzer_eval(wrapper->x == 42); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/security-syntax-checks.m b/test/Analysis/security-syntax-checks.m
index f4ccefe58cdb..1df8a408a697 100644
--- a/test/Analysis/security-syntax-checks.m
+++ b/test/Analysis/security-syntax-checks.m
@@ -46,7 +46,7 @@ int getpw(unsigned int uid, char *buf);
void test_getpw() {
char buff[1024];
- getpw(2, buff); // expected-warning{{The getpw() function is dangerous as it may overflow the provided buffer. It is obsoleted by getpwuid().}}
+ getpw(2, buff); // expected-warning{{The getpw() function is dangerous as it may overflow the provided buffer. It is obsoleted by getpwuid()}}
}
// <rdar://problem/6337132> CWE-273: Failure to Check Whether Privileges Were
@@ -138,7 +138,7 @@ void test_strcpy() {
char x[4];
char *y;
- strcpy(x, y); //expected-warning{{Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119.}}
+ strcpy(x, y); //expected-warning{{Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119}}
}
//===----------------------------------------------------------------------===
@@ -162,7 +162,7 @@ void test_strcat() {
char x[4];
char *y;
- strcat(x, y); //expected-warning{{Call to function 'strcat' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcat'. CWE-119.}}
+ strcat(x, y); //expected-warning{{Call to function 'strcat' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcat'. CWE-119}}
}
//===----------------------------------------------------------------------===
@@ -173,7 +173,7 @@ typedef __int32_t pid_t;
pid_t vfork(void);
void test_vfork() {
- vfork(); //expected-warning{{Call to function 'vfork' is insecure as it can lead to denial of service situations in the parent process.}}
+ vfork(); //expected-warning{{Call to function 'vfork' is insecure as it can lead to denial of service situations in the parent process}}
}
//===----------------------------------------------------------------------===
diff --git a/test/Analysis/sizeofpointer.c b/test/Analysis/sizeofpointer.c
index 0c86de88ae28..aa85fc002aa1 100644
--- a/test/Analysis/sizeofpointer.c
+++ b/test/Analysis/sizeofpointer.c
@@ -4,5 +4,5 @@ struct s {
};
int f(struct s *p) {
- return sizeof(p); // expected-warning{{The code calls sizeof() on a pointer type. This can produce an unexpected result.}}
+ return sizeof(p); // expected-warning{{The code calls sizeof() on a pointer type. This can produce an unexpected result}}
}
diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp
index b21a03dc38a4..cbdb143c1857 100644
--- a/test/Analysis/stack-addr-ps.cpp
+++ b/test/Analysis/stack-addr-ps.cpp
@@ -87,6 +87,6 @@ struct TS {
// rdar://11345441
int* f5() {
- int& i = i; // expected-warning {{Assigned value is garbage or undefined}} expected-note {{binding reference variable 'i' here}}
+ int& i = i; // expected-warning {{Assigned value is garbage or undefined}} expected-note {{binding reference variable 'i' here}} expected-warning{{variable 'i' is uninitialized when used within its own initialization}}
return &i; // expected-warning {{address of stack memory associated with local variable 'i' returned}}
}
diff --git a/test/Analysis/stream.c b/test/Analysis/stream.c
index e68835e5cfc4..4a095cffd028 100644
--- a/test/Analysis/stream.c
+++ b/test/Analysis/stream.c
@@ -16,25 +16,25 @@ extern void rewind (FILE *__stream);
void f1(void) {
FILE *p = fopen("foo", "r");
char buf[1024];
- fread(buf, 1, 1, p); // expected-warning {{Stream pointer might be NULL.}}
+ fread(buf, 1, 1, p); // expected-warning {{Stream pointer might be NULL}}
fclose(p);
}
void f2(void) {
FILE *p = fopen("foo", "r");
- fseek(p, 1, SEEK_SET); // expected-warning {{Stream pointer might be NULL.}}
+ fseek(p, 1, SEEK_SET); // expected-warning {{Stream pointer might be NULL}}
fclose(p);
}
void f3(void) {
FILE *p = fopen("foo", "r");
- ftell(p); // expected-warning {{Stream pointer might be NULL.}}
+ ftell(p); // expected-warning {{Stream pointer might be NULL}}
fclose(p);
}
void f4(void) {
FILE *p = fopen("foo", "r");
- rewind(p); // expected-warning {{Stream pointer might be NULL.}}
+ rewind(p); // expected-warning {{Stream pointer might be NULL}}
fclose(p);
}
@@ -43,26 +43,26 @@ void f5(void) {
if (!p)
return;
fseek(p, 1, SEEK_SET); // no-warning
- fseek(p, 1, 3); // expected-warning {{The whence argument to fseek() should be SEEK_SET, SEEK_END, or SEEK_CUR.}}
+ fseek(p, 1, 3); // expected-warning {{The whence argument to fseek() should be SEEK_SET, SEEK_END, or SEEK_CUR}}
fclose(p);
}
void f6(void) {
FILE *p = fopen("foo", "r");
fclose(p);
- fclose(p); // expected-warning {{Try to close a file Descriptor already closed. Cause undefined behaviour.}}
+ fclose(p); // expected-warning {{Try to close a file Descriptor already closed. Cause undefined behaviour}}
}
void f7(void) {
FILE *p = tmpfile();
- ftell(p); // expected-warning {{Stream pointer might be NULL.}}
+ ftell(p); // expected-warning {{Stream pointer might be NULL}}
fclose(p);
}
void f8(int c) {
FILE *p = fopen("foo.c", "r");
if(c)
- return; // expected-warning {{Opened File never closed. Potential Resource leak.}}
+ return; // expected-warning {{Opened File never closed. Potential Resource leak}}
fclose(p);
}
diff --git a/test/Analysis/variadic-method-types.m b/test/Analysis/variadic-method-types.m
index 4d0f6bc3f75a..9f90e5ff343d 100644
--- a/test/Analysis/variadic-method-types.m
+++ b/test/Analysis/variadic-method-types.m
@@ -74,7 +74,7 @@ void f(id a, id<P> b, C* c, C<P> *d, FooType fooType, BarType barType) {
[NSArray arrayWithObjects:@"Hello", a, b, c, d, nil];
[NSArray arrayWithObjects:@"Foo", ^{}, nil];
- [NSArray arrayWithObjects:@"Foo", "Bar", "Baz", nil]; // expected-warning 2 {{Argument to 'NSArray' method 'arrayWithObjects:' should be an Objective-C pointer type, not 'char *'}}
+ [NSArray arrayWithObjects:@"Foo", "Bar", "Baz", nil]; // expected-warning {{Argument to 'NSArray' method 'arrayWithObjects:' should be an Objective-C pointer type, not 'char *'}}
[NSDictionary dictionaryWithObjectsAndKeys:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSDictionary' method 'dictionaryWithObjectsAndKeys:' should be an Objective-C pointer type, not 'char *'}}
[NSSet setWithObjects:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSSet' method 'setWithObjects:' should be an Objective-C pointer type, not 'char *'}}
[NSOrderedSet orderedSetWithObjects:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSOrderedSet' method 'orderedSetWithObjects:' should be an Objective-C pointer type, not 'char *'}}
diff --git a/test/CodeCompletion/objc-expr.m b/test/CodeCompletion/objc-expr.m
index b59586ab96cf..d3c95a6e6ff1 100644
--- a/test/CodeCompletion/objc-expr.m
+++ b/test/CodeCompletion/objc-expr.m
@@ -11,7 +11,7 @@ id testCompleteAfterAtSign() {
// CHECK-AT: COMPLETION: Pattern : [#char[]#]encode(<#type-name#>)
// CHECK-AT: COMPLETION: Pattern : [#Protocol *#]protocol(<#protocol-name#>)
// CHECK-AT: COMPLETION: Pattern : [#SEL#]selector(<#selector#>)
-// CHECK-AT: COMPLETION: Pattern : [#NSDictionary *#]{<#key#> : <#object, ...#>}
+// CHECK-AT: COMPLETION: Pattern : [#NSDictionary *#]{<#key#>: <#object, ...#>}
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:4:11 %s -fconst-strings -o - | FileCheck -check-prefix=CONST-STRINGS %s
// CHECK-CONST-STRINGS: COMPLETION: Pattern : [#const char[]#]encode(<#type-name#>)
diff --git a/test/CodeGen/align-global-large.c b/test/CodeGen/align-global-large.c
new file mode 100644
index 000000000000..fcbe758a82e4
--- /dev/null
+++ b/test/CodeGen/align-global-large.c
@@ -0,0 +1,18 @@
+// PR13606 - Clang crashes with large alignment attribute
+// RUN: %clang -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: x
+// CHECK: align
+// CHECK: 1048576
+volatile char x[4000] __attribute__((aligned(0x100000)));
+
+int
+main (int argc, char ** argv) {
+ // CHECK: y
+ // CHECK: align
+ // CHECK: 1048576
+ volatile char y[4000] __attribute__((aligned(0x100000)));
+
+ return y[argc];
+}
+
diff --git a/test/CodeGen/alignment.c b/test/CodeGen/alignment.c
index 8882c91d03e1..98ea01be0920 100644
--- a/test/CodeGen/alignment.c
+++ b/test/CodeGen/alignment.c
@@ -43,7 +43,8 @@ void test3(packedfloat3 *p) {
*p = (packedfloat3) { 3.2f, 2.3f, 0.1f };
}
// CHECK: @test3(
-// CHECK: store <3 x float> {{.*}}, align 4
+// CHECK: %{{.*}} = bitcast <3 x float>* %{{.*}} to <4 x float>*
+// CHECK: store <4 x float> {{.*}}, align 4
// CHECK: ret void
diff --git a/test/CodeGen/arm-neon-misc.c b/test/CodeGen/arm-neon-misc.c
new file mode 100644
index 000000000000..56ce316c749b
--- /dev/null
+++ b/test/CodeGen/arm-neon-misc.c
@@ -0,0 +1,34 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple thumbv7-apple-darwin \
+// RUN: -target-abi apcs-gnu \
+// RUN: -target-cpu cortex-a8 \
+// RUN: -mfloat-abi soft \
+// RUN: -target-feature +soft-float-abi \
+// RUN: -ffreestanding \
+// RUN: -emit-llvm -w -o - %s | FileCheck %s
+
+#include <arm_neon.h>
+
+// Radar 11998303: Avoid using i64 types for vld1q_lane and vst1q_lane Neon
+// intrinsics with <2 x i64> vectors to avoid poor code for i64 in the backend.
+void t1(uint64_t *src, uint8_t *dst) {
+// CHECK: @t1
+ uint64x2_t q = vld1q_u64(src);
+// CHECK: call <2 x i64> @llvm.arm.neon.vld1.v2i64
+ vst1q_lane_u64(dst, q, 1);
+// CHECK: bitcast <16 x i8> %{{.*}} to <2 x i64>
+// CHECK: shufflevector <2 x i64>
+// CHECK: call void @llvm.arm.neon.vst1.v1i64
+}
+
+void t2(uint64_t *src1, uint8_t *src2, uint64x2_t *dst) {
+// CHECK: @t2
+ uint64x2_t q = vld1q_u64(src1);
+// CHECK: call <2 x i64> @llvm.arm.neon.vld1.v2i64
+ q = vld1q_lane_u64(src2, q, 0);
+// CHECK: shufflevector <2 x i64>
+// CHECK: call <1 x i64> @llvm.arm.neon.vld1.v1i64
+// CHECK: shufflevector <1 x i64>
+ *dst = q;
+// CHECK: store <2 x i64>
+}
diff --git a/test/CodeGen/complex-builtints.c b/test/CodeGen/complex-builtints.c
new file mode 100644
index 000000000000..09219cfb9d4e
--- /dev/null
+++ b/test/CodeGen/complex-builtints.c
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 %s -O1 -emit-llvm -o - | FileCheck %s
+// rdar://8315199
+
+/* Test for builtin conj, creal, cimag. */
+/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
+
+extern float _Complex conjf (float _Complex);
+extern double _Complex conj (double _Complex);
+extern long double _Complex conjl (long double _Complex);
+
+extern float crealf (float _Complex);
+extern double creal (double _Complex);
+extern long double creall (long double _Complex);
+
+extern float cimagf (float _Complex);
+extern double cimag (double _Complex);
+extern long double cimagl (long double _Complex);
+
+extern void abort (void);
+extern void link_error (void);
+
+int
+main ()
+{
+ /* For each type, test both runtime and compile time (constant folding)
+ optimization. */
+ volatile float _Complex fc = 1.0F + 2.0iF;
+ volatile double _Complex dc = 1.0 + 2.0i;
+ volatile long double _Complex ldc = 1.0L + 2.0iL;
+ /* Test floats. */
+ if (__builtin_conjf (fc) != 1.0F - 2.0iF)
+ abort ();
+ if (__builtin_conjf (1.0F + 2.0iF) != 1.0F - 2.0iF)
+ link_error ();
+ if (__builtin_crealf (fc) != 1.0F)
+ abort ();
+ if (__builtin_crealf (1.0F + 2.0iF) != 1.0F)
+ link_error ();
+ if (__builtin_cimagf (fc) != 2.0F)
+ abort ();
+ if (__builtin_cimagf (1.0F + 2.0iF) != 2.0F)
+ link_error ();
+ /* Test doubles. */
+ if (__builtin_conj (dc) != 1.0 - 2.0i)
+ abort ();
+ if (__builtin_conj (1.0 + 2.0i) != 1.0 - 2.0i)
+ link_error ();
+ if (__builtin_creal (dc) != 1.0)
+ abort ();
+ if (__builtin_creal (1.0 + 2.0i) != 1.0)
+ link_error ();
+ if (__builtin_cimag (dc) != 2.0)
+ abort ();
+ if (__builtin_cimag (1.0 + 2.0i) != 2.0)
+ link_error ();
+ /* Test long doubles. */
+ if (__builtin_conjl (ldc) != 1.0L - 2.0iL)
+ abort ();
+ if (__builtin_conjl (1.0L + 2.0iL) != 1.0L - 2.0iL)
+ link_error ();
+ if (__builtin_creall (ldc) != 1.0L)
+ abort ();
+ if (__builtin_creall (1.0L + 2.0iL) != 1.0L)
+ link_error ();
+ if (__builtin_cimagl (ldc) != 2.0L)
+ abort ();
+ if (__builtin_cimagl (1.0L + 2.0iL) != 2.0L)
+ link_error ();
+}
+
+// CHECK-NOT: link_error
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
index 8c3e5f7c569b..c140d60551d9 100644
--- a/test/CodeGen/ms-inline-asm.c
+++ b/test/CodeGen/ms-inline-asm.c
@@ -9,7 +9,9 @@ void t1() {
void t2() {
// CHECK: @t2
-// CHECK: call void asm sideeffect "nop\0Anop\0Anop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
// CHECK: ret void
__asm nop
__asm nop
@@ -25,7 +27,8 @@ void t3() {
void t4(void) {
// CHECK: @t4
-// CHECK: call void asm sideeffect "mov ebx, eax\0Amov ecx, ebx", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
// CHECK: ret void
__asm mov ebx, eax
__asm mov ecx, ebx
@@ -33,8 +36,85 @@ void t4(void) {
void t5(void) {
// CHECK: @t5
-// CHECK: call void asm sideeffect "mov ebx, eax\0Amov ecx, ebx", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "mov ebx, eax\0Amov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
// CHECK: ret void
__asm mov ebx, eax __asm mov ecx, ebx
}
+void t6(void) {
+ __asm int 0x2c
+// CHECK: t6
+// CHECK: call void asm sideeffect "int 0x2c", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+}
+
+void* t7(void) {
+ __asm mov eax, fs:[0x10]
+// CHECK: t7
+// CHECK: call void asm sideeffect "mov eax, fs:[0x10]", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+}
+
+void t8() {
+ __asm {
+ int 0x2c ; } asm comments are fun! }{
+ }
+ __asm {}
+// CHECK: t8
+// CHECK: call void asm sideeffect "int 0x2c", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+}
+int t9() {
+ __asm int 3 ; } comments for single-line asm
+ __asm {}
+ __asm int 4
+ return 10;
+// CHECK: t9
+// CHECK: call void asm sideeffect "int 3", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "int 4", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: ret i32 10
+}
+void t10() {
+ __asm {
+ push ebx
+ mov ebx, 0x07
+ pop ebx
+ }
+// CHECK: t10
+// CHECK: call void asm sideeffect "push ebx\0Amov ebx, 0x07\0Apop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+}
+
+unsigned t11(void) {
+ unsigned i = 1, j;
+ __asm {
+ mov eax, i
+ mov j, eax
+ }
+ return j;
+// CHECK: t11
+// CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4
+// CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4
+// CHECK: store i32 1, i32* [[I]], align 4
+// CHECK: call void asm sideeffect "mov eax, i\0Amov j, eax", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4
+// CHECK: ret i32 [[RET]]
+}
+
+void t12(void) {
+ __asm EVEN
+ __asm ALIGN
+}
+
+void t13(void) {
+ __asm {
+ _emit 0x4A
+ _emit 0x43
+ _emit 0x4B
+ }
+}
+
+void t14(void) {
+ unsigned arr[10];
+ __asm LENGTH arr ; sizeof(arr)/sizeof(arr[0])
+ __asm SIZE arr ; sizeof(arr)
+ __asm TYPE arr ; sizeof(arr[0])
+}
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
index c5a4094a53c3..7ef4864c8367 100644
--- a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
+++ b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
@@ -83,3 +83,20 @@ namespace test3 {
d.B::~B();
}
}
+
+namespace test4 {
+ struct Animal {
+ virtual void eat();
+ };
+ struct Fish : Animal {
+ virtual void eat();
+ };
+ struct Wrapper {
+ Fish fish;
+ };
+ extern Wrapper *p;
+ void test() {
+ // CHECK: call void @_ZN5test44Fish3eatEv
+ p->fish.eat();
+ }
+}
diff --git a/test/CodeGenObjC/instance-method-metadata.m b/test/CodeGenObjC/instance-method-metadata.m
index ec24c287a36d..0d8c0e0eae50 100644
--- a/test/CodeGenObjC/instance-method-metadata.m
+++ b/test/CodeGenObjC/instance-method-metadata.m
@@ -28,8 +28,8 @@
@end
// CHECK: l_OBJC_$_INSTANCE_METHODS_Bar:
-// CHECK-NEXT .long 24
-// CHECK-NEXT .long 2
-// CHECK-NEXT .quad L_OBJC_METH_VAR_NAME_
-// CHECK-NEXT .quad L_OBJC_METH_VAR_TYPE_
-// CHECK-NEXT .quad "-[Bar prop]"
+// CHECK-NEXT: .long 24
+// CHECK-NEXT: .long 2
+// CHECK-NEXT: .quad L_OBJC_METH_VAR_NAME_
+// CHECK-NEXT: .quad L_OBJC_METH_VAR_TYPE_
+// CHECK-NEXT: .quad "-[Bar prop]"
diff --git a/test/CodeGenObjC/ns_consume_null_check.m b/test/CodeGenObjC/ns_consume_null_check.m
index e3b60759e91b..a8e5acd57e61 100644
--- a/test/CodeGenObjC/ns_consume_null_check.m
+++ b/test/CodeGenObjC/ns_consume_null_check.m
@@ -17,7 +17,7 @@ void foo()
[x isEqual : obj];
}
-// CHECK: [[TMP:%.*]] = alloca i8
+// CHECK: [[TMP:%.*]] = alloca i8{{$}}
// CHECK: [[FIVE:%.*]] = call i8* @objc_retain
// CHECK-NEXT: [[SIX:%.*]] = bitcast
// CHECK-NEXT: [[SEVEN:%.*]] = icmp eq i8* [[SIX]], null
@@ -25,8 +25,8 @@ void foo()
// CHECK: [[FN:%.*]] = load i8** getelementptr inbounds
// CHECK-NEXT: [[EIGHT:%.*]] = bitcast i8* [[FN]]
// CHECK-NEXT: [[CALL:%.*]] = call signext i8 [[EIGHT]]
-// CHECK-NEXT store i8 [[CALL]], i8* [[TMP]]
-// CHECK-NEXT br label [[CONT:%.*]]
+// CHECK-NEXT: store i8 [[CALL]], i8* [[TMP]]
+// CHECK-NEXT: br label [[CONT:%.*]]
// CHECK: call void @objc_release(i8* [[FIVE]]) nounwind
// CHECK-NEXT: call void @llvm.memset
-// CHECK-NEXT br label [[CONT]]
+// CHECK-NEXT: br label [[CONT]]
diff --git a/test/CodeGenOpenCL/vectorLoadStore.cl b/test/CodeGenOpenCL/vectorLoadStore.cl
new file mode 100644
index 000000000000..44bc7bd25d45
--- /dev/null
+++ b/test/CodeGenOpenCL/vectorLoadStore.cl
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | FileCheck %s
+
+typedef char char3 __attribute((ext_vector_type(3)));;
+
+// Check for optimized vec3 load/store which treats vec3 as vec4.
+void foo(char3 *P, char3 *Q) {
+ *P = *Q;
+ // CHECK: %{{.*}} = shufflevector <4 x i8> %{{.*}}, <4 x i8> undef, <3 x i32> <i32 0, i32 1, i32 2>
+}
diff --git a/test/Driver/Xlinker-args.c b/test/Driver/Xlinker-args.c
index b4e5a9b08f43..d89d5bad1aaf 100644
--- a/test/Driver/Xlinker-args.c
+++ b/test/Driver/Xlinker-args.c
@@ -4,6 +4,13 @@
// RUN: %clang -target i386-apple-darwin9 -### \
// RUN: -Xlinker one -Xlinker --no-demangle \
// RUN: -Wl,two,--no-demangle,three -Xlinker four %s 2> %t
-// RUN: FileCheck < %t %s
+// RUN: FileCheck -check-prefix=DARWIN < %t %s
//
-// CHECK: "one" "two" "three" "four"
+// RUN: %clang -target x86_64-pc-linux-gnu -### \
+// RUN: -Xlinker one -Xlinker --no-demangle \
+// RUN: -Wl,two,--no-demangle,three -Xlinker four %s 2> %t
+// RUN: FileCheck -check-prefix=LINUX < %t %s
+//
+// DARWIN-NOT: --no-demangle
+// DARWIN: "one" "two" "three" "four"
+// LINUX: "--no-demangle" "one" "two" "three" "four"
diff --git a/test/Index/complete-enums.cpp b/test/Index/complete-enums.cpp
index 49a893258773..23c60ac4dfa5 100644
--- a/test/Index/complete-enums.cpp
+++ b/test/Index/complete-enums.cpp
@@ -1,6 +1,6 @@
// Note: the run lines follow their respective tests, since line/column
// matter in this test.
-
+struct X { X(); ~X(); };
enum class Color {
Red = 17,
Green,
@@ -9,7 +9,7 @@ enum class Color {
int Greeby();
void f(Color color) {
switch (color) {
- case Color::Green:
+ case Color::Green: { X x; }
case Color::Red;
}
}
diff --git a/test/Index/complete-exprs.m b/test/Index/complete-exprs.m
index 3fb1540351d5..16eeda9bff4b 100644
--- a/test/Index/complete-exprs.m
+++ b/test/Index/complete-exprs.m
@@ -21,7 +21,7 @@ __strong id global;
// CHECK-CC1: NotImplemented:{ResultType NSString *}{TypedText @"}{Placeholder string}{Text "} (40)
// CHECK-CC1: NotImplemented:{ResultType id}{TypedText @(}{Placeholder expression}{RightParen )} (40)
// CHECK-CC1: NotImplemented:{ResultType NSArray *}{TypedText @[}{Placeholder objects, ...}{RightBracket ]} (40)
-// CHECK-CC1: NotImplemented:{ResultType NSDictionary *}{TypedText @{}{Placeholder key}{HorizontalSpace }{Colon :}{HorizontalSpace }{Placeholder object, ...}{RightBrace }} (40)
+// CHECK-CC1: NotImplemented:{ResultType NSDictionary *}{TypedText @{}{Placeholder key}{Colon :}{HorizontalSpace }{Placeholder object, ...}{RightBrace }} (40)
// CHECK-CC1: NotImplemented:{ResultType SEL}{TypedText _cmd} (80)
// CHECK-CC1: TypedefDecl:{TypedText BOOL} (50)
// CHECK-CC1: macro definition:{TypedText bool} (51)
@@ -43,7 +43,7 @@ __strong id global;
// RUN: c-index-test -code-completion-at=%s:16:5 %s | FileCheck -check-prefix=CHECK-CC4 %s
// RUN: c-index-test -code-completion-at=%s:16:14 %s | FileCheck -check-prefix=CHECK-CC4 %s
// CHECK-CC4: NotImplemented:{ResultType NSArray *}{TypedText @[}{Placeholder objects, ...}{RightBracket ]} (40)
-// CHECK-CC4: NotImplemented:{ResultType NSDictionary *}{TypedText @{}{Placeholder key}{HorizontalSpace }{Colon :}{HorizontalSpace }{Placeholder object, ...}{RightBrace }} (40)
+// CHECK-CC4: NotImplemented:{ResultType NSDictionary *}{TypedText @{}{Placeholder key}{Colon :}{HorizontalSpace }{Placeholder object, ...}{RightBrace }} (40)
// CHECK-CC4: NotImplemented:{ResultType SEL}{TypedText _cmd} (80)
// CHECK-CC4: macro definition:{TypedText bool} (51)
// CHECK-CC4: macro definition:{TypedText NO} (65)
diff --git a/test/Index/complete-preamble.cpp b/test/Index/complete-preamble.cpp
new file mode 100644
index 000000000000..8f4810522527
--- /dev/null
+++ b/test/Index/complete-preamble.cpp
@@ -0,0 +1,8 @@
+#include "complete-preamble.h"
+void f() {
+ std::
+}
+
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:3:8 %s -o - | FileCheck -check-prefix=CC1 %s
+// CHECK-CC1: {ResultType void}{TypedText wibble}{LeftParen (}{RightParen )} (50) (parent: Namespace 'std')
+
diff --git a/test/Index/complete-preamble.h b/test/Index/complete-preamble.h
new file mode 100644
index 000000000000..e696284c0964
--- /dev/null
+++ b/test/Index/complete-preamble.h
@@ -0,0 +1,6 @@
+namespace std {
+ void wibble();
+}
+
+namespace std {
+}
diff --git a/test/Parser/ms-inline-asm.c b/test/Parser/ms-inline-asm.c
index 2d181958857b..5326ce4d2417 100644
--- a/test/Parser/ms-inline-asm.c
+++ b/test/Parser/ms-inline-asm.c
@@ -11,13 +11,13 @@ void t5() {
__asm { // expected-warning {{MS-style inline assembly is not supported}}
int 0x2c ; } asm comments are fun! }{
}
- __asm {} // no warning as this gets merged with the previous inline asm
+ __asm {} // expected-warning {{MS-style inline assembly is not supported}}
}
int t6() {
__asm int 3 ; } comments for single-line asm // expected-warning {{MS-style inline assembly is not supported}}
- __asm {} // no warning as this gets merged with the previous inline asm
+ __asm {} // expected-warning {{MS-style inline assembly is not supported}}
- __asm int 4 // no warning as this gets merged with the previous inline asm
+ __asm int 4 // expected-warning {{MS-style inline assembly is not supported}}
return 10;
}
int t7() {
diff --git a/test/Sema/128bitint.c b/test/Sema/128bitint.c
index ddad83554753..600c25a630c2 100644
--- a/test/Sema/128bitint.c
+++ b/test/Sema/128bitint.c
@@ -18,3 +18,22 @@ long long Signed64 = 123456789012345678901234567890i128; // expected-warning {{i
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}}
+
+// Ensure we don't crash when user passes 128-bit values to type safety
+// attributes.
+void pointer_with_type_tag_arg_num_1(void *buf, int datatype)
+ __attribute__(( pointer_with_type_tag(mpi,0x10000000000000001i128,1) )); // expected-error {{attribute parameter 2 is out of bounds}}
+
+void pointer_with_type_tag_arg_num_2(void *buf, int datatype)
+ __attribute__(( pointer_with_type_tag(mpi,1,0x10000000000000001i128) )); // expected-error {{attribute parameter 3 is out of bounds}}
+
+void MPI_Send(void *buf, int datatype) __attribute__(( pointer_with_type_tag(mpi,1,2) ));
+
+static const __uint128_t mpi_int_wrong __attribute__(( type_tag_for_datatype(mpi,int) )) = 0x10000000000000001i128; // expected-error {{'type_tag_for_datatype' attribute requires the initializer to be an integer constant expression that can be represented by a 64 bit integer}}
+static const int mpi_int __attribute__(( type_tag_for_datatype(mpi,int) )) = 10;
+
+void test(int *buf)
+{
+ MPI_Send(buf, 0x10000000000000001i128); // expected-warning {{implicit conversion from '__int128' to 'int' changes value}}
+}
+
diff --git a/test/Sema/arm-asm.c b/test/Sema/arm-asm.c
new file mode 100644
index 000000000000..3fc0eeb7543a
--- /dev/null
+++ b/test/Sema/arm-asm.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -triple armv7-apple-darwin -verify -fsyntax-only
+
+void f (void) {
+ int Val;
+ asm volatile ("lw (r1), %0[val]": "=&b"(Val)); // expected-error {{invalid output constraint '=&b' in asm}}
+ return;
+}
diff --git a/test/Sema/builtins-decl.c b/test/Sema/builtins-decl.c
index 19bdb840ccfb..d6b004aa8820 100644
--- a/test/Sema/builtins-decl.c
+++ b/test/Sema/builtins-decl.c
@@ -6,3 +6,8 @@
extern unsigned int __builtin_ia32_crc32qi (unsigned int, unsigned char);
extern unsigned int __builtin_ia32_crc32hi (unsigned int, unsigned short);
extern unsigned int __builtin_ia32_crc32si (unsigned int, unsigned int);
+
+// GCC documents these as unsigned, but they are defined with a signed argument.
+extern int __builtin_ffs(int);
+extern int __builtin_ffsl(long);
+extern int __builtin_ffsll(long long);
diff --git a/test/Sema/callingconv.c b/test/Sema/callingconv.c
index 25669f08ae29..6c844a373318 100644
--- a/test/Sema/callingconv.c
+++ b/test/Sema/callingconv.c
@@ -36,6 +36,14 @@ void (__attribute__((cdecl)) *pctest2)() = ctest2;
typedef void (__attribute__((fastcall)) *Handler) (float *);
Handler H = foo;
+int __attribute__((pcs("aapcs", "aapcs"))) pcs1(void); // expected-error {{attribute takes one argument}}
+int __attribute__((pcs())) pcs2(void); // expected-error {{attribute takes one argument}}
+int __attribute__((pcs(pcs1))) pcs3(void); // expected-error {{attribute takes one argument}}
+int __attribute__((pcs(0))) pcs4(void); // expected-error {{'pcs' attribute requires parameter 1 to be a string}}
+int __attribute__((pcs("aapcs"))) pcs5(void); // no-error
+int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // no-error
+int __attribute__((pcs("foo"))) pcs7(void); // expected-error {{Invalid PCS type}}
+
// PR6361
void ctest3();
void __attribute__((cdecl)) ctest3() {}
diff --git a/test/Sema/static-array.c b/test/Sema/static-array.c
index 2d4b968decda..5ca693b2bf54 100644
--- a/test/Sema/static-array.c
+++ b/test/Sema/static-array.c
@@ -1,12 +1,9 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
void cat0(int a[static 0]) {} // expected-warning {{'static' has no effect on zero-length arrays}}
void cat(int a[static 3]) {} // expected-note 2 {{callee declares array parameter as static here}}
-typedef int i3[static 3];
-void tcat(i3 a) {}
-
void vat(int i, int a[static i]) {} // expected-note {{callee declares array parameter as static here}}
void f(int *p) {
@@ -20,12 +17,41 @@ void f(int *p) {
cat(c);
cat(p);
- tcat(0); // expected-warning {{null passed to a callee which requires a non-null argument}}
- tcat(a); // expected-warning {{array argument is too small; contains 2 elements, callee requires at least 3}}
- tcat(b);
- tcat(c);
- tcat(p);
-
vat(1, 0); // expected-warning {{null passed to a callee which requires a non-null argument}}
vat(3, b);
}
+
+
+typedef int td[static 3]; // expected-error {{'static' used in array declarator outside of function prototype}}
+typedef void(*fp)(int[static 42]); // no-warning
+
+void g(void) {
+ int a[static 42]; // expected-error {{'static' used in array declarator outside of function prototype}}
+
+ int b[const 10]; // expected-error {{type qualifier used in array declarator outside of function prototype}}
+ int c[volatile 10]; // expected-error {{type qualifier used in array declarator outside of function prototype}}
+ int d[restrict 10]; // expected-error {{type qualifier used in array declarator outside of function prototype}}
+
+ int e[static restrict 1]; // expected-error {{'static' used in array declarator outside of function prototype}}
+}
+
+void h(int [static const 10][42]); // no-warning
+
+void i(int [10]
+ [static 42]); // expected-error {{'static' used in non-outermost array type derivation}}
+
+void j(int [10]
+ [const 42]); // expected-error {{type qualifier used in non-outermost array type derivation}}
+
+void k(int (*x)[static 10]); // expected-error {{'static' used in non-outermost array type derivation}}
+void l(int (x)[static 10]); // no-warning
+void m(int *x[static 10]); // no-warning
+void n(int *(x)[static 10]); // no-warning
+
+void o(int (x[static 10])(void)); // expected-error{{'x' declared as array of functions of type 'int (void)'}}
+void p(int (^x)[static 10]); // expected-error{{block pointer to non-function type is invalid}}
+void q(int (^x[static 10])()); // no-warning
+
+void r(x)
+ int x[restrict]; // no-warning
+{}
diff --git a/test/Sema/tentative-decls.c b/test/Sema/tentative-decls.c
index b15537bfa0cd..e14540ba8417 100644
--- a/test/Sema/tentative-decls.c
+++ b/test/Sema/tentative-decls.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify
+// RUN: %clang_cc1 %s -fsyntax-only -Wprivate-extern -verify
// PR3310
struct a x1; // expected-note 2{{forward declaration of 'struct a'}}
@@ -32,7 +32,8 @@ int i2 = 3; // expected-error{{non-static declaration of 'i2' follows static dec
static int i3 = 5;
extern int i3;
-__private_extern__ int pExtern;
+// rdar://7703982
+__private_extern__ int pExtern; // expected-warning {{Use of __private_extern__ on tentative definition has unexpected behaviour}}
int pExtern = 0;
int i4;
diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp
index 16ba4297cdc4..d99520b6733e 100644
--- a/test/Sema/warn-documentation.cpp
+++ b/test/Sema/warn-documentation.cpp
@@ -624,13 +624,9 @@ class test_attach37 {
/// \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) {}
+ void test_attach39(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}}
@@ -639,6 +635,29 @@ void test_attach37<T>::test_attach38(int aaa, int bbb) {}
template<>
void test_attach37<int>::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_attach39(int aaa, int bbb) {}
+
+// We used to emit warning that parameter 'a' is not found because we parsed
+// the comment in context of the redeclaration which does not have parameter
+// names.
+template <typename T>
+struct test_attach38 {
+ /*!
+ \param a First param
+ \param b Second param
+ */
+ template <typename B>
+ void test_attach39(T a, B b);
+};
+
+template <>
+template <typename B>
+void test_attach38<int>::test_attach39(int, B);
+
// PR13411, reduced. We used to crash on this.
/**
@@ -652,7 +671,7 @@ void test_nocrash1(int);
/// \param\brief
void test_nocrash2(int);
-// PR13593
+// PR13593, example 1 and 2
/**
* Bla.
@@ -668,3 +687,30 @@ template <typename>
void test_nocrash3()
{
}
+
+// PR13593, example 3
+
+/**
+ * aaa
+ */
+template <typename T>
+inline T test_nocrash5(T a1)
+{
+ return a1;
+}
+
+///
+//,
+
+inline void test_nocrash6()
+{
+ test_nocrash5(1);
+}
+
+// We used to crash on this.
+
+/*!
+ Blah.
+*/
+typedef const struct test_nocrash7 * test_nocrash8;
+
diff --git a/test/Sema/warn-type-safety-mpi-hdf5.c b/test/Sema/warn-type-safety-mpi-hdf5.c
new file mode 100644
index 000000000000..9c2ee965866d
--- /dev/null
+++ b/test/Sema/warn-type-safety-mpi-hdf5.c
@@ -0,0 +1,307 @@
+// RUN: %clang_cc1 -std=c99 -DOPEN_MPI -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c99 -DMPICH -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c++ -std=c++98 -DOPEN_MPI -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c++ -std=c++98 -DMPICH -fsyntax-only -verify %s
+//
+// RUN: %clang_cc1 -std=c99 -DOPEN_MPI -fno-signed-char -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c99 -DMPICH -fno-signed-char -fsyntax-only -verify %s
+
+//===--- limits.h mock ----------------------------------------------------===//
+
+#ifdef __CHAR_UNSIGNED__
+#define CHAR_MIN 0
+#define CHAR_MAX (__SCHAR_MAX__*2 +1)
+#else
+#define CHAR_MIN (-__SCHAR_MAX__-1)
+#define CHAR_MAX __SCHAR_MAX__
+#endif
+
+//===--- mpi.h mock -------------------------------------------------------===//
+
+#define NULL ((void *)0)
+
+#ifdef OPEN_MPI
+typedef struct ompi_datatype_t *MPI_Datatype;
+#endif
+
+#ifdef MPICH
+typedef int MPI_Datatype;
+#endif
+
+int MPI_Send(void *buf, int count, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,1,3) ));
+
+int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+ void *recvbuf, int recvcount, MPI_Datatype recvtype)
+ __attribute__(( pointer_with_type_tag(mpi,1,3), pointer_with_type_tag(mpi,4,6) ));
+
+#ifdef OPEN_MPI
+// OpenMPI and LAM/MPI-style datatype definitions
+
+#define OMPI_PREDEFINED_GLOBAL(type, global) ((type) &(global))
+
+#define MPI_DATATYPE_NULL OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_datatype_null)
+#define MPI_FLOAT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float)
+#define MPI_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_int)
+#define MPI_LONG OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long)
+#define MPI_LONG_LONG_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long_long_int)
+#define MPI_CHAR OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_char)
+
+#define MPI_FLOAT_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float_int)
+#define MPI_2INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_2int)
+
+#define MPI_IN_PLACE ((void *) 1)
+
+extern struct ompi_predefined_datatype_t ompi_mpi_datatype_null __attribute__(( type_tag_for_datatype(mpi,void,must_be_null) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_float __attribute__(( type_tag_for_datatype(mpi,float) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_int __attribute__(( type_tag_for_datatype(mpi,int) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_long __attribute__(( type_tag_for_datatype(mpi,long) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_long_long_int __attribute__(( type_tag_for_datatype(mpi,long long int) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_char __attribute__(( type_tag_for_datatype(mpi,char) ));
+
+struct ompi_struct_mpi_float_int {float f; int i;};
+extern struct ompi_predefined_datatype_t ompi_mpi_float_int __attribute__(( type_tag_for_datatype(mpi, struct ompi_struct_mpi_float_int, layout_compatible) ));
+
+struct ompi_struct_mpi_2int {int i1; int i2;};
+extern struct ompi_predefined_datatype_t ompi_mpi_2int __attribute__(( type_tag_for_datatype(mpi, struct ompi_struct_mpi_2int, layout_compatible) ));
+#endif
+
+#ifdef MPICH
+// MPICH2 and MVAPICH2-style datatype definitions
+
+#define MPI_COMM_WORLD ((MPI_Comm) 0x44000000)
+
+#define MPI_DATATYPE_NULL ((MPI_Datatype) 0xa0000000)
+#define MPI_FLOAT ((MPI_Datatype) 0xa0000001)
+#define MPI_INT ((MPI_Datatype) 0xa0000002)
+#define MPI_LONG ((MPI_Datatype) 0xa0000003)
+#define MPI_LONG_LONG_INT ((MPI_Datatype) 0xa0000004)
+#define MPI_CHAR ((MPI_Datatype) 0xa0000005)
+
+#define MPI_FLOAT_INT ((MPI_Datatype) 0xa0000006)
+#define MPI_2INT ((MPI_Datatype) 0xa0000007)
+
+#define MPI_IN_PLACE (void *) -1
+
+static const MPI_Datatype mpich_mpi_datatype_null __attribute__(( type_tag_for_datatype(mpi,void,must_be_null) )) = 0xa0000000;
+static const MPI_Datatype mpich_mpi_float __attribute__(( type_tag_for_datatype(mpi,float) )) = 0xa0000001;
+static const MPI_Datatype mpich_mpi_int __attribute__(( type_tag_for_datatype(mpi,int) )) = 0xa0000002;
+static const MPI_Datatype mpich_mpi_long __attribute__(( type_tag_for_datatype(mpi,long) )) = 0xa0000003;
+static const MPI_Datatype mpich_mpi_long_long_int __attribute__(( type_tag_for_datatype(mpi,long long int) )) = 0xa0000004;
+static const MPI_Datatype mpich_mpi_char __attribute__(( type_tag_for_datatype(mpi,char) )) = 0xa0000005;
+
+struct mpich_struct_mpi_float_int { float f; int i; };
+struct mpich_struct_mpi_2int { int i1; int i2; };
+static const MPI_Datatype mpich_mpi_float_int __attribute__(( type_tag_for_datatype(mpi, struct mpich_struct_mpi_float_int, layout_compatible) )) = 0xa0000006;
+static const MPI_Datatype mpich_mpi_2int __attribute__(( type_tag_for_datatype(mpi, struct mpich_struct_mpi_2int, layout_compatible) )) = 0xa0000007;
+#endif
+
+//===--- HDF5 headers mock ------------------------------------------------===//
+
+typedef int hid_t;
+void H5open(void);
+
+#ifndef HDF_PRIVATE
+#define H5OPEN H5open(),
+#else
+#define H5OPEN
+#endif
+
+#define H5T_NATIVE_CHAR (CHAR_MIN?H5T_NATIVE_SCHAR:H5T_NATIVE_UCHAR)
+#define H5T_NATIVE_SCHAR (H5OPEN H5T_NATIVE_SCHAR_g)
+#define H5T_NATIVE_UCHAR (H5OPEN H5T_NATIVE_UCHAR_g)
+#define H5T_NATIVE_INT (H5OPEN H5T_NATIVE_INT_g)
+#define H5T_NATIVE_LONG (H5OPEN H5T_NATIVE_LONG_g)
+
+hid_t H5T_NATIVE_SCHAR_g __attribute__(( type_tag_for_datatype(hdf5,signed char) ));
+hid_t H5T_NATIVE_UCHAR_g __attribute__(( type_tag_for_datatype(hdf5,unsigned char) ));
+hid_t H5T_NATIVE_INT_g __attribute__(( type_tag_for_datatype(hdf5,int) ));
+hid_t H5T_NATIVE_LONG_g __attribute__(( type_tag_for_datatype(hdf5,long) ));
+
+void H5Dwrite(hid_t mem_type_id, const void *buf) __attribute__(( pointer_with_type_tag(hdf5,2,1) ));
+
+//===--- Tests ------------------------------------------------------------===//
+
+//===--- MPI
+
+struct pair_float_int
+{
+ float f; int i;
+};
+
+struct pair_int_int
+{
+ int i1; int i2;
+};
+
+void test_mpi_predefined_types(
+ int *int_buf,
+ long *long_buf1,
+ long *long_buf2,
+ void *void_buf,
+ struct pair_float_int *pfi,
+ struct pair_int_int *pii)
+{
+ char char_buf[255];
+
+ // Layout-compatible scalar types.
+ MPI_Send(int_buf, 1, MPI_INT); // no-warning
+
+ // Layout-compatible class types.
+ MPI_Send(pfi, 1, MPI_FLOAT_INT); // no-warning
+ MPI_Send(pii, 1, MPI_2INT); // no-warning
+
+ // Layout-incompatible scalar types.
+ MPI_Send(long_buf1, 1, MPI_INT); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
+
+ // Layout-incompatible class types.
+ MPI_Send(pii, 1, MPI_FLOAT_INT); // expected-warning {{argument type 'struct pair_int_int *' doesn't match specified 'mpi' type tag}}
+ MPI_Send(pfi, 1, MPI_2INT); // expected-warning {{argument type 'struct pair_float_int *' doesn't match specified 'mpi' type tag}}
+
+ // Layout-incompatible class-scalar types.
+ MPI_Send(long_buf1, 1, MPI_2INT); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag}}
+
+ // Function with two buffers.
+ MPI_Gather(long_buf1, 1, MPI_INT, // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
+ long_buf2, 1, MPI_INT); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
+
+ // Array buffers should work like pointer buffers.
+ MPI_Send(char_buf, 255, MPI_CHAR); // no-warning
+
+ // Explicit casts should not be dropped.
+ MPI_Send((int *) char_buf, 255, MPI_INT); // no-warning
+ MPI_Send((int *) char_buf, 255, MPI_CHAR); // expected-warning {{argument type 'int *' doesn't match specified 'mpi' type tag that requires 'char *'}}
+
+ // `void*' buffer should never warn.
+ MPI_Send(void_buf, 255, MPI_CHAR); // no-warning
+
+ // We expect that MPI_IN_PLACE is `void*', shouldn't warn.
+ MPI_Gather(MPI_IN_PLACE, 0, MPI_INT,
+ int_buf, 1, MPI_INT);
+
+ // Special handling for MPI_DATATYPE_NULL: buffer pointer should be either
+ // a `void*' pointer or a null pointer constant.
+ MPI_Gather(NULL, 0, MPI_DATATYPE_NULL, // no-warning
+ int_buf, 1, MPI_INT);
+
+ MPI_Gather(int_buf, 0, MPI_DATATYPE_NULL, // expected-warning {{specified mpi type tag requires a null pointer}}
+ int_buf, 1, MPI_INT);
+}
+
+MPI_Datatype my_int_datatype __attribute__(( type_tag_for_datatype(mpi,int) ));
+
+struct S1 { int a; int b; };
+MPI_Datatype my_s1_datatype __attribute__(( type_tag_for_datatype(mpi,struct S1) ));
+
+// Layout-compatible to S1, but should be treated as a different type.
+struct S2 { int a; int b; };
+MPI_Datatype my_s2_datatype __attribute__(( type_tag_for_datatype(mpi,struct S2) ));
+
+void test_user_types(int *int_buf,
+ long *long_buf,
+ struct S1 *s1_buf,
+ struct S2 *s2_buf)
+{
+ MPI_Send(int_buf, 1, my_int_datatype); // no-warning
+ MPI_Send(long_buf, 1, my_int_datatype); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
+
+ MPI_Send(s1_buf, 1, my_s1_datatype); // no-warning
+ MPI_Send(s1_buf, 1, my_s2_datatype); // expected-warning {{argument type 'struct S1 *' doesn't match specified 'mpi' type tag that requires 'struct S2 *'}}
+
+ MPI_Send(long_buf, 1, my_s1_datatype); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'struct S1 *'}}
+ MPI_Send(s1_buf, 1, MPI_INT); // expected-warning {{argument type 'struct S1 *' doesn't match specified 'mpi' type tag that requires 'int *'}}
+}
+
+MPI_Datatype my_unknown_datatype;
+
+void test_not_annotated(int *int_buf,
+ long *long_buf,
+ MPI_Datatype type)
+{
+ // Using 'MPI_Datatype's without attributes should not produce warnings.
+ MPI_Send(long_buf, 1, my_unknown_datatype); // no-warning
+ MPI_Send(int_buf, 1, type); // no-warning
+}
+
+struct S1_compat { int a; int b; };
+MPI_Datatype my_s1_compat_datatype
+ __attribute__(( type_tag_for_datatype(mpi, struct S1_compat, layout_compatible) ));
+
+struct S3 { int a; long b; double c; double d; struct S1 s1; };
+struct S3_compat { int a; long b; double c; double d; struct S2 s2; };
+MPI_Datatype my_s3_compat_datatype
+ __attribute__(( type_tag_for_datatype(mpi, struct S3_compat, layout_compatible) ));
+
+struct S4 { char c; };
+struct S4_compat { signed char c; };
+MPI_Datatype my_s4_compat_datatype
+ __attribute__(( type_tag_for_datatype(mpi, struct S4_compat, layout_compatible) ));
+
+union U1 { int a; long b; double c; double d; struct S1 s1; };
+union U1_compat { long b; double c; struct S2 s; int a; double d; };
+MPI_Datatype my_u1_compat_datatype
+ __attribute__(( type_tag_for_datatype(mpi, union U1_compat, layout_compatible) ));
+
+union U2 { int a; long b; double c; struct S1 s1; };
+MPI_Datatype my_u2_datatype
+ __attribute__(( type_tag_for_datatype(mpi, union U2, layout_compatible) ));
+
+void test_layout_compatibility(struct S1 *s1_buf, struct S3 *s3_buf,
+ struct S4 *s4_buf,
+ union U1 *u1_buf, union U2 *u2_buf)
+{
+ MPI_Send(s1_buf, 1, my_s1_compat_datatype); // no-warning
+ MPI_Send(s3_buf, 1, my_s3_compat_datatype); // no-warning
+ MPI_Send(s1_buf, 1, my_s3_compat_datatype); // expected-warning {{argument type 'struct S1 *' doesn't match specified 'mpi' type tag}}
+ MPI_Send(s4_buf, 1, my_s4_compat_datatype); // expected-warning {{argument type 'struct S4 *' doesn't match specified 'mpi' type tag}}
+ MPI_Send(u1_buf, 1, my_u1_compat_datatype); // no-warning
+ MPI_Send(u1_buf, 1, my_u2_datatype); // expected-warning {{argument type 'union U1 *' doesn't match specified 'mpi' type tag}}
+ MPI_Send(u2_buf, 1, my_u1_compat_datatype); // expected-warning {{argument type 'union U2 *' doesn't match specified 'mpi' type tag}}
+}
+
+// There is an MPI_REAL predefined in MPI, but some existing MPI programs do
+// this.
+typedef float real;
+#define MPI_REAL MPI_FLOAT
+
+void test_mpi_real_user_type(real *real_buf, float *float_buf)
+{
+ MPI_Send(real_buf, 1, MPI_REAL); // no-warning
+ MPI_Send(real_buf, 1, MPI_FLOAT); // no-warning
+ MPI_Send(float_buf, 1, MPI_REAL); // no-warning
+ MPI_Send(float_buf, 1, MPI_FLOAT); // no-warning
+}
+
+//===--- HDF5
+
+void test_hdf5(char *char_buf,
+ signed char *schar_buf,
+ unsigned char *uchar_buf,
+ int *int_buf,
+ long *long_buf)
+{
+ H5Dwrite(H5T_NATIVE_CHAR, char_buf); // no-warning
+#ifdef __CHAR_UNSIGNED__
+ H5Dwrite(H5T_NATIVE_CHAR, schar_buf); // expected-warning {{argument type 'signed char *' doesn't match specified 'hdf5' type tag that requires 'unsigned char *'}}
+ H5Dwrite(H5T_NATIVE_CHAR, uchar_buf); // no-warning
+#else
+ H5Dwrite(H5T_NATIVE_CHAR, schar_buf); // no-warning
+ H5Dwrite(H5T_NATIVE_CHAR, uchar_buf); // expected-warning {{argument type 'unsigned char *' doesn't match specified 'hdf5' type tag that requires 'signed char *'}}
+#endif
+ H5Dwrite(H5T_NATIVE_SCHAR, schar_buf); // no-warning
+ H5Dwrite(H5T_NATIVE_UCHAR, uchar_buf); // no-warning
+ H5Dwrite(H5T_NATIVE_INT, int_buf); // no-warning
+ H5Dwrite(H5T_NATIVE_LONG, long_buf); // no-warning
+
+#ifdef __CHAR_UNSIGNED__
+ H5Dwrite(H5T_NATIVE_CHAR, int_buf); // expected-warning {{argument type 'int *' doesn't match specified 'hdf5' type tag that requires 'unsigned char *'}}
+#else
+ H5Dwrite(H5T_NATIVE_CHAR, int_buf); // expected-warning {{argument type 'int *' doesn't match specified 'hdf5' type tag that requires 'signed char *'}}
+#endif
+ H5Dwrite(H5T_NATIVE_INT, long_buf); // expected-warning {{argument type 'long *' doesn't match specified 'hdf5' type tag that requires 'int *'}}
+
+ // FIXME: we should warn here, but it will cause false positives because
+ // different kinds may use same magic values.
+ //H5Dwrite(MPI_INT, int_buf);
+}
+
diff --git a/test/Sema/warn-type-safety.c b/test/Sema/warn-type-safety.c
new file mode 100644
index 000000000000..6f548aa2567d
--- /dev/null
+++ b/test/Sema/warn-type-safety.c
@@ -0,0 +1,152 @@
+// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c++ -std=c++98 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c99 -fno-signed-char -fsyntax-only -verify %s
+
+struct A {};
+
+typedef struct A *MPI_Datatype;
+
+int wrong1(void *buf, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag )); // expected-error {{attribute requires parameter 1 to be an identifier}}
+
+int wrong2(void *buf, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,0,7) )); // expected-error {{attribute parameter 2 is out of bounds}}
+
+int wrong3(void *buf, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,3,7) )); // expected-error {{attribute parameter 2 is out of bounds}}
+
+int wrong4(void *buf, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,1,0) )); // expected-error {{attribute parameter 3 is out of bounds}}
+
+int wrong5(void *buf, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,1,3) )); // expected-error {{attribute parameter 3 is out of bounds}}
+
+int wrong6(void *buf, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,0x8000000000000001ULL,1) )); // expected-error {{attribute parameter 2 is out of bounds}}
+
+extern int x;
+
+int wrong7(void *buf, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,x,2) )); // expected-error {{attribute requires parameter 2 to be an integer constant}}
+
+int wrong8(void *buf, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,1,x) )); // expected-error {{attribute requires parameter 3 to be an integer constant}}
+
+int wrong9 __attribute__(( pointer_with_type_tag(mpi,1,2) )); // expected-error {{attribute only applies to functions and methods}}
+
+int wrong10(double buf, MPI_Datatype type)
+ __attribute__(( pointer_with_type_tag(mpi,1,2) )); // expected-error {{'pointer_with_type_tag' attribute only applies to pointer arguments}}
+
+
+extern struct A datatype_wrong1
+ __attribute__(( type_tag_for_datatype )); // expected-error {{attribute requires parameter 1 to be an identifier}}
+
+extern struct A datatype_wrong2
+ __attribute__(( type_tag_for_datatype(mpi,1,2) )); // expected-error {{expected a type}}
+
+extern struct A datatype_wrong3
+ __attribute__(( type_tag_for_datatype(mpi,not_a_type) )); // expected-error {{unknown type name 'not_a_type'}}
+
+extern struct A datatype_wrong4
+ __attribute__(( type_tag_for_datatype(mpi,int,int) )); // expected-error {{expected identifier}}
+
+extern struct A datatype_wrong5
+ __attribute__(( type_tag_for_datatype(mpi,int,not_a_flag) )); // expected-error {{invalid comparison flag 'not_a_flag'}}
+
+extern struct A datatype_wrong6
+ __attribute__(( type_tag_for_datatype(mpi,int,layout_compatible,not_a_flag) )); // expected-error {{invalid comparison flag 'not_a_flag'}}
+
+
+// Using a tag with kind A in a place where the function requires kind B should
+// warn.
+
+void A_func(void *ptr, void *tag) __attribute__(( pointer_with_type_tag(a,1,2) ));
+
+extern struct A A_tag __attribute__(( type_tag_for_datatype(a,int) ));
+extern struct A B_tag __attribute__(( type_tag_for_datatype(b,int) ));
+
+void C_func(void *ptr, int tag) __attribute__(( pointer_with_type_tag(c,1,2) ));
+
+static const int C_tag __attribute__(( type_tag_for_datatype(c,int) )) = 10;
+static const int D_tag __attribute__(( type_tag_for_datatype(d,int) )) = 20;
+
+void test_tag_mismatch(int *ptr)
+{
+ A_func(ptr, &A_tag); // no-warning
+ A_func(ptr, &B_tag); // expected-warning {{this type tag was not designed to be used with this function}}
+ C_func(ptr, C_tag); // no-warning
+ C_func(ptr, D_tag); // expected-warning {{this type tag was not designed to be used with this function}}
+ C_func(ptr, 10); // no-warning
+ C_func(ptr, 20); // should warn, but may cause false positives
+}
+
+// Check that we look through typedefs in the special case of allowing 'char'
+// to be matched with 'signed char' or 'unsigned char'.
+void E_func(void *ptr, int tag) __attribute__(( pointer_with_type_tag(e,1,2) ));
+
+typedef char E_char;
+typedef char E_char_2;
+typedef signed char E_char_signed;
+typedef unsigned char E_char_unsigned;
+
+static const int E_tag __attribute__(( type_tag_for_datatype(e,E_char) )) = 10;
+
+void test_char_typedef(char *char_buf,
+ E_char_2 *e_char_buf,
+ E_char_signed *e_char_signed_buf,
+ E_char_unsigned *e_char_unsigned_buf)
+{
+ E_func(char_buf, E_tag);
+ E_func(e_char_buf, E_tag);
+#ifdef __CHAR_UNSIGNED__
+ E_func(e_char_signed_buf, E_tag); // expected-warning {{argument type 'E_char_signed *' (aka 'signed char *') doesn't match specified 'e' type tag that requires 'E_char *' (aka 'char *')}}
+ E_func(e_char_unsigned_buf, E_tag);
+#else
+ E_func(e_char_signed_buf, E_tag);
+ E_func(e_char_unsigned_buf, E_tag); // expected-warning {{argument type 'E_char_unsigned *' (aka 'unsigned char *') doesn't match specified 'e' type tag that requires 'E_char *' (aka 'char *')}}
+#endif
+}
+
+// Tests for argument_with_type_tag.
+
+#define F_DUPFD 10
+#define F_SETLK 20
+
+struct flock { };
+
+static const int F_DUPFD_tag __attribute__(( type_tag_for_datatype(fcntl,int) )) = F_DUPFD;
+static const int F_SETLK_tag __attribute__(( type_tag_for_datatype(fcntl,struct flock *) )) = F_SETLK;
+
+int fcntl(int fd, int cmd, ...) __attribute__(( argument_with_type_tag(fcntl,3,2) ));
+
+void test_argument_with_type_tag(struct flock *f)
+{
+ fcntl(0, F_DUPFD, 10); // no-warning
+ fcntl(0, F_SETLK, f); // no-warning
+
+ fcntl(0, F_SETLK, 10); // expected-warning {{argument type 'int' doesn't match specified 'fcntl' type tag that requires 'struct flock *'}}
+ fcntl(0, F_DUPFD, f); // expected-warning {{argument type 'struct flock *' doesn't match specified 'fcntl' type tag that requires 'int'}}
+}
+
+void test_tag_expresssion(int b) {
+ fcntl(0, b ? F_DUPFD : F_SETLK, 10); // no-warning
+ fcntl(0, b + F_DUPFD, 10); // no-warning
+ fcntl(0, (b, F_DUPFD), 10); // expected-warning {{expression result unused}}
+}
+
+// Check that using 64-bit magic values as tags works and tag values do not
+// overflow internally.
+void F_func(void *ptr, unsigned long long tag) __attribute__((pointer_with_type_tag(f,1,2) ));
+
+static const unsigned long long F_tag1 __attribute__(( type_tag_for_datatype(f,int) )) = 0xFFFFFFFFFFFFFFFFULL;
+static const unsigned long long F_tag2 __attribute__(( type_tag_for_datatype(f,float) )) = 0xFFFFFFFFULL;
+
+void test_64bit_magic(int *int_ptr, float *float_ptr)
+{
+ F_func(int_ptr, 0xFFFFFFFFFFFFFFFFULL);
+ F_func(int_ptr, 0xFFFFFFFFULL); // expected-warning {{argument type 'int *' doesn't match specified 'f' type tag that requires 'float *'}}
+ F_func(float_ptr, 0xFFFFFFFFFFFFFFFFULL); // expected-warning {{argument type 'float *' doesn't match specified 'f' type tag that requires 'int *'}}
+ F_func(float_ptr, 0xFFFFFFFFULL);
+}
+
+
diff --git a/test/Sema/warn-type-safety.cpp b/test/Sema/warn-type-safety.cpp
new file mode 100644
index 000000000000..d053fbaa21fc
--- /dev/null
+++ b/test/Sema/warn-type-safety.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct ompi_datatype_t *MPI_Datatype;
+
+#define OMPI_PREDEFINED_GLOBAL(type, global) ((type) &(global))
+
+#define MPI_FLOAT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float)
+#define MPI_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_int)
+#define MPI_NULL OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_null)
+
+extern struct ompi_predefined_datatype_t ompi_mpi_float __attribute__(( type_tag_for_datatype(mpi,float) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_int __attribute__(( type_tag_for_datatype(mpi,int) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_null __attribute__(( type_tag_for_datatype(mpi,void,must_be_null) ));
+
+int f(int x) { return x; }
+static const int wrong_init __attribute__(( type_tag_for_datatype(zzz,int) )) = f(100); // expected-error {{'type_tag_for_datatype' attribute requires the initializer to be an integral constant expression}}
+
+//===--- Tests ------------------------------------------------------------===//
+// Check that hidden 'this' is handled correctly.
+
+class C
+{
+public:
+ void f1(void *buf, int count, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,5,6) )); // expected-error {{attribute parameter 2 is out of bounds}}
+
+ void f2(void *buf, int count, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,2,5) )); // expected-error {{attribute parameter 3 is out of bounds}}
+
+ void f3(void *buf, int count, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,1,5) )); // expected-error {{attribute is invalid for the implicit this argument}}
+
+ void f4(void *buf, int count, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,2,1) )); // expected-error {{attribute is invalid for the implicit this argument}}
+
+ void MPI_Send(void *buf, int count, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,2,4) )); // no-error
+};
+
+// Check that we don't crash on type and value dependent expressions.
+template<int a>
+void value_dep(void *buf, int count, MPI_Datatype datatype)
+ __attribute__(( pointer_with_type_tag(mpi,a,5) )); // expected-error {{attribute requires parameter 2 to be an integer constant}}
+
+class OperatorIntStar
+{
+public:
+ operator int*();
+};
+
+void test1(C *c, int *int_buf)
+{
+ c->MPI_Send(int_buf, 1, MPI_INT); // no-warning
+ c->MPI_Send(int_buf, 1, MPI_FLOAT); // expected-warning {{argument type 'int *' doesn't match specified 'mpi' type tag that requires 'float *'}}
+
+ OperatorIntStar i;
+ c->MPI_Send(i, 1, MPI_INT); // no-warning
+ c->MPI_Send(i, 1, MPI_FLOAT); // expected-warning {{argument type 'int *' doesn't match specified 'mpi' type tag that requires 'float *'}}
+}
+
+template<typename T>
+void test2(C *c, int *int_buf, T tag)
+{
+ c->MPI_Send(int_buf, 1, tag); // no-warning
+}
+
+void test3(C *c, int *int_buf) {
+ test2(c, int_buf, MPI_INT);
+ test2(c, int_buf, MPI_NULL);
+}
+
diff --git a/test/SemaCXX/convert-to-bool.cpp b/test/SemaCXX/convert-to-bool.cpp
index c9a355549fdf..b52f11c93d39 100644
--- a/test/SemaCXX/convert-to-bool.cpp
+++ b/test/SemaCXX/convert-to-bool.cpp
@@ -62,6 +62,5 @@ struct C {
void test_copy_init_conversions(C c) {
A &a = c; // expected-error{{no viable conversion from 'C' to 'A'}}
- B &b = b; // okay
+ B &b = c; // okay
}
-
diff --git a/test/SemaCXX/pragma-pack.cpp b/test/SemaCXX/pragma-pack.cpp
index 1bc738b087a9..5c1d5c6c82af 100644
--- a/test/SemaCXX/pragma-pack.cpp
+++ b/test/SemaCXX/pragma-pack.cpp
@@ -32,3 +32,26 @@ struct Sub : virtual Base {
int check[sizeof(Sub) == 13 ? 1 : -1];
}
+
+namespace llvm_support_endian {
+
+template<typename, bool> struct X;
+
+#pragma pack(push)
+#pragma pack(1)
+template<typename T> struct X<T, true> {
+ T t;
+};
+#pragma pack(pop)
+
+#pragma pack(push)
+#pragma pack(2)
+template<> struct X<long double, true> {
+ long double c;
+};
+#pragma pack(pop)
+
+int check1[__alignof(X<int, true>) == 1 ? 1 : -1];
+int check2[__alignof(X<long double, true>) == 2 ? 1 : -1];
+
+}
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index 70d3799a0ea5..028c6909210e 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -136,4 +136,4 @@ namespace PR8608 {
}
// The following crashed trying to recursively evaluate the LValue.
-const int &do_not_crash = do_not_crash;
+const int &do_not_crash = do_not_crash; // expected-warning{{variable 'do_not_crash' is uninitialized when used within its own initialization}}
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index 13d287bf1af6..385548b51cca 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -316,3 +316,84 @@ namespace {
G(char (*)[8]) : f3(new F(f3->*ptr)) {} // expected-warning {{field is uninitialized when used here}}
};
}
+
+namespace statics {
+ static int a = a; // no-warning: used to signal intended lack of initialization.
+ static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
+ static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
+ static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
+ static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+
+ // Thes don't warn as they don't require the value.
+ static int g = sizeof(g);
+ int gg = g; // Silence unneeded warning
+ static void* ptr = &ptr;
+ static int h = bar(&h);
+ static int i = boo(i);
+ static int j = far(j);
+ static int k = __alignof__(k);
+
+ static int l = k ? l : l; // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
+ static int m = 1 + (k ? m : m); // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
+ static int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+
+ void test() {
+ static int a = a; // no-warning: used to signal intended lack of initialization.
+ static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
+ static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
+ static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}}
+ static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
+ static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+
+ // Thes don't warn as they don't require the value.
+ static int g = sizeof(g);
+ static void* ptr = &ptr;
+ static int h = bar(&h);
+ static int i = boo(i);
+ static int j = far(j);
+ static int k = __alignof__(k);
+
+ static int l = k ? l : l; // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
+ static int m = 1 + (k ? m : m); // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
+ static int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+ for (;;) {
+ static int a = a; // no-warning: used to signal intended lack of initialization.
+ static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
+ static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
+ static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}}
+ static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
+ static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+
+ // Thes don't warn as they don't require the value.
+ static int g = sizeof(g);
+ static void* ptr = &ptr;
+ static int h = bar(&h);
+ static int i = boo(i);
+ static int j = far(j);
+ static int k = __alignof__(k);
+
+ static int l = k ? l : l; // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
+ static int m = 1 + (k ? m : m); // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
+ static int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+ }
+ }
+}
+
+namespace references {
+ int &a = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}}
+
+ struct S {
+ S() : a(a) {} // expected-warning{{field is uninitialized when used here}}
+ int &a;
+ };
+
+ void f() {
+ int &a = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}}
+ }
+
+ struct T {
+ T() : a(b), b(a) {} // FIXME: Warn here.
+ int &a, &b;
+ int &c = c; // FIXME: Warn here.
+ };
+}
diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp
index 3f8a7359088d..8aa6a91a9d2d 100644
--- a/test/SemaCXX/warn-thread-safety-parsing.cpp
+++ b/test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -1429,4 +1429,14 @@ class Foo {
}
+namespace InvalidDeclTest {
+
+class Foo { };
+namespace {
+void Foo::bar(Mutex* mu) LOCKS_EXCLUDED(mu) { } // \
+ // expected-error {{cannot define or redeclare 'bar' here because namespace '' does not enclose namespace 'Foo'}} \
+ // expected-warning {{attribute locks_excluded ignored, because it is not attached to a declaration}}
+}
+
+} // end namespace InvalidDeclTest
diff --git a/test/SemaObjC/warn-cast-of-sel-expr.m b/test/SemaObjC/warn-cast-of-sel-expr.m
new file mode 100644
index 000000000000..97915a0094ef
--- /dev/null
+++ b/test/SemaObjC/warn-cast-of-sel-expr.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wcast-of-sel-type -Wno-unused-value %s
+// rdar://12107381
+
+SEL s;
+
+SEL sel_registerName(const char *);
+
+int main() {
+(char *)s; // expected-warning {{cast of type 'SEL' to 'char *' is deprecated; use sel_getName instead}}
+(void *)s; // ok
+(const char *)sel_registerName("foo"); // expected-warning {{cast of type 'SEL' to 'const char *' is deprecated; use sel_getName instead}}
+
+(const void *)sel_registerName("foo"); // ok
+
+(void) s; // ok
+
+(void *const)s; // ok
+
+(const void *const)s; // ok
+}
diff --git a/test/SemaObjCXX/abstract-class-type-ivar.mm b/test/SemaObjCXX/abstract-class-type-ivar.mm
new file mode 100644
index 000000000000..823e9c197d35
--- /dev/null
+++ b/test/SemaObjCXX/abstract-class-type-ivar.mm
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://12095239
+
+class CppAbstractBase {
+public:
+ virtual void testA() = 0;
+ virtual void testB() = 0; // expected-note {{unimplemented pure virtual method 'testB' in 'CppConcreteSub}}
+ int a;
+};
+
+class CppConcreteSub : public CppAbstractBase {
+ virtual void testA() { }
+};
+
+@interface Objc {
+ CppConcreteSub _concrete; // expected-error{{ivar type 'CppConcreteSub' is an abstract class}}
+}
+- (CppAbstractBase*)abstract;
+@end
+@implementation Objc
+- (CppAbstractBase*)abstract {
+ return &_concrete;
+}
+@end
+
+class Cpp {
+public:
+ CppConcreteSub sub; // expected-error {{field type 'CppConcreteSub' is an abstract class}}
+};
diff --git a/test/Tooling/clang-check-ast-dump.cpp b/test/Tooling/clang-check-ast-dump.cpp
index 86533af3e11d..e29072bcfe87 100644
--- a/test/Tooling/clang-check-ast-dump.cpp
+++ b/test/Tooling/clang-check-ast-dump.cpp
@@ -22,6 +22,10 @@
// CHECK-LIST-NEXT: test_namespace::TheClass
// CHECK-LIST-NEXT: test_namespace::TheClass::theMethod
// CHECK-LIST-NEXT: x
+//
+// RUN: clang-check -ast-dump -ast-dump-filter test_namespace::TheClass::n "%s" -- 2>&1 | FileCheck -check-prefix CHECK-ATTR %s
+// CHECK-ATTR: test_namespace
+// CHECK-ATTR-NEXT: int n __attribute__((aligned((BinaryOperator
namespace test_namespace {
@@ -30,6 +34,7 @@ public:
int theMethod(int x) {
return x + x;
}
+ int n __attribute__((aligned(1+1)));
};
}