diff options
author | dim <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
commit | ea266cad53e3d49771fa38103913d3ec7a166694 (patch) | |
tree | 8f7776b7310bebaf415ac5b69e46e9f928c37144 /test | |
parent | c72c57c9e9b69944e3e009cd5e209634839581d3 (diff) | |
download | FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.zip FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.tar.gz |
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3
release):
http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_33/final@183502
Diffstat (limited to 'test')
556 files changed, 16693 insertions, 2762 deletions
diff --git a/test/ARCMT/check-with-serialized-diag.m b/test/ARCMT/check-with-serialized-diag.m index d8073d0..77bad96 100644 --- a/test/ARCMT/check-with-serialized-diag.m +++ b/test/ARCMT/check-with-serialized-diag.m @@ -43,13 +43,13 @@ void test1(A *a, struct UnsafeS *unsafeS) { // CHECK-NEXT: Number FIXITs = 0 // CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:4: error: [rewriter] it is not safe to remove 'retain' message on a global variable // CHECK-NEXT: Number FIXITs = 0 -// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:32:4: error: ARC forbids explicit message send of 'retain' -// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:32:23 {{.*}}check-with-serialized-diag.m:32:29 +// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:32:23: error: ARC forbids explicit message send of 'retain' +// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:32:4 {{.*}}check-with-serialized-diag.m:32:22 // CHECK-NEXT: Number FIXITs = 0 -// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:4: error: ARC forbids explicit message send of 'retain' -// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:34:15 {{.*}}check-with-serialized-diag.m:34:21 +// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:15: error: ARC forbids explicit message send of 'retain' +// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:34:4 {{.*}}check-with-serialized-diag.m:34:14 // CHECK-NEXT: Number FIXITs = 0 -// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:35:4: error: ARC forbids explicit message send of 'retainCount' -// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:35:6 {{.*}}check-with-serialized-diag.m:35:17 +// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:35:6: error: ARC forbids explicit message send of 'retainCount' +// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:35:4 {{.*}}check-with-serialized-diag.m:35:5 // CHECK-NEXT: Number FIXITs = 0 diff --git a/test/ARCMT/migrate-plist-output.m b/test/ARCMT/migrate-plist-output.m index 12efa93..377dce3 100644 --- a/test/ARCMT/migrate-plist-output.m +++ b/test/ARCMT/migrate-plist-output.m @@ -26,7 +26,7 @@ void test(id p) { // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>10</integer> -// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <key>ranges</key> @@ -34,12 +34,12 @@ void test(id p) { // CHECK: <array> // CHECK: <dict> // CHECK: <key>line</key><integer>10</integer> -// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>10</integer> -// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> diff --git a/test/ARCMT/objcmt-subscripting-literals.m b/test/ARCMT/objcmt-subscripting-literals.m index 8cef091..014c109 100644 --- a/test/ARCMT/objcmt-subscripting-literals.m +++ b/test/ARCMT/objcmt-subscripting-literals.m @@ -157,6 +157,7 @@ typedef const struct __CFString * CFStringRef; dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", [NSArray array], nil] forKeys:[NSArray arrayWithObjects:@"A", [arr objectAtIndex:2], nil]]; dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", @"2", nil] forKeys:arr]; dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", @"2", nil] forKeys:@[@"A", @"B"]]; + dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray array], @"A", [NSArray array], @"B", nil]; } @end diff --git a/test/ARCMT/objcmt-subscripting-literals.m.result b/test/ARCMT/objcmt-subscripting-literals.m.result index 0ca6dca..e9ff8df 100644 --- a/test/ARCMT/objcmt-subscripting-literals.m.result +++ b/test/ARCMT/objcmt-subscripting-literals.m.result @@ -157,6 +157,7 @@ typedef const struct __CFString * CFStringRef; dict = @{@"A": @"1", arr[2]: @[]}; dict = [NSDictionary dictionaryWithObjects:@[@"1", @"2"] forKeys:arr]; dict = @{@"A": @"1", @"B": @"2"}; + dict = @{@"A": @[], @"B": @[]}; } @end diff --git a/test/ASTMerge/function.c b/test/ASTMerge/function.c index 320bca2..8a8a030 100644 --- a/test/ASTMerge/function.c +++ b/test/ASTMerge/function.c @@ -9,7 +9,7 @@ // CHECK: function1.c:4:6: note: declared here with type 'void (void)' // CHECK: 2 errors generated -// expected-error@3 {{external function 'f1' declared with incompatible types}} -// expected-note@2 {{declared here}} -// expected-error@5 {{external function 'f3' declared with incompatible types}} -// expected-note@4 {{declared here}} +// expected-error@Inputs/function2.c:3 {{external function 'f1' declared with incompatible types}} +// expected-note@Inputs/function1.c:2 {{declared here}} +// expected-error@Inputs/function2.c:5 {{external function 'f3' declared with incompatible types}} +// expected-note@Inputs/function1.c:4 {{declared here}} diff --git a/test/Analysis/Inputs/system-header-simulator-cxx.h b/test/Analysis/Inputs/system-header-simulator-cxx.h index eee0e31..6e434a0 100644 --- a/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -80,6 +80,12 @@ namespace std { *OI++ = *II++; return OI; } + + struct input_iterator_tag { }; + struct output_iterator_tag { }; + struct forward_iterator_tag : public input_iterator_tag { }; + struct bidirectional_iterator_tag : public forward_iterator_tag { }; + struct random_access_iterator_tag : public bidirectional_iterator_tag { }; } void* operator new(std::size_t, const std::nothrow_t&) throw(); diff --git a/test/Analysis/Inputs/system-header-simulator.h b/test/Analysis/Inputs/system-header-simulator.h index 04688c78..dd1cd49 100644 --- a/test/Analysis/Inputs/system-header-simulator.h +++ b/test/Analysis/Inputs/system-header-simulator.h @@ -5,6 +5,10 @@ // suppressed. #pragma clang system_header +#ifdef __cplusplus +#define restrict /*restrict*/ +#endif + typedef struct _FILE FILE; extern FILE *stdin; extern FILE *stdout; @@ -14,8 +18,11 @@ extern FILE *__stdinp; extern FILE *__stdoutp; extern FILE *__stderrp; - +int scanf(const char *restrict format, ...); int fscanf(FILE *restrict, const char *restrict, ...); +int printf(const char *restrict format, ...); +int fprintf(FILE *restrict, const char *restrict, ...); +int getchar(void); // Note, on some platforms errno macro gets replaced with a function call. extern int errno; @@ -37,6 +44,8 @@ typedef __darwin_off_t fpos_t; void setbuf(FILE * restrict, char * restrict); int setvbuf(FILE * restrict, char * restrict, int, size_t); +FILE *fopen(const char * restrict, const char * restrict); +int fclose(FILE *); FILE *funopen(const void *, int (*)(void *, char *, int), int (*)(void *, const char *, int), diff --git a/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp index b0bb173..5a596d4 100644 --- a/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp +++ b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp @@ -1,8 +1,7 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,alpha.cplusplus.NewDelete -analyzer-store region -std=c++11 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete -std=c++11 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s -typedef __typeof(sizeof(int)) size_t; -void *malloc(size_t); -void free(void *); +#include "Inputs/system-header-simulator-for-malloc.h" //-------------------------------------------------- // Check that unix.Malloc catches all types of bugs. @@ -15,7 +14,7 @@ void testMallocDoubleFree() { void testMallocLeak() { int *p = (int *)malloc(sizeof(int)); -} // expected-warning{{Memory is never released; potential leak of memory pointed to by 'p'}} +} // expected-warning{{Potential leak of memory pointed to by 'p'}} void testMallocUseAfterFree() { int *p = (int *)malloc(sizeof(int)); @@ -52,7 +51,10 @@ void testNewDoubleFree() { void testNewLeak() { int *p = new int; -} // expected-warning{{Memory is never released; potential leak of memory pointed to by 'p'}} +} +#ifdef LEAKS +// expected-warning@-2 {{Potential leak of memory pointed to by 'p'}} +#endif void testNewUseAfterFree() { int *p = (int *)operator new(0); @@ -69,3 +71,35 @@ void testNewOffsetFree() { int *p = new int; operator delete(++p); // expected-warning{{Argument to operator delete is offset by 4 bytes from the start of memory allocated by 'new'}} } + +//---------------------------------------------------------------- +// Test that we check for free errors on escaped pointers. +//---------------------------------------------------------------- +void changePtr(int **p); +static int *globalPtr; +void changePointee(int *p); + +void testMismatchedChangePtrThroughCall() { + int *p = (int*)malloc(sizeof(int)*4); + changePtr(&p); + delete p; // no-warning the value of the pointer might have changed +} + +void testMismatchedChangePointeeThroughCall() { + int *p = (int*)malloc(sizeof(int)*4); + changePointee(p); + delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} +} + +void testShouldReportDoubleFreeNotMismatched() { + int *p = (int*)malloc(sizeof(int)*4); + globalPtr = p; + free(p); + delete globalPtr; // expected-warning {{Attempt to free released memory}} +} + +void testMismatchedChangePointeeThroughAssignment() { + int *arr = new int[4]; + globalPtr = arr; + delete arr; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}} +}
\ No newline at end of file diff --git a/test/Analysis/Malloc+NewDelete_intersections.cpp b/test/Analysis/Malloc+NewDelete_intersections.cpp index 7a0ef8e..3106636 100644 --- a/test/Analysis/Malloc+NewDelete_intersections.cpp +++ b/test/Analysis/Malloc+NewDelete_intersections.cpp @@ -1,14 +1,15 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,alpha.cplusplus.NewDelete -analyzer-store region -std=c++11 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete -std=c++11 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks -std=c++11 -verify %s typedef __typeof(sizeof(int)) size_t; void *malloc(size_t); void free(void *); //------------------------------------------------------------------- -// Check that unix.Malloc + alpha.cplusplus.NewDelete does not enable +// Check that unix.Malloc + cplusplus.NewDelete does not enable // warnings produced by unix.MismatchedDeallocator. //------------------------------------------------------------------- void testMismatchedDeallocator() { int *p = (int *)malloc(sizeof(int)); delete p; -} // expected-warning{{Memory is never released; potential leak of memory pointed to by 'p'}} +} // expected-warning{{Potential leak of memory pointed to by 'p'}} diff --git a/test/Analysis/alloc-match-dealloc.mm b/test/Analysis/MismatchedDeallocator-checker-test.mm index 56d46d9..56d46d9 100644 --- a/test/Analysis/alloc-match-dealloc.mm +++ b/test/Analysis/MismatchedDeallocator-checker-test.mm diff --git a/test/Analysis/MismatchedDeallocator-path-notes.cpp b/test/Analysis/MismatchedDeallocator-path-notes.cpp new file mode 100644 index 0000000..369d8f6 --- /dev/null +++ b/test/Analysis/MismatchedDeallocator-path-notes.cpp @@ -0,0 +1,159 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=text -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=plist %s -o %t.plist +// RUN: FileCheck --input-file=%t.plist %s + +void changePointee(int *p); +void test() { + int *p = new int[1]; + // expected-note@-1 {{Memory is allocated}} + changePointee(p); + delete p; // expected-warning {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}} + // expected-note@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}} +} + +// CHECK: <key>diagnostics</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Memory is allocated</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Memory is allocated</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'</string> +// CHECK-NEXT: <key>category</key><string>Memory Error</string> +// CHECK-NEXT: <key>type</key><string>Bad deallocator</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>test</string> +// CHECK-NEXT: <key>issue_hash</key><string>4</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> diff --git a/test/Analysis/NSContainers.m b/test/Analysis/NSContainers.m index d6fded5..540c7a4 100644 --- a/test/Analysis/NSContainers.m +++ b/test/Analysis/NSContainers.m @@ -115,32 +115,32 @@ void testNilArgNSArray1() { // NSMutableDictionary and NSDictionary APIs. void testNilArgNSMutableDictionary1(NSMutableDictionary *d, NSString* key) { - [d setObject:0 forKey:key]; // expected-warning {{Argument to 'NSMutableDictionary' method 'setObject:forKey:' cannot be nil}} + [d setObject:0 forKey:key]; // expected-warning {{Value argument to 'setObject:forKey:' cannot be nil}} } void testNilArgNSMutableDictionary2(NSMutableDictionary *d, NSObject *obj) { - [d setObject:obj forKey:0]; // expected-warning {{Argument to 'NSMutableDictionary' method 'setObject:forKey:' cannot be nil}} + [d setObject:obj forKey:0]; // expected-warning {{Key argument to 'setObject:forKey:' cannot be nil}} } void testNilArgNSMutableDictionary3(NSMutableDictionary *d) { - [d removeObjectForKey:0]; // expected-warning {{Argument to 'NSMutableDictionary' method 'removeObjectForKey:' cannot be nil}} + [d removeObjectForKey:0]; // expected-warning {{Value argument to 'removeObjectForKey:' cannot be nil}} } void testNilArgNSMutableDictionary5(NSMutableDictionary *d, NSString* key) { - d[key] = 0; // expected-warning {{Dictionary object cannot be nil}} + d[key] = 0; // expected-warning {{Value stored into 'NSMutableDictionary' cannot be nil}} } void testNilArgNSMutableDictionary6(NSMutableDictionary *d, NSString *key) { if (key) ; - d[key] = 0; // expected-warning {{Dictionary key cannot be nil}} - // expected-warning@-1 {{Dictionary object cannot be nil}} + d[key] = 0; // expected-warning {{'NSMutableDictionary' key cannot be nil}} + // expected-warning@-1 {{Value stored into 'NSMutableDictionary' cannot be nil}} } NSDictionary *testNilArgNSDictionary1(NSString* key) { - return [NSDictionary dictionaryWithObject:0 forKey:key]; // expected-warning {{Argument to 'NSDictionary' method 'dictionaryWithObject:forKey:' cannot be nil}} + return [NSDictionary dictionaryWithObject:0 forKey:key]; // expected-warning {{Value argument to 'dictionaryWithObject:forKey:' cannot be nil}} } NSDictionary *testNilArgNSDictionary2(NSObject *obj) { - return [NSDictionary dictionaryWithObject:obj forKey:0]; // expected-warning {{Argument to 'NSDictionary' method 'dictionaryWithObject:forKey:' cannot be nil}} + return [NSDictionary dictionaryWithObject:obj forKey:0]; // expected-warning {{Key argument to 'dictionaryWithObject:forKey:' cannot be nil}} } // Test inline defensive checks suppression. diff --git a/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp index 23b70b8..b606f23 100644 --- a/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp +++ b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.cplusplus.NewDelete,unix.MismatchedDeallocator -analyzer-store region -std=c++11 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,unix.MismatchedDeallocator -std=c++11 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks,unix.MismatchedDeallocator -DLEAKS -std=c++11 -verify %s // expected-no-diagnostics typedef __typeof(sizeof(int)) size_t; diff --git a/test/Analysis/NewDelete-checker-test.cpp b/test/Analysis/NewDelete-checker-test.cpp index c31d7f3..5d134bc 100644 --- a/test/Analysis/NewDelete-checker-test.cpp +++ b/test/Analysis/NewDelete-checker-test.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.cplusplus.NewDelete -analyzer-store region -std=c++11 -fblocks -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s #include "Inputs/system-header-simulator-cxx.h" typedef __typeof__(sizeof(int)) size_t; @@ -12,29 +13,46 @@ int *global; //----- Standard non-placement operators void testGlobalOpNew() { void *p = operator new(0); -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif void testGlobalOpNewArray() { void *p = operator new[](0); -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif void testGlobalNewExpr() { int *p = new int; -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif void testGlobalNewExprArray() { int *p = new int[0]; -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif //----- Standard nothrow placement operators void testGlobalNoThrowPlacementOpNewBeforeOverload() { void *p = operator new(0, std::nothrow); -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif void testGlobalNoThrowPlacementExprNewBeforeOverload() { int *p = new(std::nothrow) int; -} // expected-warning{{Memory is never released; potential leak}} - +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif //----- Standard pointer placement operators void testGlobalPointerPlacementNew() { @@ -72,14 +90,59 @@ void testNewInvalidationPlacement(PtrWrapper *w) { // other checks //--------------- -void f(int *); +class SomeClass { +public: + void f(int *p); +}; -void testUseAfterDelete() { +void f(int *p1, int *p2 = 0, int *p3 = 0); +void g(SomeClass &c, ...); + +void testUseFirstArgAfterDelete() { int *p = new int; delete p; f(p); // expected-warning{{Use of memory after it is freed}} } +void testUseMiddleArgAfterDelete(int *p) { + delete p; + f(0, p); // expected-warning{{Use of memory after it is freed}} +} + +void testUseLastArgAfterDelete(int *p) { + delete p; + f(0, 0, p); // expected-warning{{Use of memory after it is freed}} +} + +void testUseSeveralArgsAfterDelete(int *p) { + delete p; + f(p, p, p); // expected-warning{{Use of memory after it is freed}} +} + +void testUseRefArgAfterDelete(SomeClass &c) { + delete &c; + g(c); // expected-warning{{Use of memory after it is freed}} +} + +void testVariadicArgAfterDelete() { + SomeClass c; + int *p = new int; + delete p; + g(c, 0, p); // expected-warning{{Use of memory after it is freed}} +} + +void testUseMethodArgAfterDelete(int *p) { + SomeClass *c = new SomeClass; + delete p; + c->f(p); // expected-warning{{Use of memory after it is freed}} +} + +void testUseThisAfterDelete() { + SomeClass *c = new SomeClass; + delete c; + c->f(0); // expected-warning{{Use of memory after it is freed}} +} + void testDeleteAlloca() { int *p = (int *)__builtin_alloca(sizeof(int)); delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}} diff --git a/test/Analysis/NewDelete-custom.cpp b/test/Analysis/NewDelete-custom.cpp index 7d7796b..c64bfce 100644 --- a/test/Analysis/NewDelete-custom.cpp +++ b/test/Analysis/NewDelete-custom.cpp @@ -1,6 +1,12 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.cplusplus.NewDelete,unix.Malloc -analyzer-store region -std=c++11 -fblocks -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,unix.Malloc -std=c++11 -fblocks -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -DLEAKS -fblocks -verify %s #include "Inputs/system-header-simulator-cxx.h" +#ifndef LEAKS +// expected-no-diagnostics +#endif + + void *allocator(std::size_t size); void *operator new[](std::size_t size) throw() { return allocator(size); } @@ -19,7 +25,10 @@ void testNewMethod() { C *p2 = new C; // no warn C *c3 = ::new C; -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'c3'}} +#endif void testOpNewArray() { void *p = operator new[](0); // call is inlined, no warn @@ -27,7 +36,11 @@ void testOpNewArray() { void testNewExprArray() { int *p = new int[0]; -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif + //----- Custom non-placement operators void testOpNew() { @@ -36,16 +49,26 @@ void testOpNew() { void testNewExpr() { int *p = new int; -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif + //----- Custom NoThrow placement operators void testOpNewNoThrow() { void *p = operator new(0, std::nothrow); -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif void testNewExprNoThrow() { int *p = new(std::nothrow) int; -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif //----- Custom placement operators void testOpNewPlacement() { diff --git a/test/Analysis/NewDelete-intersections.mm b/test/Analysis/NewDelete-intersections.mm index 3a87e4f..9024ed5 100644 --- a/test/Analysis/NewDelete-intersections.mm +++ b/test/Analysis/NewDelete-intersections.mm @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.cplusplus.NewDelete -analyzer-store region -std=c++11 -fblocks -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks -std=c++11 -DLEAKS -fblocks -verify %s #include "Inputs/system-header-simulator-cxx.h" #include "Inputs/system-header-simulator-objc.h" @@ -39,16 +40,25 @@ void testDeleteMalloced() { void testFreeOpNew() { void *p = operator new(0); free(p); -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2 {{Potential leak of memory pointed to by 'p'}} +#endif void testFreeNewExpr() { int *p = new int; free(p); -} // expected-warning{{Memory is never released; potential leak}} +} +#ifdef LEAKS +// expected-warning@-2 {{Potential leak of memory pointed to by 'p'}} +#endif void testObjcFreeNewed() { int *p = new int; - NSData *nsdata = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Memory is never released; potential leak}} + NSData *nsdata = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; +#ifdef LEAKS + // expected-warning@-2 {{Potential leak of memory pointed to by 'p'}} +#endif } void testFreeAfterDelete() { diff --git a/test/Analysis/NewDelete-path-notes.cpp b/test/Analysis/NewDelete-path-notes.cpp index eeb6105..85b71be 100644 --- a/test/Analysis/NewDelete-path-notes.cpp +++ b/test/Analysis/NewDelete-path-notes.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.NewDelete,unix.Malloc -analyzer-output=text -verify %s -// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.NewDelete,unix.Malloc -analyzer-output=plist %s -o %t.plist +// RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=text -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=plist %s -o %t.plist // RUN: FileCheck --input-file=%t.plist %s void test() { @@ -15,80 +15,68 @@ void test() { // expected-note@-1 {{Attempt to free released memory}} } +struct Odd { + void kill() { + delete this; // expected-note {{Memory is released}} + } +}; + +void test(Odd *odd) { + odd->kill(); // expected-note{{Calling 'Odd::kill'}} + // expected-note@-1 {{Returning; memory was released}} + delete odd; // expected-warning {{Attempt to free released memory}} + // expected-note@-1 {{Attempt to free released memory}} +} + // CHECK: <key>diagnostics</key> -// CHECK-NEXT:<array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>path</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>6</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>6</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>6</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>6</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>14</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>line</key><integer>6</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <key>ranges</key> -// CHECK-NEXT: <array> +// CHECK-NEXT: <key>ranges</key> // CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>18</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>0</integer> -// CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is allocated</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is allocated</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> @@ -97,227 +85,467 @@ void test() { // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Memory is allocated</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Memory is allocated</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>6</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>6</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Assuming 'p' is non-null</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Assuming 'p' is non-null</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Memory is released</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Memory is released</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <key>ranges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> // CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Attempt to free released memory</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Attempt to free released memory</string> +// CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>0</integer> -// CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Assuming 'p' is non-null</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Assuming 'p' is non-null</string> +// CHECK-NEXT: <key>description</key><string>Attempt to free released memory</string> +// CHECK-NEXT: <key>category</key><string>Memory Error</string> +// CHECK-NEXT: <key>type</key><string>Double free</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>test</string> +// CHECK-NEXT: <key>issue_hash</key><string>9</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <key>line</key><integer>25</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>line</key><integer>25</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>line</key><integer>25</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling 'Odd::kill'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling 'Odd::kill'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Entered call from 'test'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'test'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>20</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>20</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>20</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>11</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>20</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>11</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>line</key><integer>20</integer> +// CHECK-NEXT: <key>col</key><integer>13</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>11</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <key>ranges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>11</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>11</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>0</integer> -// CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is released</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is released</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Memory is released</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Memory is released</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <key>line</key><integer>25</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>11</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>25</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>11</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>line</key><integer>25</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Returning; memory was released</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Returning; memory was released</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>25</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>25</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>27</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>27</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>27</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>line</key><integer>27</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>line</key><integer>27</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <key>ranges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> // CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Attempt to free released memory</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Attempt to free released memory</string> +// CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>0</integer> -// CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Attempt to free released memory</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Attempt to free released memory</string> +// CHECK-NEXT: <key>description</key><string>Attempt to free released memory</string> +// CHECK-NEXT: <key>category</key><string>Memory Error</string> +// CHECK-NEXT: <key>type</key><string>Double free</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>test</string> +// CHECK-NEXT: <key>issue_hash</key><string>3</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>27</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Attempt to free released memory</string> -// CHECK-NEXT: <key>category</key><string>Memory Error</string> -// CHECK-NEXT: <key>type</key><string>Double free</string> -// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> -// CHECK-NEXT: <key>issue_context</key><string>test</string> -// CHECK-NEXT: <key>issue_hash</key><string>9</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </dict> -// CHECK-NEXT:</array> diff --git a/test/Analysis/NewDelete-variadic.cpp b/test/Analysis/NewDelete-variadic.cpp index 129af1f..53dba46 100644 --- a/test/Analysis/NewDelete-variadic.cpp +++ b/test/Analysis/NewDelete-variadic.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.cplusplus.NewDelete,unix.Malloc -analyzer-store region -std=c++11 -fblocks -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -fblocks -verify %s // expected-no-diagnostics namespace std { diff --git a/test/Analysis/analyzer-config.c b/test/Analysis/analyzer-config.c index 96b9483..55b1df9 100644 --- a/test/Analysis/analyzer-config.c +++ b/test/Analysis/analyzer-config.c @@ -1,4 +1,4 @@ -// RUN: %clang --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper > %t 2>&1 +// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper > %t 2>&1 // RUN: FileCheck --input-file=%t %s void bar() {} @@ -11,10 +11,12 @@ void foo() { bar(); } // CHECK-NEXT: graph-trim-interval = 1000 // CHECK-NEXT: ipa = dynamic-bifurcate // CHECK-NEXT: ipa-always-inline-size = 3 +// CHECK-NEXT: leak-diagnostics-reference-allocation = false // CHECK-NEXT: max-inlinable-size = 50 // CHECK-NEXT: max-nodes = 150000 // CHECK-NEXT: max-times-inline-large = 32 // CHECK-NEXT: mode = deep +// CHECK-NEXT: region-store-small-struct-limit = 2 // CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 10 +// CHECK-NEXT: num-entries = 12 diff --git a/test/Analysis/analyzer-config.cpp b/test/Analysis/analyzer-config.cpp index 1224204..bf18a5e 100644 --- a/test/Analysis/analyzer-config.cpp +++ b/test/Analysis/analyzer-config.cpp @@ -1,4 +1,4 @@ -// RUN: %clang --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper > %t 2>&1 +// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper > %t 2>&1 // RUN: FileCheck --input-file=%t %s void bar() {} @@ -21,9 +21,11 @@ public: // CHECK-NEXT: graph-trim-interval = 1000 // CHECK-NEXT: ipa = dynamic-bifurcate // CHECK-NEXT: ipa-always-inline-size = 3 +// CHECK-NEXT: leak-diagnostics-reference-allocation = false // CHECK-NEXT: max-inlinable-size = 50 // CHECK-NEXT: max-nodes = 150000 // CHECK-NEXT: max-times-inline-large = 32 // CHECK-NEXT: mode = deep +// CHECK-NEXT: region-store-small-struct-limit = 2 // CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 14 +// CHECK-NEXT: num-entries = 16 diff --git a/test/Analysis/bool-assignment.cpp b/test/Analysis/bool-assignment.c index 9361d93..0f782fb 100644 --- a/test/Analysis/bool-assignment.cpp +++ b/test/Analysis/bool-assignment.c @@ -1,27 +1,32 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -std=c99 -Dbool=_Bool %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -x c++ %s -// Test C++'s bool +// Test C++'s bool and C's _Bool. +// FIXME: We stopped warning on these when SValBuilder got smarter about +// casts to bool. Arguably, however, these conversions are okay; the result +// is always 'true' or 'false'. -void test_cppbool_initialization(int y) { +void test_stdbool_initialization(int y) { + bool constant = 2; // no-warning if (y < 0) { - bool x = y; // expected-warning {{Assignment of a non-Boolean value}} + bool x = y; // no-warning return; } if (y > 1) { - bool x = y; // expected-warning {{Assignment of a non-Boolean value}} + bool x = y; // no-warning return; } bool x = y; // no-warning } -void test_cppbool_assignment(int y) { +void test_stdbool_assignment(int y) { bool x = 0; // no-warning if (y < 0) { - x = y; // expected-warning {{Assignment of a non-Boolean value}} + x = y; // no-warning return; } if (y > 1) { - x = y; // expected-warning {{Assignment of a non-Boolean value}} + x = y; // no-warning return; } x = y; // no-warning @@ -32,6 +37,7 @@ void test_cppbool_assignment(int y) { typedef signed char BOOL; void test_BOOL_initialization(int y) { + BOOL constant = 2; // expected-warning {{Assignment of a non-Boolean value}} if (y < 0) { BOOL x = y; // expected-warning {{Assignment of a non-Boolean value}} return; @@ -62,6 +68,7 @@ void test_BOOL_assignment(int y) { typedef unsigned char Boolean; void test_Boolean_initialization(int y) { + Boolean constant = 2; // expected-warning {{Assignment of a non-Boolean value}} if (y < 0) { Boolean x = y; // expected-warning {{Assignment of a non-Boolean value}} return; diff --git a/test/Analysis/bool-assignment2.c b/test/Analysis/bool-assignment2.c deleted file mode 100644 index 22f4237..0000000 --- a/test/Analysis/bool-assignment2.c +++ /dev/null @@ -1,35 +0,0 @@ -// RUN: %clang_cc1 -std=c99 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify %s - -// Test stdbool.h's _Bool - -// Prior to C99, stdbool.h uses this typedef, but even in ANSI C mode, _Bool -// appears to be defined. - -// #if __STDC_VERSION__ < 199901L -// typedef int _Bool; -// #endif - -void test_stdbool_initialization(int y) { - if (y < 0) { - _Bool x = y; // expected-warning {{Assignment of a non-Boolean value}} - return; - } - if (y > 1) { - _Bool x = y; // expected-warning {{Assignment of a non-Boolean value}} - return; - } - _Bool x = y; // no-warning -} - -void test_stdbool_assignment(int y) { - _Bool x = 0; // no-warning - if (y < 0) { - x = y; // expected-warning {{Assignment of a non-Boolean value}} - return; - } - if (y > 1) { - x = y; // expected-warning {{Assignment of a non-Boolean value}} - return; - } - x = y; // no-warning -} diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c index 087bd97..3e2f807 100644 --- a/test/Analysis/casts.c +++ b/test/Analysis/casts.c @@ -1,6 +1,7 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s -// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s -// expected-no-diagnostics +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s +// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s + +extern void clang_analyzer_eval(_Bool); // Test if the 'storage' region gets properly initialized after it is cast to // 'struct sockaddr *'. @@ -85,3 +86,34 @@ int foo (int* p) { } return 0; } + +void castsToBool() { + clang_analyzer_eval(0); // expected-warning{{FALSE}} + clang_analyzer_eval(0U); // expected-warning{{FALSE}} + clang_analyzer_eval((void *)0); // expected-warning{{FALSE}} + + clang_analyzer_eval(1); // expected-warning{{TRUE}} + clang_analyzer_eval(1U); // expected-warning{{TRUE}} + clang_analyzer_eval(-1); // expected-warning{{TRUE}} + clang_analyzer_eval(0x100); // expected-warning{{TRUE}} + clang_analyzer_eval(0x100U); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)0x100); // expected-warning{{TRUE}} + + extern int symbolicInt; + clang_analyzer_eval(symbolicInt); // expected-warning{{UNKNOWN}} + if (symbolicInt) + clang_analyzer_eval(symbolicInt); // expected-warning{{TRUE}} + + extern void *symbolicPointer; + clang_analyzer_eval(symbolicPointer); // expected-warning{{UNKNOWN}} + if (symbolicPointer) + clang_analyzer_eval(symbolicPointer); // expected-warning{{TRUE}} + + int localInt; + clang_analyzer_eval(&localInt); // expected-warning{{TRUE}} + clang_analyzer_eval(&castsToBool); // expected-warning{{TRUE}} + clang_analyzer_eval("abc"); // expected-warning{{TRUE}} + + extern float globalFloat; + clang_analyzer_eval(globalFloat); // expected-warning{{UNKNOWN}} +} diff --git a/test/Analysis/conditional-operator-path-notes.c b/test/Analysis/conditional-operator-path-notes.c index c781ddf..a8af394 100644 --- a/test/Analysis/conditional-operator-path-notes.c +++ b/test/Analysis/conditional-operator-path-notes.c @@ -242,12 +242,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>10</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>10</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -259,7 +259,7 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>10</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -293,7 +293,7 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>10</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -882,12 +882,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>44</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>44</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -899,7 +899,7 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>44</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -933,7 +933,7 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>44</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> diff --git a/test/Analysis/conditional-operator.cpp b/test/Analysis/conditional-operator.cpp new file mode 100644 index 0000000..5a3c325 --- /dev/null +++ b/test/Analysis/conditional-operator.cpp @@ -0,0 +1,17 @@ +// RUN: %clang -cc1 -analyze -analyzer-checker=core,debug.ExprInspection %s -analyzer-output=text -verify + +void clang_analyzer_eval(bool); + +// Test that the analyzer does not crash on GNU extension operator "?:". +void NoCrashTest(int x, int y) { + int w = x ?: y; +} + +void OperatorEvaluationTest(int y) { + int x = 1; + int w = x ?: y; // expected-note {{'?' condition is true}} + + // TODO: We are not precise when processing the "?:" operator in C++. + clang_analyzer_eval(w == 1); // expected-warning{{UNKNOWN}} + // expected-note@-1{{UNKNOWN}} +}
\ No newline at end of file diff --git a/test/Analysis/coverage.c b/test/Analysis/coverage.c index 38e84e1..9e437d21 100644 --- a/test/Analysis/coverage.c +++ b/test/Analysis/coverage.c @@ -33,26 +33,26 @@ static void function_which_doesnt_give_up_nested(int *x, int *y) { void coverage1(int *x) { function_which_gives_up(x); char *m = (char*)malloc(12); -} // expected-warning {{potential leak}} +} // expected-warning {{Potential leak of memory pointed to by 'm'}} void coverage2(int *x) { if (x) { function_which_gives_up(x); char *m = (char*)malloc(12); } -} // expected-warning {{potential leak}} +} // expected-warning {{Potential leak of memory pointed to by 'm'}} void coverage3(int *x) { x++; function_which_gives_up(x); char *m = (char*)malloc(12); -} // expected-warning {{potential leak}} +} // expected-warning {{Potential leak of memory pointed to by 'm'}} void coverage4(int *x) { *x += another_function(x); function_which_gives_up(x); char *m = (char*)malloc(12); -} // expected-warning {{potential leak}} +} // expected-warning {{Potential leak of memory pointed to by 'm'}} void coverage5(int *x) { for (int i = 0; i<7; ++i) @@ -66,7 +66,7 @@ void coverage6(int *x) { function_which_gives_up(x); } char *m = (char*)malloc(12); -} // expected-warning {{potential leak}} +} // expected-warning {{Potential leak of memory pointed to by 'm'}} int coverage7_inline(int *i) { function_which_doesnt_give_up(&i); @@ -78,7 +78,7 @@ void coverage8(int *x) { function_which_doesnt_give_up_nested(x, &y); y = (*x)/y; // expected-warning {{Division by zero}} char *m = (char*)malloc(12); -} // expected-warning {{potential leak}} +} // expected-warning {{Potential leak of memory pointed to by 'm'}} void function_which_gives_up_settonull(int **x) { *x = 0; diff --git a/test/Analysis/cstring-syntax-cxx.cpp b/test/Analysis/cstring-syntax-cxx.cpp index bae3d0a..39c978a 100644 --- a/test/Analysis/cstring-syntax-cxx.cpp +++ b/test/Analysis/cstring-syntax-cxx.cpp @@ -15,3 +15,8 @@ void test(X a, X b) { X c = a + b; } +// Ensure we don't crash on custom-defined strncat. +char strncat (); +int main () { + return strncat (); +}
\ No newline at end of file diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c index 165a12b..067a050 100644 --- a/test/Analysis/dead-stores.c +++ b/test/Analysis/dead-stores.c @@ -547,3 +547,25 @@ int *radar11185138_baz() { return y; } +int getInt(); +int *getPtr(); +void testBOComma() { + int x0 = (getInt(), 0); // expected-warning{{unused variable 'x0'}} + int x1 = (getInt(), getInt()); // expected-warning {{Value stored to 'x1' during its initialization is never read}} // expected-warning{{unused variable 'x1'}} + int x2 = (getInt(), getInt(), getInt()); //expected-warning{{Value stored to 'x2' during its initialization is never read}} // expected-warning{{unused variable 'x2'}} + int x3; + x3 = (getInt(), getInt(), 0); // expected-warning{{Value stored to 'x3' is never read}} + int x4 = (getInt(), (getInt(), 0)); // expected-warning{{unused variable 'x4'}} + int y; + int x5 = (getInt(), (y = 0)); // expected-warning{{unused variable 'x5'}} + int x6 = (getInt(), (y = getInt())); //expected-warning {{Value stored to 'x6' during its initialization is never read}} // expected-warning{{unused variable 'x6'}} + int x7 = 0, x8 = getInt(); //expected-warning {{Value stored to 'x8' during its initialization is never read}} // expected-warning{{unused variable 'x8'}} // expected-warning{{unused variable 'x7'}} + int x9 = getInt(), x10 = 0; //expected-warning {{Value stored to 'x9' during its initialization is never read}} // expected-warning{{unused variable 'x9'}} // expected-warning{{unused variable 'x10'}} + int m = getInt(), mm, mmm; //expected-warning {{Value stored to 'm' during its initialization is never read}} // expected-warning{{unused variable 'm'}} // expected-warning{{unused variable 'mm'}} // expected-warning{{unused variable 'mmm'}} + int n, nn = getInt(); //expected-warning {{Value stored to 'nn' during its initialization is never read}} // expected-warning{{unused variable 'n'}} // expected-warning{{unused variable 'nn'}} + + int *p; + p = (getPtr(), (int *)0); // no warning + +} + diff --git a/test/Analysis/derived-to-base.cpp b/test/Analysis/derived-to-base.cpp index b846d2c..0664189 100644 --- a/test/Analysis/derived-to-base.cpp +++ b/test/Analysis/derived-to-base.cpp @@ -2,6 +2,7 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -DCONSTRUCTORS=1 -analyzer-config c++-inlining=constructors -verify %s void clang_analyzer_eval(bool); +void clang_analyzer_checkInlined(bool); class A { protected: @@ -363,3 +364,89 @@ namespace Redeclaration { } }; +namespace PR15394 { + namespace Original { + class Base { + public: + virtual int f() = 0; + int i; + }; + + class Derived1 : public Base { + public: + int j; + }; + + class Derived2 : public Derived1 { + public: + virtual int f() { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + return i + j; + } + }; + + void testXXX() { + Derived1 *d1p = reinterpret_cast<Derived1*>(new Derived2); + d1p->i = 1; + d1p->j = 2; + clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}} + } + } + + namespace VirtualInDerived { + class Base { + public: + int i; + }; + + class Derived1 : public Base { + public: + virtual int f() = 0; + int j; + }; + + class Derived2 : public Derived1 { + public: + virtual int f() { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + return i + j; + } + }; + + void test() { + Derived1 *d1p = reinterpret_cast<Derived1*>(new Derived2); + d1p->i = 1; + d1p->j = 2; + clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}} + } + } + + namespace NoCast { + class Base { + public: + int i; + }; + + class Derived1 : public Base { + public: + virtual int f() = 0; + int j; + }; + + class Derived2 : public Derived1 { + public: + virtual int f() { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + return i + j; + } + }; + + void test() { + Derived1 *d1p = new Derived2; + d1p->i = 1; + d1p->j = 2; + clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}} + } + } +}; + diff --git a/test/Analysis/diagnostics/deref-track-symbolic-region.c b/test/Analysis/diagnostics/deref-track-symbolic-region.c index 94774dd..03716de 100644 --- a/test/Analysis/diagnostics/deref-track-symbolic-region.c +++ b/test/Analysis/diagnostics/deref-track-symbolic-region.c @@ -24,6 +24,21 @@ void test(struct S syz, int *pp) { // expected-note@-1{{Dereference of null pointer (loaded from field 'x')}} } +void testTrackConstraintBRVisitorIsTrackingTurnedOn(struct S syz, int *pp) { + int m = 0; + syz.x = foo(); // expected-note{{Value assigned to 'syz.x'}} + + struct S *ps = &syz; + if (ps->x) + //expected-note@-1{{Taking false branch}} + //expected-note@-2{{Assuming pointer value is null}} + + m++; + int *p = syz.x; //expected-note {{'p' initialized to a null pointer value}} + m = *p; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}} + // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}} +} + // CHECK: <key>diagnostics</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> @@ -300,6 +315,341 @@ void test(struct S syz, int *pp) { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>28</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>28</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>29</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>29</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>29</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>29</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>29</integer> +// CHECK-NEXT: <key>col</key><integer>15</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Value assigned to 'syz.x'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Value assigned to 'syz.x'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>29</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>29</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>32</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>32</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>32</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>32</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>32</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>32</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>32</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>32</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>32</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Assuming pointer value is null</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Assuming pointer value is null</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>32</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>32</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>37</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>37</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>37</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>37</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>37</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>'p' initialized to a null pointer value</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>'p' initialized to a null pointer value</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>37</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>37</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>testTrackConstraintBRVisitorIsTrackingTurnedOn</string> +// CHECK-NEXT: <key>issue_hash</key><string>11</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </plist> diff --git a/test/Analysis/diagnostics/explicit-suppression.cpp b/test/Analysis/diagnostics/explicit-suppression.cpp index 79afeed..57d2d16 100644 --- a/test/Analysis/diagnostics/explicit-suppression.cpp +++ b/test/Analysis/diagnostics/explicit-suppression.cpp @@ -12,69 +12,6 @@ void clang_analyzer_eval(bool); void testCopyNull(int *I, int *E) { std::copy(I, E, (int *)0); #ifndef SUPPRESSED - // This line number comes from system-header-simulator-cxx.h. - // expected-warning@79 {{Dereference of null pointer}} + // expected-warning@../Inputs/system-header-simulator-cxx.h:80 {{Dereference of null pointer}} #endif } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// PR15613: expected-* can't refer to diagnostics in other source files. -// The current implementation only matches line numbers, but has an upper limit -// of the number of lines in the main source file. diff --git a/test/Analysis/diagnostics/undef-value-param.c b/test/Analysis/diagnostics/undef-value-param.c index 597bf91..5855f50 100644 --- a/test/Analysis/diagnostics/undef-value-param.c +++ b/test/Analysis/diagnostics/undef-value-param.c @@ -328,7 +328,7 @@ double testPassingParentRegionStruct(int x) { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'foo'</string> // CHECK-NEXT: <key>message</key> @@ -390,46 +390,12 @@ double testPassingParentRegionStruct(int x) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>26</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>26</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>26</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>26</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>26</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>26</integer> -// CHECK-NEXT: <key>col</key><integer>13</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -441,7 +407,7 @@ double testPassingParentRegionStruct(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>26</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -475,7 +441,7 @@ double testPassingParentRegionStruct(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>26</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -713,7 +679,7 @@ double testPassingParentRegionStruct(int x) { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'initArray'</string> // CHECK-NEXT: <key>message</key> @@ -741,46 +707,12 @@ double testPassingParentRegionStruct(int x) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>42</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>42</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>42</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>42</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>42</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>42</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -792,7 +724,7 @@ double testPassingParentRegionStruct(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>42</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -826,7 +758,7 @@ double testPassingParentRegionStruct(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>42</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1127,7 +1059,7 @@ double testPassingParentRegionStruct(int x) { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'initStruct'</string> // CHECK-NEXT: <key>message</key> diff --git a/test/Analysis/diagnostics/undef-value-param.m b/test/Analysis/diagnostics/undef-value-param.m index d6c8a16..4de83bf 100644 --- a/test/Analysis/diagnostics/undef-value-param.m +++ b/test/Analysis/diagnostics/undef-value-param.m @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=text -verify %s -// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=plist-multi-file %s -o - | FileCheck %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=plist-multi-file %s -o %t.plist +// RUN: FileCheck --input-file=%t.plist %s typedef signed char BOOL; @protocol NSObject - (BOOL)isEqual:(id)object; @end @@ -86,12 +87,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>34</integer> +// CHECK-NEXT: <key>line</key><integer>35</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>34</integer> +// CHECK-NEXT: <key>line</key><integer>35</integer> // CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -99,12 +100,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>35</integer> +// CHECK-NEXT: <key>line</key><integer>36</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>35</integer> +// CHECK-NEXT: <key>line</key><integer>36</integer> // CHECK-NEXT: <key>col</key><integer>13</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -116,7 +117,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>35</integer> +// CHECK-NEXT: <key>line</key><integer>36</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -124,12 +125,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>35</integer> +// CHECK-NEXT: <key>line</key><integer>36</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>35</integer> +// CHECK-NEXT: <key>line</key><integer>36</integer> // CHECK-NEXT: <key>col</key><integer>27</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -145,7 +146,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>52</integer> +// CHECK-NEXT: <key>line</key><integer>53</integer> // CHECK-NEXT: <key>col</key><integer>1</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -163,12 +164,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>52</integer> +// CHECK-NEXT: <key>line</key><integer>53</integer> // CHECK-NEXT: <key>col</key><integer>1</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>52</integer> +// CHECK-NEXT: <key>line</key><integer>53</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -176,12 +177,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>54</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>54</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -197,12 +198,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>54</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>54</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -210,12 +211,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>55</integer> +// CHECK-NEXT: <key>line</key><integer>56</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>55</integer> +// CHECK-NEXT: <key>line</key><integer>56</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -231,12 +232,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>55</integer> +// CHECK-NEXT: <key>line</key><integer>56</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>55</integer> +// CHECK-NEXT: <key>line</key><integer>56</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -244,12 +245,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>55</integer> +// CHECK-NEXT: <key>line</key><integer>56</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>55</integer> +// CHECK-NEXT: <key>line</key><integer>56</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -261,7 +262,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>55</integer> +// CHECK-NEXT: <key>line</key><integer>56</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -269,12 +270,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>55</integer> +// CHECK-NEXT: <key>line</key><integer>56</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>55</integer> +// CHECK-NEXT: <key>line</key><integer>56</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -294,12 +295,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>55</integer> +// CHECK-NEXT: <key>line</key><integer>56</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>55</integer> +// CHECK-NEXT: <key>line</key><integer>56</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -307,12 +308,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>58</integer> +// CHECK-NEXT: <key>line</key><integer>59</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>58</integer> +// CHECK-NEXT: <key>line</key><integer>59</integer> // CHECK-NEXT: <key>col</key><integer>17</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -328,12 +329,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>58</integer> +// CHECK-NEXT: <key>line</key><integer>59</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>58</integer> +// CHECK-NEXT: <key>line</key><integer>59</integer> // CHECK-NEXT: <key>col</key><integer>17</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -341,12 +342,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>line</key><integer>60</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>line</key><integer>60</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -358,7 +359,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>line</key><integer>60</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -366,12 +367,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>line</key><integer>60</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>line</key><integer>60</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -391,12 +392,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>line</key><integer>60</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>line</key><integer>60</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -404,12 +405,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>61</integer> +// CHECK-NEXT: <key>line</key><integer>62</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>61</integer> +// CHECK-NEXT: <key>line</key><integer>62</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -421,7 +422,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>61</integer> +// CHECK-NEXT: <key>line</key><integer>62</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -429,12 +430,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>61</integer> +// CHECK-NEXT: <key>line</key><integer>62</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>61</integer> +// CHECK-NEXT: <key>line</key><integer>62</integer> // CHECK-NEXT: <key>col</key><integer>19</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -450,7 +451,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>35</integer> +// CHECK-NEXT: <key>line</key><integer>36</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -458,18 +459,18 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>35</integer> +// CHECK-NEXT: <key>line</key><integer>36</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>35</integer> +// CHECK-NEXT: <key>line</key><integer>36</integer> // CHECK-NEXT: <key>col</key><integer>27</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'CreateRef'</string> // CHECK-NEXT: <key>message</key> @@ -483,12 +484,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>35</integer> +// CHECK-NEXT: <key>line</key><integer>36</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>35</integer> +// CHECK-NEXT: <key>line</key><integer>36</integer> // CHECK-NEXT: <key>col</key><integer>13</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -496,12 +497,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>line</key><integer>39</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>line</key><integer>39</integer> // CHECK-NEXT: <key>col</key><integer>13</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -513,7 +514,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>line</key><integer>39</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -521,12 +522,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>line</key><integer>39</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>line</key><integer>39</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -547,7 +548,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>issue_hash</key><string>5</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>38</integer> +// CHECK-NEXT: <key>line</key><integer>39</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -559,7 +560,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>43</integer> +// CHECK-NEXT: <key>line</key><integer>44</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -567,12 +568,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>43</integer> +// CHECK-NEXT: <key>line</key><integer>44</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>43</integer> +// CHECK-NEXT: <key>line</key><integer>44</integer> // CHECK-NEXT: <key>col</key><integer>30</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -592,12 +593,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>43</integer> +// CHECK-NEXT: <key>line</key><integer>44</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>43</integer> +// CHECK-NEXT: <key>line</key><integer>44</integer> // CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -605,12 +606,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>44</integer> +// CHECK-NEXT: <key>line</key><integer>45</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>44</integer> +// CHECK-NEXT: <key>line</key><integer>45</integer> // CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -622,7 +623,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>44</integer> +// CHECK-NEXT: <key>line</key><integer>45</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -630,12 +631,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>44</integer> +// CHECK-NEXT: <key>line</key><integer>45</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>44</integer> +// CHECK-NEXT: <key>line</key><integer>45</integer> // CHECK-NEXT: <key>col</key><integer>32</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -651,7 +652,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>65</integer> // CHECK-NEXT: <key>col</key><integer>1</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -669,12 +670,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>65</integer> // CHECK-NEXT: <key>col</key><integer>1</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>65</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -682,12 +683,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>65</integer> +// CHECK-NEXT: <key>line</key><integer>66</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>65</integer> +// CHECK-NEXT: <key>line</key><integer>66</integer> // CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -703,12 +704,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>65</integer> +// CHECK-NEXT: <key>line</key><integer>66</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>65</integer> +// CHECK-NEXT: <key>line</key><integer>66</integer> // CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -716,12 +717,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>68</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>68</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -737,12 +738,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>68</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>68</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -750,12 +751,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>68</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>68</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -767,7 +768,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>68</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -775,12 +776,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>68</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>68</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -800,12 +801,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>68</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>68</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -813,12 +814,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>70</integer> +// CHECK-NEXT: <key>line</key><integer>71</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>70</integer> +// CHECK-NEXT: <key>line</key><integer>71</integer> // CHECK-NEXT: <key>col</key><integer>13</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -830,7 +831,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>44</integer> +// CHECK-NEXT: <key>line</key><integer>45</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -838,18 +839,18 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>44</integer> +// CHECK-NEXT: <key>line</key><integer>45</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>44</integer> +// CHECK-NEXT: <key>line</key><integer>45</integer> // CHECK-NEXT: <key>col</key><integer>32</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'CreateRefUndef'</string> // CHECK-NEXT: <key>message</key> @@ -863,12 +864,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>44</integer> +// CHECK-NEXT: <key>line</key><integer>45</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>44</integer> +// CHECK-NEXT: <key>line</key><integer>45</integer> // CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -876,12 +877,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>47</integer> +// CHECK-NEXT: <key>line</key><integer>48</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>47</integer> +// CHECK-NEXT: <key>line</key><integer>48</integer> // CHECK-NEXT: <key>col</key><integer>13</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -893,7 +894,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>47</integer> +// CHECK-NEXT: <key>line</key><integer>48</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -901,12 +902,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>47</integer> +// CHECK-NEXT: <key>line</key><integer>48</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>47</integer> +// CHECK-NEXT: <key>line</key><integer>48</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -927,7 +928,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) { // CHECK-NEXT: <key>issue_hash</key><string>5</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>47</integer> +// CHECK-NEXT: <key>line</key><integer>48</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> diff --git a/test/Analysis/enum.cpp b/test/Analysis/enum.cpp new file mode 100644 index 0000000..571fa7b --- /dev/null +++ b/test/Analysis/enum.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=debug.ExprInspection %s + +void clang_analyzer_eval(bool); + +enum class Foo { + Zero +}; + +bool pr15703(int x) { + return Foo::Zero == (Foo)x; // don't crash +} + +void testCasting(int i) { + Foo f = static_cast<Foo>(i); + int j = static_cast<int>(f); + if (i == 0) + { + clang_analyzer_eval(f == Foo::Zero); // expected-warning{{TRUE}} + clang_analyzer_eval(j == 0); // expected-warning{{TRUE}} + } + else + { + clang_analyzer_eval(f == Foo::Zero); // expected-warning{{FALSE}} + clang_analyzer_eval(j == 0); // expected-warning{{FALSE}} + } +} diff --git a/test/Analysis/global-region-invalidation.c b/test/Analysis/global-region-invalidation.c index 77de9dd..bff2201 100644 --- a/test/Analysis/global-region-invalidation.c +++ b/test/Analysis/global-region-invalidation.c @@ -44,7 +44,10 @@ int testErrnoSystem() { fscanf(stdin, "%d", &i); // errno gets invalidated here. return 5 / errno; // no-warning } - return 0; + + errno = 0; + fscanf(stdin, "%d", &i); // errno gets invalidated here. + return 5 / errno; // no-warning } // Test that errno gets invalidated by internal calls. diff --git a/test/Analysis/global_region_invalidation.mm b/test/Analysis/global_region_invalidation.mm index f853470..2369c09 100644 --- a/test/Analysis/global_region_invalidation.mm +++ b/test/Analysis/global_region_invalidation.mm @@ -2,6 +2,8 @@ void clang_analyzer_eval(int); +#include "Inputs/system-header-simulator.h" + void use(int); id foo(int x) { if (x) @@ -19,27 +21,168 @@ void testGlobalRef() { } extern int globalInt; +struct IntWrapper { + int value; +}; +extern struct IntWrapper globalStruct; extern void invalidateGlobals(); void testGlobalInvalidation() { + clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}} + if (globalInt != 42) return; + if (globalStruct.value != 43) + return; clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{TRUE}} invalidateGlobals(); clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}} -} + clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}} + // Repeat to make sure we don't get the /same/ new symbolic values. + if (globalInt != 42) + return; + if (globalStruct.value != 43) + return; + clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{TRUE}} -//--------------------------------- -// False negatives -//--------------------------------- + invalidateGlobals(); + clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}} +} void testGlobalInvalidationWithDirectBinding() { + clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}} + globalInt = 42; + globalStruct.value = 43; clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{TRUE}} invalidateGlobals(); - // FIXME: Should be UNKNOWN. - clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}} +} + +void testStaticLocals(void) { + static int i; + int tmp; + + extern int someSymbolicValue(); + i = someSymbolicValue(); + + if (i == 5) { + clang_analyzer_eval(i == 5); // expected-warning{{TRUE}} + scanf("%d", &tmp); + clang_analyzer_eval(i == 5); // expected-warning{{TRUE}} + invalidateGlobals(); + clang_analyzer_eval(i == 5); // expected-warning{{TRUE}} + } + + i = 6; + clang_analyzer_eval(i == 6); // expected-warning{{TRUE}} + scanf("%d", &tmp); + clang_analyzer_eval(i == 6); // expected-warning{{TRUE}} + invalidateGlobals(); + clang_analyzer_eval(i == 6); // expected-warning{{TRUE}} + + i = someSymbolicValue(); + if (i == 7) { + clang_analyzer_eval(i == 7); // expected-warning{{TRUE}} + scanf("%d", &i); + clang_analyzer_eval(i == 7); // expected-warning{{UNKNOWN}} + } + + i = 8; + clang_analyzer_eval(i == 8); // expected-warning{{TRUE}} + scanf("%d", &i); + clang_analyzer_eval(i == 8); // expected-warning{{UNKNOWN}} +} + +void testNonSystemGlobals(void) { + extern int i; + int tmp; + + if (i == 5) { + clang_analyzer_eval(i == 5); // expected-warning{{TRUE}} + scanf("%d", &tmp); + clang_analyzer_eval(i == 5); // expected-warning{{TRUE}} + invalidateGlobals(); + clang_analyzer_eval(i == 5); // expected-warning{{UNKNOWN}} + } + + i = 6; + clang_analyzer_eval(i == 6); // expected-warning{{TRUE}} + scanf("%d", &tmp); + clang_analyzer_eval(i == 6); // expected-warning{{TRUE}} + invalidateGlobals(); + clang_analyzer_eval(i == 6); // expected-warning{{UNKNOWN}} + + if (i == 7) { + clang_analyzer_eval(i == 7); // expected-warning{{TRUE}} + scanf("%d", &i); + clang_analyzer_eval(i == 7); // expected-warning{{UNKNOWN}} + } + + i = 8; + clang_analyzer_eval(i == 8); // expected-warning{{TRUE}} + scanf("%d", &i); + clang_analyzer_eval(i == 8); // expected-warning{{UNKNOWN}} +} + +void testWrappedGlobals(void) { + extern char c; + SomeStruct s; + + if (c == 'C') { + s.p = &c; + clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}} + fakeSystemHeaderCall(0); + clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}} + fakeSystemHeaderCall(&s); + clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}} + } + + c = 'c'; + s.p = &c; + clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}} + fakeSystemHeaderCall(0); + clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}} + fakeSystemHeaderCall(&s); + clang_analyzer_eval(c == 'c'); // expected-warning{{UNKNOWN}} + + if (c == 'C') { + s.p = &c; + clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}} + fakeSystemHeaderCall(0); + clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}} + fakeSystemHeaderCall(&s); + clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}} + } +} + +void testWrappedStaticsViaGlobal(void) { + static char c; + extern SomeStruct s; + + extern char getSomeChar(); + c = getSomeChar(); + + if (c == 'C') { + s.p = &c; + clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}} + invalidateGlobals(); + clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}} + } + + c = 'c'; + s.p = &c; + clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}} + invalidateGlobals(); + clang_analyzer_eval(c == 'c'); // expected-warning{{UNKNOWN}} } diff --git a/test/Analysis/inline-plist.c b/test/Analysis/inline-plist.c index a2dd98a..dcdd23f 100644 --- a/test/Analysis/inline-plist.c +++ b/test/Analysis/inline-plist.c @@ -244,12 +244,12 @@ void test_block_arg() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>18</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>18</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -261,7 +261,7 @@ void test_block_arg() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>18</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -295,7 +295,7 @@ void test_block_arg() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>18</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -443,11 +443,45 @@ void test_block_arg() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>23</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>23</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>23</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>23</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>23</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -481,7 +515,7 @@ void test_block_arg() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>23</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -760,11 +794,45 @@ void test_block_arg() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>33</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>33</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>33</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>33</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>33</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -798,7 +866,7 @@ void test_block_arg() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>33</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -946,11 +1014,45 @@ void test_block_arg() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>60</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>60</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>60</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>60</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>60</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -981,7 +1083,7 @@ void test_block_arg() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>60</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1214,7 +1316,7 @@ void test_block_arg() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning to caller</string> // CHECK-NEXT: <key>message</key> @@ -1229,40 +1331,6 @@ void test_block_arg() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>66</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>66</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>66</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>66</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>66</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1339,12 +1407,12 @@ void test_block_arg() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>70</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>70</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -1356,7 +1424,7 @@ void test_block_arg() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>70</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1390,7 +1458,7 @@ void test_block_arg() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>70</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1560,7 +1628,7 @@ void test_block_arg() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning to caller</string> // CHECK-NEXT: <key>message</key> @@ -1588,12 +1656,12 @@ void test_block_arg() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>78</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>78</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -1605,7 +1673,7 @@ void test_block_arg() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>78</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1639,7 +1707,7 @@ void test_block_arg() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>78</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1809,7 +1877,7 @@ void test_block_arg() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning to caller</string> // CHECK-NEXT: <key>message</key> @@ -1837,12 +1905,12 @@ void test_block_arg() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>86</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>86</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -1854,7 +1922,7 @@ void test_block_arg() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>86</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1888,7 +1956,7 @@ void test_block_arg() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>86</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> diff --git a/test/Analysis/inline-unique-reports.c b/test/Analysis/inline-unique-reports.c index 9a8cd7f..5c42135 100644 --- a/test/Analysis/inline-unique-reports.c +++ b/test/Analysis/inline-unique-reports.c @@ -15,172 +15,290 @@ void test_bug_2() { bug(p); } -// CHECK: <?xml version="1.0" encoding="UTF-8"?> -// CHECK: <plist version="1.0"> -// CHECK: <dict> -// CHECK: <key>files</key> -// CHECK: <array> -// CHECK: </array> -// CHECK: <key>diagnostics</key> -// CHECK: <array> -// 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>14</integer> -// CHECK: <key>col</key><integer>3</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>14</integer> -// CHECK: <key>col</key><integer>5</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>15</integer> -// CHECK: <key>col</key><integer>3</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>15</integer> -// CHECK: <key>col</key><integer>5</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>15</integer> -// CHECK: <key>col</key><integer>3</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>15</integer> -// CHECK: <key>col</key><integer>3</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>15</integer> -// CHECK: <key>col</key><integer>8</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>Calling 'bug'</string> -// CHECK: <key>message</key> -// CHECK: <string>Calling 'bug'</string> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>kind</key><string>event</string> -// CHECK: <key>location</key> -// CHECK: <dict> -// CHECK: <key>line</key><integer>4</integer> -// CHECK: <key>col</key><integer>1</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <key>depth</key><integer>1</integer> -// CHECK: <key>extended_message</key> -// CHECK: <string>Entered call from 'test_bug_2'</string> -// CHECK: <key>message</key> -// CHECK: <string>Entered call from 'test_bug_2'</string> -// CHECK: </dict> -// 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>4</integer> -// CHECK: <key>col</key><integer>1</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>4</integer> -// CHECK: <key>col</key><integer>6</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>5</integer> -// CHECK: <key>col</key><integer>3</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>5</integer> -// CHECK: <key>col</key><integer>3</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>5</integer> -// CHECK: <key>col</key><integer>3</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>5</integer> -// CHECK: <key>col</key><integer>4</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>5</integer> -// CHECK: <key>col</key><integer>4</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: </array> -// CHECK: </array> -// CHECK: <key>depth</key><integer>1</integer> -// CHECK: <key>extended_message</key> -// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> -// CHECK: <key>message</key> -// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> -// CHECK: </dict> -// CHECK: </array> -// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string> -// CHECK: <key>category</key><string>Logic error</string> -// CHECK: <key>type</key><string>Dereference of null pointer</string> -// CHECK: <key>issue_context_kind</key><string>function</string> -// CHECK: <key>issue_context</key><string>bug</string> -// CHECK: <key>issue_hash</key><string>1</string> -// CHECK: <key>location</key> -// CHECK: <dict> -// CHECK: <key>line</key><integer>5</integer> -// CHECK: <key>col</key><integer>3</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: </dict> -// CHECK: </array> -// CHECK: </dict> -// CHECK: </plist> +// CHECK: <key>diagnostics</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>'p' initialized to a null pointer value</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>'p' initialized to a null pointer value</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Passing null pointer value via 1st parameter 'p'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Passing null pointer value via 1st parameter 'p'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>15</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling 'bug'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling 'bug'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>4</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Entered call from 'test_bug_2'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'test_bug_2'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>4</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>4</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>bug</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> diff --git a/test/Analysis/inline.cpp b/test/Analysis/inline.cpp index a16fa00..909e180 100644 --- a/test/Analysis/inline.cpp +++ b/test/Analysis/inline.cpp @@ -262,12 +262,33 @@ namespace DefaultArgs { } int defaultReference(const int &input = 42) { - return input; + return -input; + } + int defaultReferenceZero(const int &input = 0) { + return -input; } void testReference() { - clang_analyzer_eval(defaultReference(1) == 1); // expected-warning{{TRUE}} - clang_analyzer_eval(defaultReference() == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(defaultReference(1) == -1); // expected-warning{{TRUE}} + clang_analyzer_eval(defaultReference() == -42); // expected-warning{{TRUE}} + + clang_analyzer_eval(defaultReferenceZero(1) == -1); // expected-warning{{TRUE}} + clang_analyzer_eval(defaultReferenceZero() == 0); // expected-warning{{TRUE}} +} + + double defaultFloatReference(const double &i = 42) { + return -i; + } + double defaultFloatReferenceZero(const double &i = 0) { + return -i; + } + + void testFloatReference() { + clang_analyzer_eval(defaultFloatReference(1) == -1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(defaultFloatReference() == -42); // expected-warning{{UNKNOWN}} + + clang_analyzer_eval(defaultFloatReferenceZero(1) == -1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(defaultFloatReferenceZero() == 0); // expected-warning{{UNKNOWN}} } } @@ -351,9 +372,7 @@ namespace VirtualWithSisterCasts { void testCastViaNew(B *b) { Grandchild *g = new (b) Grandchild(); - // FIXME: We actually now have perfect type info because of 'new'. - // This should be TRUE. - clang_analyzer_eval(g->foo() == 42); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(g->foo() == 42); // expected-warning{{TRUE}} g->x = 42; clang_analyzer_eval(g->x == 42); // expected-warning{{TRUE}} diff --git a/test/Analysis/inlining/containers.cpp b/test/Analysis/inlining/containers.cpp index 4500dff..73b2957 100644 --- a/test/Analysis/inlining/containers.cpp +++ b/test/Analysis/inlining/containers.cpp @@ -78,7 +78,9 @@ void testWrappers(BeginOnlySet &w1, IteratorStructOnlySet &w2, } -#else +#else // HEADER + +#include "../Inputs/system-header-simulator-cxx.h" class MySet { int *storage; @@ -152,8 +154,13 @@ class BeginOnlySet { public: struct IterImpl { MySet::iterator impl; + typedef std::forward_iterator_tag iterator_category; + IterImpl(MySet::iterator i) : impl(i) { - clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} + clang_analyzer_checkInlined(true); +#if INLINE + // expected-warning@-2 {{TRUE}} +#endif } }; @@ -231,4 +238,4 @@ public: } }; -#endif +#endif // HEADER diff --git a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp index 890e564..d219446 100644 --- a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp +++ b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp @@ -16,6 +16,11 @@ void testKnown() { clang_analyzer_eval(a.get() == 0); // expected-warning{{TRUE}} } +void testNew() { + A *a = new A(); + clang_analyzer_eval(a->get() == 0); // expected-warning{{TRUE}} +} + namespace ReinterpretDisruptsDynamicTypeInfo { class Parent {}; diff --git a/test/Analysis/inlining/eager-reclamation-path-notes.c b/test/Analysis/inlining/eager-reclamation-path-notes.c index f3e7376..6561365 100644 --- a/test/Analysis/inlining/eager-reclamation-path-notes.c +++ b/test/Analysis/inlining/eager-reclamation-path-notes.c @@ -120,40 +120,6 @@ void testChainedCalls() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>16</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>21</integer> // CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -286,11 +252,45 @@ void testChainedCalls() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>6</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>6</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>6</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>6</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -324,7 +324,7 @@ void testChainedCalls() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -577,40 +577,6 @@ void testChainedCalls() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>33</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>33</integer> -// CHECK-NEXT: <key>col</key><integer>6</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>33</integer> -// CHECK-NEXT: <key>col</key><integer>11</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>33</integer> -// CHECK-NEXT: <key>col</key><integer>17</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>33</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -743,11 +709,45 @@ void testChainedCalls() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>28</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>28</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>28</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>28</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>28</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -781,7 +781,7 @@ void testChainedCalls() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>28</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> diff --git a/test/Analysis/inlining/eager-reclamation-path-notes.cpp b/test/Analysis/inlining/eager-reclamation-path-notes.cpp index 3ee9d92..05411bb 100644 --- a/test/Analysis/inlining/eager-reclamation-path-notes.cpp +++ b/test/Analysis/inlining/eager-reclamation-path-notes.cpp @@ -202,7 +202,7 @@ int memberCallBaseDisappears() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'getNullWrapper'</string> // CHECK-NEXT: <key>message</key> @@ -217,40 +217,6 @@ int memberCallBaseDisappears() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>24</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>24</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>24</integer> -// CHECK-NEXT: <key>col</key><integer>21</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>24</integer> -// CHECK-NEXT: <key>col</key><integer>34</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>24</integer> // CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> diff --git a/test/Analysis/inlining/false-positive-suppression.c b/test/Analysis/inlining/false-positive-suppression.c index a836d9c..c5c6bb8 100644 --- a/test/Analysis/inlining/false-positive-suppression.c +++ b/test/Analysis/inlining/false-positive-suppression.c @@ -143,6 +143,27 @@ void testTrackNullVariable() { #endif } +void inlinedIsDifferent(int inlined) { + int i; + + // We were erroneously picking up the inner stack frame's initialization, + // even though the error occurs in the outer stack frame! + int *p = inlined ? &i : getNull(); + + if (!inlined) + inlinedIsDifferent(1); + + *p = 1; +#ifndef SUPPRESSED + // expected-warning@-2 {{Dereference of null pointer}} +#endif +} + +void testInlinedIsDifferent() { + // <rdar://problem/13787723> + inlinedIsDifferent(0); +} + // --------------------------------------- // FALSE NEGATIVES (over-suppression) diff --git a/test/Analysis/inlining/false-positive-suppression.m b/test/Analysis/inlining/false-positive-suppression.m new file mode 100644 index 0000000..53ec138 --- /dev/null +++ b/test/Analysis/inlining/false-positive-suppression.m @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s + +#ifdef SUPPRESSED +// expected-no-diagnostics +#endif + +@interface PointerWrapper +- (int *)getPtr; +- (id)getObject; +@end + +id getNil() { + return 0; +} + +void testNilReceiverHelperA(int *x) { + *x = 1; +#ifndef SUPPRESSED + // expected-warning@-2 {{Dereference of null pointer}} +#endif +} + +void testNilReceiverHelperB(int *x) { + *x = 1; +#ifndef SUPPRESSED + // expected-warning@-2 {{Dereference of null pointer}} +#endif +} + +void testNilReceiver(int coin) { + id x = getNil(); + if (coin) + testNilReceiverHelperA([x getPtr]); + else + testNilReceiverHelperB([[x getObject] getPtr]); +} diff --git a/test/Analysis/inlining/inline-defensive-checks.c b/test/Analysis/inlining/inline-defensive-checks.c index df3a8f2..aa7f700 100644 --- a/test/Analysis/inlining/inline-defensive-checks.c +++ b/test/Analysis/inlining/inline-defensive-checks.c @@ -97,3 +97,16 @@ void test24(char *buffer) { use(buffer); buffer[1] = 'b'; } + +// Ensure idc works on pointers with constant offset. +void idcchar(const char *s2) { + if(s2) + ; +} +void testConstantOffset(char *value) { + char *cursor = value + 5; + idcchar(cursor); + if (*cursor) { + cursor++; + } +} diff --git a/test/Analysis/inlining/inline-defensive-checks.cpp b/test/Analysis/inlining/inline-defensive-checks.cpp index 37bccbd..b69c535 100644 --- a/test/Analysis/inlining/inline-defensive-checks.cpp +++ b/test/Analysis/inlining/inline-defensive-checks.cpp @@ -52,4 +52,22 @@ void radar13224271_caller() Ty value; radar13224271_callee(getTyVal(), value ); notNullArg(value); // no-warning +} + +struct Foo { + int *ptr; + Foo(int *p) { + *p = 1; // no-warning + } +}; +void idc(int *p3) { + if (p3) + ; +} +int *retNull() { + return 0; +} +void test(int *p1, int *p2) { + idc(p1); + Foo f(p1); }
\ No newline at end of file diff --git a/test/Analysis/inlining/path-notes.c b/test/Analysis/inlining/path-notes.c index b128aab..6609885 100644 --- a/test/Analysis/inlining/path-notes.c +++ b/test/Analysis/inlining/path-notes.c @@ -107,6 +107,39 @@ void testUseOfNullPointer() { // expected-note@-4 {{Calling 'usePointer'}} } +struct X { char *p; }; + +void setFieldToNull(struct X *x) { + x->p = 0; // expected-note {{Null pointer value stored to field 'p'}} +} + +int testSetFieldToNull(struct X *x) { + setFieldToNull(x); // expected-note {{Calling 'setFieldToNull'}} + // expected-note@-1{{Returning from 'setFieldToNull'}} + return *x->p; + // expected-warning@-1 {{Dereference of null pointer (loaded from field 'p')}} + // expected-note@-2 {{Dereference of null pointer (loaded from field 'p')}} +} + +struct Outer { + struct Inner { + int *p; + } inner; +}; + +void test(struct Outer *wrapperPtr) { + wrapperPtr->inner.p = 0; // expected-note {{Null pointer value stored to field 'p'}} + *wrapperPtr->inner.p = 1; //expected-warning {{Dereference of null pointer (loaded from field 'p')}} + // expected-note@-1 {{Dereference of null pointer (loaded from field 'p')}} +} + +void test4(int **p) { + if (*p) return; // expected-note {{Taking false branch}} + // expected-note@-1 {{Assuming pointer value is null}} + **p = 1; // expected-warning {{Dereference of null pointer}} + // expected-note@-1 {{Dereference of null pointer}} +} + // CHECK: <key>diagnostics</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> @@ -241,7 +274,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'zero'</string> // CHECK-NEXT: <key>message</key> @@ -269,12 +302,12 @@ void testUseOfNullPointer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -286,7 +319,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -320,7 +353,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -425,11 +458,45 @@ void testUseOfNullPointer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>24</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -463,7 +530,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>24</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -631,11 +698,45 @@ void testUseOfNullPointer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>39</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>39</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>39</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>39</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>39</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -669,7 +770,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>39</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -837,11 +938,45 @@ void testUseOfNullPointer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>51</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>51</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>51</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>51</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>51</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -875,7 +1010,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>51</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1108,7 +1243,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'getZero'</string> // CHECK-NEXT: <key>message</key> @@ -1123,40 +1258,6 @@ void testUseOfNullPointer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>65</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>65</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>65</integer> -// CHECK-NEXT: <key>col</key><integer>4</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>65</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>65</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1170,12 +1271,12 @@ void testUseOfNullPointer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>65</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>65</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -1187,7 +1288,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>65</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1221,7 +1322,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>65</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1454,7 +1555,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'getZero'</string> // CHECK-NEXT: <key>message</key> @@ -1469,40 +1570,6 @@ void testUseOfNullPointer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>72</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> -// CHECK-NEXT: <key>col</key><integer>8</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> -// CHECK-NEXT: <key>col</key><integer>11</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> -// CHECK-NEXT: <key>col</key><integer>17</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1800,7 +1867,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'getZero'</string> // CHECK-NEXT: <key>message</key> @@ -1815,40 +1882,6 @@ void testUseOfNullPointer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>79</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>79</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>79</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>79</integer> -// CHECK-NEXT: <key>col</key><integer>18</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>79</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1925,12 +1958,12 @@ void testUseOfNullPointer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>83</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>83</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -1942,7 +1975,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>83</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1976,7 +2009,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>83</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -2209,7 +2242,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'getZero'</string> // CHECK-NEXT: <key>message</key> @@ -2224,40 +2257,6 @@ void testUseOfNullPointer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>88</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>88</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>88</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>88</integer> -// CHECK-NEXT: <key>col</key><integer>13</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>88</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2334,12 +2333,12 @@ void testUseOfNullPointer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>92</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>92</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -2351,7 +2350,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>92</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -2385,7 +2384,7 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>92</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -2618,47 +2617,13 @@ void testUseOfNullPointer() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'getZero'</string> // CHECK-NEXT: <key>message</key> // CHECK-NEXT: <string>Returning from 'getZero'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>103</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>103</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>103</integer> -// CHECK-NEXT: <key>col</key><integer>14</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>103</integer> -// CHECK-NEXT: <key>col</key><integer>20</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> @@ -2765,11 +2730,45 @@ void testUseOfNullPointer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>97</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>97</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>97</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>97</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>97</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -2803,7 +2802,542 @@ void testUseOfNullPointer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>97</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>117</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>117</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>117</integer> +// CHECK-NEXT: <key>col</key><integer>19</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling 'setFieldToNull'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling 'setFieldToNull'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>112</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Entered call from 'testSetFieldToNull'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'testSetFieldToNull'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>112</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>112</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>113</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>113</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>113</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>113</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>113</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Null pointer value stored to field 'p'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Null pointer value stored to field 'p'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>117</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>117</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>117</integer> +// CHECK-NEXT: <key>col</key><integer>19</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Returning from 'setFieldToNull'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Returning from 'setFieldToNull'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>117</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>117</integer> +// CHECK-NEXT: <key>col</key><integer>16</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>119</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>119</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>119</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>119</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>119</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>119</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>119</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>119</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>119</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from field 'p')</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from field 'p')</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from field 'p')</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>testSetFieldToNull</string> +// CHECK-NEXT: <key>issue_hash</key><string>3</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>119</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>131</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>131</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>131</integer> +// CHECK-NEXT: <key>col</key><integer>25</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Null pointer value stored to field 'p'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Null pointer value stored to field 'p'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>131</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>131</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>132</integer> +// CHECK-NEXT: <key>col</key><integer>24</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>132</integer> +// CHECK-NEXT: <key>col</key><integer>24</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>132</integer> +// CHECK-NEXT: <key>col</key><integer>24</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>132</integer> +// CHECK-NEXT: <key>col</key><integer>22</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>132</integer> +// CHECK-NEXT: <key>col</key><integer>22</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from field 'p')</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from field 'p')</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from field 'p')</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>test</string> +// CHECK-NEXT: <key>issue_hash</key><string>2</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>132</integer> +// CHECK-NEXT: <key>col</key><integer>24</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>137</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>137</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>137</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>137</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>137</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>137</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>137</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Assuming pointer value is null</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Assuming pointer value is null</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>137</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>137</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>139</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>139</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>139</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>139</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>139</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>139</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>139</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>139</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>139</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>test4</string> +// CHECK-NEXT: <key>issue_hash</key><string>3</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>139</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> diff --git a/test/Analysis/inlining/path-notes.cpp b/test/Analysis/inlining/path-notes.cpp index 895ee28..e0c83cb 100644 --- a/test/Analysis/inlining/path-notes.cpp +++ b/test/Analysis/inlining/path-notes.cpp @@ -206,6 +206,64 @@ void testPathNoteOnInitializer() { // expected-note@-1 {{Calling constructor for 'FooWithInitializer'}} } +int testNonPrintableAssignment(int **p) { + int *&y = *p; // expected-note {{'y' initialized here}} + y = 0; // expected-note {{Storing null pointer value}} + return *y; // expected-warning {{Dereference of null pointer (loaded from variable 'y')}} + // expected-note@-1 {{Dereference of null pointer (loaded from variable 'y')}} +} + +struct Base { int *x; }; +struct Derived : public Base {}; + +void test(Derived d) { + d.x = 0; //expected-note {{Null pointer value stored to 'd.x'}} + *d.x = 1; // expected-warning {{Dereference of null pointer (loaded from field 'x')}} + // expected-note@-1 {{Dereference of null pointer (loaded from field 'x')}} +} + +struct Owner { + struct Wrapper { + int x; + }; + Wrapper *arr; + void testGetDerefExprOnMemberExprWithADot(); +}; + +void Owner::testGetDerefExprOnMemberExprWithADot() { + if (arr) // expected-note {{Assuming pointer value is null}} + // expected-note@-1 {{Taking false branch}} + ; + arr[1].x = 1; //expected-warning {{Dereference of null pointer}} + //expected-note@-1 {{Dereference of null pointer}} +} + +void testGetDerefExprOnMemberExprWithADot() { + Owner::Wrapper *arr; // expected-note {{'arr' declared without an initial value}} + arr[2].x = 1; // expected-warning {{Dereference of undefined pointer value}} + // expected-note@-1 {{Dereference of undefined pointer value}} +} + + + +class A { +public: + void bar() const {} +}; +const A& testDeclRefExprToReferenceInGetDerefExpr(const A *ptr) { + const A& val = *ptr; //expected-note {{'val' initialized here}} + + // This is not valid C++; if 'ptr' were null, creating 'ref' would be illegal. + // However, this is not checked at runtime, so this branch is actually + // possible. + if (&val == 0) { //expected-note {{Assuming pointer value is null}} + // expected-note@-1 {{Taking true branch}} + val.bar(); // expected-warning {{Called C++ object pointer is null}} + // expected-note@-1 {{Called C++ object pointer is null}} + } + + return val; +} // CHECK: <key>diagnostics</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> @@ -719,11 +777,45 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>8</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -757,7 +849,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>8</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -973,11 +1065,45 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>41</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>41</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>41</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>41</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>41</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1011,7 +1137,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>41</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1188,11 +1314,45 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>63</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>63</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>63</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>63</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>63</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1224,7 +1384,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>63</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1401,11 +1561,45 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>68</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>68</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>68</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>68</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>68</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1437,7 +1631,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>68</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1648,11 +1842,45 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>73</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>73</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>73</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>73</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>73</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1684,7 +1912,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>73</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1929,11 +2157,45 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>78</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>78</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>78</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>78</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>78</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1967,7 +2229,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>78</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -2106,40 +2368,6 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>145</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>145</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>145</integer> -// CHECK-NEXT: <key>col</key><integer>9</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>145</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> @@ -2280,11 +2508,45 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>83</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>83</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>83</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>83</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>83</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -2318,7 +2580,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>83</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -2533,11 +2795,45 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>88</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>88</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>88</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>88</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>88</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -2569,7 +2865,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>88</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -2739,7 +3035,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'getZero'</string> // CHECK-NEXT: <key>message</key> @@ -2754,40 +3050,6 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>173</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>173</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>173</integer> -// CHECK-NEXT: <key>col</key><integer>23</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>173</integer> -// CHECK-NEXT: <key>col</key><integer>29</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>173</integer> // CHECK-NEXT: <key>col</key><integer>23</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2801,12 +3063,12 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>173</integer> -// CHECK-NEXT: <key>col</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>173</integer> -// CHECK-NEXT: <key>col</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -2818,7 +3080,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>173</integer> -// CHECK-NEXT: <key>col</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -2852,7 +3114,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>173</integer> -// CHECK-NEXT: <key>col</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -3119,7 +3381,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'getZeroByRef'</string> // CHECK-NEXT: <key>message</key> @@ -3134,40 +3396,6 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>180</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>180</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>180</integer> -// CHECK-NEXT: <key>col</key><integer>23</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>180</integer> -// CHECK-NEXT: <key>col</key><integer>34</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>180</integer> // CHECK-NEXT: <key>col</key><integer>23</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -3181,12 +3409,12 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>180</integer> -// CHECK-NEXT: <key>col</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>180</integer> -// CHECK-NEXT: <key>col</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -3198,7 +3426,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>180</integer> -// CHECK-NEXT: <key>col</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -3232,7 +3460,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>180</integer> -// CHECK-NEXT: <key>col</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -3655,12 +3883,12 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>197</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>197</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -3672,7 +3900,7 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>197</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -3704,7 +3932,814 @@ void testPathNoteOnInitializer() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>197</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>210</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>210</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>210</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>'y' initialized here</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>'y' initialized here</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>210</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>210</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>211</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>211</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>211</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>211</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>211</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Storing null pointer value</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Storing null pointer value</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>211</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>211</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'y')</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'y')</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from variable 'y')</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>testNonPrintableAssignment</string> +// CHECK-NEXT: <key>issue_hash</key><string>3</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>220</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>220</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>220</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Null pointer value stored to 'd.x'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Null pointer value stored to 'd.x'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>220</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>220</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>221</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>221</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>221</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>221</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>221</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from field 'x')</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from field 'x')</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from field 'x')</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>test</string> +// CHECK-NEXT: <key>issue_hash</key><string>2</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>221</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>234</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>234</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>234</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>234</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>234</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>234</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>234</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Assuming pointer value is null</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Assuming pointer value is null</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>234</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>234</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>237</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>237</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>237</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>237</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>237</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>237</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>237</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>237</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>237</integer> +// CHECK-NEXT: <key>col</key><integer>13</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>C++ method</string> +// CHECK-NEXT: <key>issue_context</key><string>testGetDerefExprOnMemberExprWithADot</string> +// CHECK-NEXT: <key>issue_hash</key><string>4</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>237</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>242</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>242</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>242</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>'arr' declared without an initial value</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>'arr' declared without an initial value</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>242</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>242</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>243</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>243</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>243</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>243</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>243</integer> +// CHECK-NEXT: <key>col</key><integer>13</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of undefined pointer value</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of undefined pointer value</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of undefined pointer value</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of undefined pointer value</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>testGetDerefExprOnMemberExprWithADot</string> +// CHECK-NEXT: <key>issue_hash</key><string>2</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>243</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>254</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>254</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>254</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>'val' initialized here</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>'val' initialized here</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>254</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>254</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>259</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>259</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>259</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>259</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>259</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>259</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>259</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>259</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>259</integer> +// CHECK-NEXT: <key>col</key><integer>15</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Assuming pointer value is null</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Assuming pointer value is null</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>259</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>259</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>261</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>261</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>261</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>261</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>261</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Called C++ object pointer is null</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Called C++ object pointer is null</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Called C++ object pointer is null</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Called C++ object pointer is null</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>testDeclRefExprToReferenceInGetDerefExpr</string> +// CHECK-NEXT: <key>issue_hash</key><string>8</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>261</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> diff --git a/test/Analysis/inlining/path-notes.m b/test/Analysis/inlining/path-notes.m index f3a7b6c..74f088a 100644 --- a/test/Analysis/inlining/path-notes.m +++ b/test/Analysis/inlining/path-notes.m @@ -13,7 +13,7 @@ void dispatch_sync(dispatch_queue_t, dispatch_block_t); int *getZeroIfNil(Test *x) { return x.p; - // expected-note@-1 {{No method is called because the receiver is nil}} + // expected-note@-1 {{'p' not called because the receiver is nil}} // expected-note@-2 {{Returning null pointer}} } @@ -65,6 +65,31 @@ int testDispatchSyncInliningNoPruning(int coin) { } +@interface PointerWrapper +- (int *)getPtr; +@end + +id getNil() { + return 0; +} + +void testNilReceiverHelper(int *x) { + *x = 1; // expected-warning {{Dereference of null pointer}} + // expected-note@-1 {{Dereference of null pointer (loaded from variable 'x')}} +} + +void testNilReceiver(id *x) { + if (*x) { + // expected-note@-1 {{Taking false branch}} + return; + } + testNilReceiverHelper([*x getPtr]); + // expected-note@-1 {{'getPtr' not called because the receiver is nil}} + // expected-note@-2 {{Passing null pointer value via 1st parameter 'x'}} + // expected-note@-3 {{Calling 'testNilReceiverHelper'}} +} + + // CHECK: <key>diagnostics</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> @@ -303,9 +328,9 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>1</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>No method is called because the receiver is nil</string> +// CHECK-NEXT: <string>'p' not called because the receiver is nil</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>No method is called because the receiver is nil</string> +// CHECK-NEXT: <string>'p' not called because the receiver is nil</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -393,7 +418,7 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'getZeroIfNil'</string> // CHECK-NEXT: <key>message</key> @@ -408,40 +433,6 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>4</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>15</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>21</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -455,12 +446,12 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -472,7 +463,7 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -506,7 +497,7 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>21</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -689,7 +680,7 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: <key>col</key><integer>1</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> -// CHECK-NEXT: <key>depth</key><integer>2</integer> +// CHECK-NEXT: <key>depth</key><integer>1</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning to caller</string> // CHECK-NEXT: <key>message</key> @@ -718,7 +709,7 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returning from 'dispatch_sync'</string> // CHECK-NEXT: <key>message</key> @@ -746,46 +737,12 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>43</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>43</integer> -// CHECK-NEXT: <key>col</key><integer>8</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>43</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>43</integer> -// CHECK-NEXT: <key>col</key><integer>8</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>43</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>43</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -797,7 +754,7 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>43</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -831,7 +788,7 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>43</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1080,4 +1037,321 @@ int testDispatchSyncInliningNoPruning(int coin) { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>82</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>82</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>23</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>23</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>26</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>26</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>26</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>26</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>27</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>'getPtr' not called because the receiver is nil</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>'getPtr' not called because the receiver is nil</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>26</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>26</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>25</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>25</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>25</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>25</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>35</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Passing null pointer value via 1st parameter 'x'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Passing null pointer value via 1st parameter 'x'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>86</integer> +// CHECK-NEXT: <key>col</key><integer>36</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling 'testNilReceiverHelper'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling 'testNilReceiverHelper'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>76</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Entered call from 'testNilReceiver'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'testNilReceiver'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>76</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>76</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>77</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>77</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>77</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>77</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>77</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>77</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>77</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>77</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>77</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'x')</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'x')</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from variable 'x')</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>testNilReceiverHelper</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>77</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> // CHECK-NEXT: </array> diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c index 3a260c3..c197df4 100644 --- a/test/Analysis/malloc-annotations.c +++ b/test/Analysis/malloc-annotations.c @@ -26,7 +26,7 @@ struct stuff myglobalstuff; void f1() { int *p = malloc(12); - return; // expected-warning{{Memory is never released; potential leak}} + return; // expected-warning{{Potential leak of memory pointed to by}} } void f2() { @@ -54,17 +54,17 @@ void naf1() { void n2af1() { int *p = my_malloc2(12); - return; // expected-warning{{Memory is never released; potential leak}} + return; // expected-warning{{Potential leak of memory pointed to by}} } void af1() { int *p = my_malloc(12); - return; // expected-warning{{Memory is never released; potential leak}} + return; // expected-warning{{Potential leak of memory pointed to by}} } void af1_b() { int *p = my_malloc(12); -} // expected-warning{{Memory is never released; potential leak}} +} // expected-warning{{Potential leak of memory pointed to by}} void af1_c() { myglobalpointer = my_malloc(12); // no-warning @@ -73,7 +73,7 @@ void af1_c() { void af1_d() { struct stuff mystuff; mystuff.somefield = my_malloc(12); -} // expected-warning{{Memory is never released; potential leak}} +} // expected-warning{{Potential leak of memory pointed to by}} // Test that we can pass out allocated memory via pointer-to-pointer. void af1_e(void **pp) { @@ -239,7 +239,7 @@ char mallocGarbage () { // This tests that calloc() buffers need to be freed void callocNoFree () { char *buf = calloc(2,2); - return; // expected-warning{{never released}} + return; // expected-warning{{Potential leak of memory pointed to by}} } // These test that calloc() buffers are zeroed by default @@ -258,7 +258,7 @@ char callocZeroesBad () { if (buf[1] != 0) { free(buf); // expected-warning{{never executed}} } - return result; // expected-warning{{never released}} + return result; // expected-warning{{Potential leak of memory pointed to by}} } void testMultipleFreeAnnotations() { diff --git a/test/Analysis/malloc-interprocedural.c b/test/Analysis/malloc-interprocedural.c index 3c7bab6..c78cc6c 100644 --- a/test/Analysis/malloc-interprocedural.c +++ b/test/Analysis/malloc-interprocedural.c @@ -32,7 +32,7 @@ static void my_free1(void *p) { static void test1() { void *data = 0; my_malloc1(&data, 4); -} // expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}} +} // expected-warning {{Potential leak of memory pointed to by 'data'}} static void test11() { void *data = 0; @@ -43,9 +43,9 @@ static void test11() { static void testUniqueingByallocationSiteInTopLevelFunction() { void *data = my_malloc2(1, 4); data = 0; - int x = 5;// expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}} + int x = 5;// expected-warning {{Potential leak of memory pointed to by 'data'}} data = my_malloc2(1, 4); -} // expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}} +} // expected-warning {{Potential leak of memory pointed to by 'data'}} static void test3() { void *data = my_malloc2(1, 4); @@ -81,7 +81,7 @@ static char *reshape(char *in) { void testThatRemoveDeadBindingsRunBeforeEachCall() { char *v = malloc(12); v = reshape(v); - v = reshape(v);// expected-warning {{Memory is never released; potential leak of memory pointed to by 'v'}} + v = reshape(v);// expected-warning {{Potential leak of memory pointed to by 'v'}} } // Test that we keep processing after 'return;' diff --git a/test/Analysis/malloc-plist.c b/test/Analysis/malloc-plist.c index ddd09db..41bb8b5 100644 --- a/test/Analysis/malloc-plist.c +++ b/test/Analysis/malloc-plist.c @@ -169,6 +169,28 @@ void use_function_with_leak7() { function_with_leak7(); } +// Test that we do not print the name of a variable not visible from where +// the issue is reported. +int *my_malloc() { + int *p = malloc(12); + return p; +} +void testOnlyRefferToVisibleVariables() { + my_malloc(); +} // expected-warning {{Potential leak of memory}} + +struct PointerWrapper{ + int*p; +}; +int *my_malloc_into_struct() { + struct PointerWrapper w; + w.p = malloc(12); + return w.p; +} +void testMyMalloc() { + my_malloc_into_struct(); // expected-warning {{Potential leak of memory}} +} + // CHECK: <key>diagnostics</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> @@ -378,12 +400,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'p'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'p'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'p'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'p'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'p'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'p'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -540,12 +562,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'A'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'A'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'A'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'A'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'A'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'A'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -925,12 +947,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'buf'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'buf'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'buf'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'buf'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -1274,7 +1296,7 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returned allocated memory</string> // CHECK-NEXT: <key>message</key> @@ -1324,12 +1346,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'buf'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'buf'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'buf'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'buf'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -1716,11 +1738,11 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>2</integer> +// CHECK-NEXT: <key>depth</key><integer>1</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Returned released memory via 1st parameter</string> +// CHECK-NEXT: <string>Returning; memory was released via 1st parameter</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Returned released memory via 1st parameter</string> +// CHECK-NEXT: <string>Returning; memory was released via 1st parameter</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -1779,11 +1801,11 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Returned released memory via 1st parameter</string> +// CHECK-NEXT: <string>Returning; memory was released via 1st parameter</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Returned released memory via 1st parameter</string> +// CHECK-NEXT: <string>Returning; memory was released via 1st parameter</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -2353,7 +2375,7 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Reallocation of 1st parameter failed</string> // CHECK-NEXT: <key>message</key> @@ -2403,12 +2425,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'buf'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'buf'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'buf'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'buf'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -2621,7 +2643,7 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returned allocated memory</string> // CHECK-NEXT: <key>message</key> @@ -2671,12 +2693,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'v'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'v'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'v'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'v'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'v'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'v'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -2833,12 +2855,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'm'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'm'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'm'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'm'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'm'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'm'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -3038,12 +3060,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>1</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -3243,12 +3265,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>1</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -3545,12 +3567,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>1</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -3847,12 +3869,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>1</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -4052,12 +4074,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>1</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -4257,12 +4279,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>1</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by 'x'</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -4441,7 +4463,7 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Returned allocated memory</string> // CHECK-NEXT: <key>message</key> @@ -4491,12 +4513,12 @@ void use_function_with_leak7() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak</string> +// CHECK-NEXT: <string>Potential memory leak</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Memory is never released; potential leak</string> +// CHECK-NEXT: <string>Potential memory leak</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak</string> +// CHECK-NEXT: <key>description</key><string>Potential memory leak</string> // CHECK-NEXT: <key>category</key><string>Memory Error</string> // CHECK-NEXT: <key>type</key><string>Memory leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> @@ -4509,6 +4531,506 @@ void use_function_with_leak7() { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>179</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>179</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>179</integer> +// CHECK-NEXT: <key>col</key><integer>13</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling 'my_malloc'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling 'my_malloc'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>174</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Entered call from 'testOnlyRefferToVisibleVariables'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'testOnlyRefferToVisibleVariables'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>174</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>174</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>175</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>175</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>175</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>175</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>175</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>175</integer> +// CHECK-NEXT: <key>col</key><integer>17</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>175</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>175</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>175</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Memory is allocated</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Memory is allocated</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>179</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>179</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>179</integer> +// CHECK-NEXT: <key>col</key><integer>13</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Returned allocated memory</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Returned allocated memory</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>179</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>179</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>180</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>180</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>180</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Potential memory leak</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Potential memory leak</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Potential memory leak</string> +// CHECK-NEXT: <key>category</key><string>Memory Error</string> +// CHECK-NEXT: <key>type</key><string>Memory leak</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>testOnlyRefferToVisibleVariables</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>180</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>191</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>191</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>191</integer> +// CHECK-NEXT: <key>col</key><integer>25</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling 'my_malloc_into_struct'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling 'my_malloc_into_struct'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>185</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Entered call from 'testMyMalloc'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'testMyMalloc'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>185</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>185</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>186</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>186</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>186</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>186</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>col</key><integer>18</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Memory is allocated</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Memory is allocated</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>191</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>191</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>191</integer> +// CHECK-NEXT: <key>col</key><integer>25</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Returned allocated memory</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Returned allocated memory</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>191</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>191</integer> +// CHECK-NEXT: <key>col</key><integer>23</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Potential memory leak</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Potential memory leak</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Potential memory leak</string> +// CHECK-NEXT: <key>category</key><string>Memory Error</string> +// CHECK-NEXT: <key>type</key><string>Memory leak</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>testMyMalloc</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </plist> diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c index 7790b32..6071d1d 100644 --- a/test/Analysis/malloc.c +++ b/test/Analysis/malloc.c @@ -21,7 +21,7 @@ char *fooRetPtr(); void f1() { int *p = malloc(12); - return; // expected-warning{{Memory is never released; potential leak of memory pointed to by 'p'}} + return; // expected-warning{{Potential leak of memory pointed to by 'p'}} } void f2() { @@ -46,7 +46,7 @@ void reallocNotNullPtr(unsigned sizeIn) { char *p = (char*)malloc(size); if (p) { char *q = (char*)realloc(p, sizeIn); - char x = *q; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'q'}} + char x = *q; // expected-warning {{Potential leak of memory pointed to by 'q'}} } } @@ -105,7 +105,7 @@ void reallocSizeZero5() { void reallocPtrZero1() { char *r = realloc(0, 12); -} // expected-warning {{Memory is never released; potential leak of memory pointed to by 'r'}} +} // expected-warning {{Potential leak of memory pointed to by 'r'}} void reallocPtrZero2() { char *r = realloc(0, 12); @@ -122,7 +122,7 @@ void reallocRadar6337483_1() { char *buf = malloc(100); buf = (char*)realloc(buf, 0x1000000); if (!buf) { - return;// expected-warning {{Memory is never released; potential leak}} + return;// expected-warning {{Potential leak of memory pointed to by}} } free(buf); } @@ -135,7 +135,7 @@ void reallocRadar6337483_2() { } else { free(buf2); } -} // expected-warning {{Memory is never released; potential leak}} +} // expected-warning {{Potential leak of memory pointed to by}} void reallocRadar6337483_3() { char * buf = malloc(100); @@ -153,7 +153,7 @@ void reallocRadar6337483_4() { char *buf = malloc(100); char *buf2 = (char*)realloc(buf, 0x1000000); if (!buf2) { - return; // expected-warning {{Memory is never released; potential leak}} + return; // expected-warning {{Potential leak of memory pointed to by}} } else { free(buf2); } @@ -189,7 +189,7 @@ void reallocfRadar6337483_3() { void reallocfPtrZero1() { char *r = reallocf(0, 12); -} // expected-warning {{Memory is never released; potential leak}} +} // expected-warning {{Potential leak of memory pointed to by}} // This case tests that storing malloc'ed memory to a static variable which is @@ -293,7 +293,7 @@ char mallocGarbage () { // This tests that calloc() buffers need to be freed void callocNoFree () { char *buf = calloc(2,2); - return; // expected-warning{{never released}} + return; // expected-warning{{Potential leak of memory pointed to by 'buf'}} } // These test that calloc() buffers are zeroed by default @@ -312,7 +312,7 @@ char callocZeroesBad () { if (buf[1] != 0) { free(buf); // expected-warning{{never executed}} } - return result; // expected-warning{{never released}} + return result; // expected-warning{{Potential leak of memory pointed to by 'buf'}} } void nullFree() { @@ -387,12 +387,12 @@ void mallocEscapeMalloc() { int *p = malloc(12); myfoo(p); p = malloc(12); -} // expected-warning{{Memory is never released; potential leak}} +} // expected-warning{{Potential leak of memory pointed to by}} void mallocMalloc() { int *p = malloc(12); p = malloc(12); -} // expected-warning {{Memory is never released; potential leak}} +} // expected-warning {{Potential leak of memory pointed to by}} void mallocFreeMalloc() { int *p = malloc(12); @@ -451,7 +451,7 @@ void mallocFailedOrNotLeak() { if (p == 0) return; // no warning else - return; // expected-warning {{Memory is never released; potential leak}} + return; // expected-warning {{Potential leak of memory pointed to by}} } void mallocAssignment() { @@ -461,7 +461,7 @@ void mallocAssignment() { int vallocTest() { char *mem = valloc(12); - return 0; // expected-warning {{Memory is never released; potential leak}} + return 0; // expected-warning {{Potential leak of memory pointed to by}} } void vallocEscapeFreeUse() { @@ -534,7 +534,7 @@ int *testMalloc3() { void testStructLeak() { StructWithPtr St; St.memP = malloc(12); - return; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'St.memP'}} + return; // expected-warning {{Potential leak of memory pointed to by 'St.memP'}} } void testElemRegion1() { @@ -584,7 +584,7 @@ struct X* RegInvalidationDetect1(struct X *s2) { struct X *px= malloc(sizeof(struct X)); px->p = 0; px = s2; - return px; // expected-warning {{Memory is never released; potential leak}} + return px; // expected-warning {{Potential leak of memory pointed to by}} } struct X* RegInvalidationGiveUp1() { @@ -598,7 +598,7 @@ int **RegInvalidationDetect2(int **pp) { int *p = malloc(12); pp = &p; pp++; - return 0;// expected-warning {{Memory is never released; potential leak}} + return 0;// expected-warning {{Potential leak of memory pointed to by}} } extern void exit(int) __attribute__ ((__noreturn__)); @@ -674,7 +674,7 @@ int *specialMallocWithStruct() { void testStrdup(const char *s, unsigned validIndex) { char *s2 = strdup(s); s2[validIndex + 1] = 'b'; -} // expected-warning {{Memory is never released; potential leak}} +} // expected-warning {{Potential leak of memory pointed to by}} int testStrndup(const char *s, unsigned validIndex, unsigned size) { char *s2 = strndup(s, size); @@ -682,7 +682,7 @@ int testStrndup(const char *s, unsigned validIndex, unsigned size) { if (s2[validIndex] != 'a') return 0; else - return 1;// expected-warning {{Memory is never released; potential leak}} + return 1;// expected-warning {{Potential leak of memory pointed to by}} } void testStrdupContentIsDefined(const char *s, unsigned validIndex) { @@ -945,7 +945,7 @@ void localStructTest() { StructWithPtr St; StructWithPtr *pSt = &St; pSt->memP = malloc(12); -} // expected-warning{{Memory is never released; potential leak}} +} // expected-warning{{Potential leak of memory pointed to by}} #ifdef __INTPTR_TYPE__ // Test double assignment through integers. @@ -1067,14 +1067,14 @@ void testPassConstPointerIndirectlyStruct() { struct HasPtr hp; hp.p = malloc(10); memcmp(&hp, &hp, sizeof(hp)); - return; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'hp.p'}} + return; // expected-warning {{Potential leak of memory pointed to by 'hp.p'}} } void testPassToSystemHeaderFunctionIndirectlyStruct() { SomeStruct ss; ss.p = malloc(1); fakeSystemHeaderCall(&ss); -} // expected-warning {{Memory is never released; potential leak of memory pointed to by 'ss.p'}} +} // expected-warning {{Potential leak of memory pointed to by 'ss.p'}} int *testOffsetAllocate(size_t size) { int *memoryBlock = (int *)malloc(size + sizeof(int)); @@ -1107,7 +1107,7 @@ void testOffsetOfRegionFreedAfterFunctionCall() { int *p = malloc(sizeof(int)*2); p += 1; myfoo(p); - free(p); // no-warning + free(p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}} } void testFixManipulatedPointerBeforeFree() { @@ -1160,7 +1160,7 @@ void testOffsetZeroDoubleFree() { void testOffsetPassedToStrlen() { char * string = malloc(sizeof(char)*10); string += 1; - int length = strlen(string); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'string'}} + int length = strlen(string); // expected-warning {{Potential leak of memory pointed to by 'string'}} } void testOffsetPassedToStrlenThenFree() { diff --git a/test/Analysis/malloc.cpp b/test/Analysis/malloc.cpp index 54efa1c..75d06d6 100644 --- a/test/Analysis/malloc.cpp +++ b/test/Analysis/malloc.cpp @@ -24,12 +24,18 @@ Foo aFunction() { // they are defined in system headers and take the const pointer to the // allocated memory. (radar://11160612) // Test default parameter. -int const_ptr_and_callback_def_param(int, const char*, int n, void(*)(void*) = 0); +int const_ptr_and_callback_def_param(int, const char*, int n, void(*)(void*) = free); void r11160612_3() { char *x = (char*)malloc(12); const_ptr_and_callback_def_param(0, x, 12); } +int const_ptr_and_callback_def_param_null(int, const char*, int n, void(*)(void*) = 0); +void r11160612_no_callback() { + char *x = (char*)malloc(12); + const_ptr_and_callback_def_param_null(0, x, 12); +} // expected-warning{{leak}} + // Test member function pointer. struct CanFreeMemory { static void myFree(void*); diff --git a/test/Analysis/malloc.mm b/test/Analysis/malloc.mm index bd9d2d2..c7fe86b 100644 --- a/test/Analysis/malloc.mm +++ b/test/Analysis/malloc.mm @@ -81,7 +81,17 @@ void testRelinquished2() { void *data = malloc(42); NSData *nsdata; free(data); - [NSData dataWithBytesNoCopy:data length:42]; // expected-warning {{Attempt to free released memory}} + [NSData dataWithBytesNoCopy:data length:42]; // expected-warning {{Use of memory after it is freed}} +} + +@interface My ++ (void)param:(void *)p; +@end + +void testUseAfterFree() { + int *p = (int *)malloc(sizeof(int)); + free(p); + [My param:p]; // expected-warning{{Use of memory after it is freed}} } void testNoCopy() { diff --git a/test/Analysis/misc-ps.c b/test/Analysis/misc-ps.c index 5369ab1..b302860 100644 --- a/test/Analysis/misc-ps.c +++ b/test/Analysis/misc-ps.c @@ -163,3 +163,15 @@ int PR14634(int x) { return !y; } + +// PR15684: If a checker generates a sink node after generating a regular node +// and no state changes between the two, graph trimming would consider the two +// the same node, forming a loop. +struct PR15684 { + void (*callback)(int); +}; +void sinkAfterRegularNode(struct PR15684 *context) { + int uninitialized; + context->callback(uninitialized); // expected-warning {{uninitialized}} +} + diff --git a/test/Analysis/new.cpp b/test/Analysis/new.cpp index 44ae980..8d3eee9 100644 --- a/test/Analysis/new.cpp +++ b/test/Analysis/new.cpp @@ -8,6 +8,12 @@ extern "C" void *malloc(size_t); extern "C" void free(void *); int someGlobal; + +class SomeClass { +public: + void f(int *p); +}; + void testImplicitlyDeclaredGlobalNew() { if (someGlobal != 0) return; @@ -101,6 +107,12 @@ void testCacheOut(PtrWrapper w) { new (&w.x) (int*)(0); // we cache out here; don't crash } +void testUseAfter(int *p) { + SomeClass *c = new SomeClass; + free(p); + c->f(p); // expected-warning{{Use of memory after it is freed}} + delete c; +} //-------------------------------------------------------------------- // Check for intersection with other checkers from MallocChecker.cpp @@ -126,7 +138,7 @@ void testNewDeleteNoWarn() { void testDeleteMallocked() { int *x = (int *)malloc(sizeof(int)); delete x; // FIXME: Shoud detect pointer escape and keep silent after 'delete' is modeled properly. -} // expected-warning{{Memory is never released; potential leak}} +} // expected-warning{{Potential leak of memory pointed to by 'x'}} void testDeleteOpAfterFree() { int *p = (int *)malloc(sizeof(int)); @@ -152,6 +164,12 @@ void testCustomPlacementNewAfterFree() { p = new(0, p) int; // expected-warning{{Use of memory after it is freed}} } +void testUsingThisAfterDelete() { + SomeClass *c = new SomeClass; + delete c; + c->f(0); // no-warning +} + //-------------------------------- // Incorrectly-modelled behavior //-------------------------------- diff --git a/test/Analysis/null-deref-path-notes.m b/test/Analysis/null-deref-path-notes.m index 6651454..e22d520 100644 --- a/test/Analysis/null-deref-path-notes.m +++ b/test/Analysis/null-deref-path-notes.m @@ -457,28 +457,47 @@ void repeatedStores(int coin) { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>33</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>33</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>33</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>33</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>33</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> -// CHECK-NEXT: <key>ranges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>33</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>33</integer> -// CHECK-NEXT: <key>col</key><integer>18</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Access to instance variable 'uniqueID' results in a dereference of a null pointer (loaded from variable 'self')</string> @@ -495,7 +514,7 @@ void repeatedStores(int coin) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>33</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -697,11 +716,45 @@ void repeatedStores(int coin) { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>50</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>50</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>50</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>50</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>50</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -735,7 +788,7 @@ void repeatedStores(int coin) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>50</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> diff --git a/test/Analysis/objc-boxing.m b/test/Analysis/objc-boxing.m index 1691578..98310b5 100644 --- a/test/Analysis/objc-boxing.m +++ b/test/Analysis/objc-boxing.m @@ -34,7 +34,7 @@ id constant_string() { } id dynamic_string() { - return @(strdup("boxed dynamic string")); // expected-warning{{Memory is never released; potential leak}} + return @(strdup("boxed dynamic string")); // expected-warning{{Potential memory leak}} } id const_char_pointer(int *x) { diff --git a/test/Analysis/objc-for.m b/test/Analysis/objc-for.m index 1561ef8..ef149c4 100644 --- a/test/Analysis/objc-for.m +++ b/test/Analysis/objc-for.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Loops,debug.ExprInspection -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.Loops,debug.ExprInspection -verify %s void clang_analyzer_eval(int); @@ -56,3 +56,15 @@ void testWithVarInFor() { clang_analyzer_eval(x != nil); // expected-warning{{UNKNOWN}} } +void testNonNil(id a, id b) { + clang_analyzer_eval(a != nil); // expected-warning{{UNKNOWN}} + for (id x in a) + clang_analyzer_eval(a != nil); // expected-warning{{TRUE}} + + if (b != nil) + return; + for (id x in b) + *(volatile int *)0 = 1; // no-warning + clang_analyzer_eval(b != nil); // expected-warning{{FALSE}} +} + diff --git a/test/Analysis/objc-string.mm b/test/Analysis/objc-string.mm new file mode 100644 index 0000000..c67ab5e --- /dev/null +++ b/test/Analysis/objc-string.mm @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s + +void clang_analyzer_eval(bool); +@class NSString; + +void sanity() { + clang_analyzer_eval(@""); // expected-warning{{TRUE}} + clang_analyzer_eval(@"abc"); // expected-warning{{TRUE}} +} + +namespace rdar13773117 { + NSString *const kConstantGlobalString = @"foo"; + NSString *globalString = @"bar"; + + extern void invalidateGlobals(); + + void testGlobals() { + clang_analyzer_eval(kConstantGlobalString); // expected-warning{{TRUE}} + clang_analyzer_eval(globalString); // expected-warning{{UNKNOWN}} + + globalString = @"baz"; + clang_analyzer_eval(globalString); // expected-warning{{TRUE}} + + invalidateGlobals(); + + clang_analyzer_eval(kConstantGlobalString); // expected-warning{{TRUE}} + clang_analyzer_eval(globalString); // expected-warning{{UNKNOWN}} + } + + NSString *returnString(NSString *input = @"garply") { + return input; + } + + void testDefaultArg() { + clang_analyzer_eval(returnString(@"")); // expected-warning{{TRUE}} + clang_analyzer_eval(returnString(0)); // expected-warning{{FALSE}} + clang_analyzer_eval(returnString()); // expected-warning{{TRUE}} + } +} diff --git a/test/Analysis/objc-subscript.m b/test/Analysis/objc-subscript.m index 324bf1c..ae621c9 100644 --- a/test/Analysis/objc-subscript.m +++ b/test/Analysis/objc-subscript.m @@ -39,9 +39,9 @@ typedef unsigned int NSUInteger; // <rdar://problem/8824416> for subscripting - (id)getDoesNotRetain:(BOOL)keyed { if (keyed) - return [self[self] autorelease]; // expected-warning{{Object sent -autorelease too many times}} + return [self[self] autorelease]; // expected-warning{{Object autoreleased too many times}} else - return [self[0] autorelease]; // expected-warning{{Object sent -autorelease too many times}} + return [self[0] autorelease]; // expected-warning{{Object autoreleased too many times}} } // <rdar://problem/9241180> for subscripting diff --git a/test/Analysis/objc_invalidation.m b/test/Analysis/objc_invalidation.m index a6f5ec3..6919fea 100644 --- a/test/Analysis/objc_invalidation.m +++ b/test/Analysis/objc_invalidation.m @@ -322,6 +322,47 @@ extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, #endif @end +@interface SomeNotInvalidatedInPartial : SomeInvalidationImplementingObject { + SomeInvalidationImplementingObject *Ivar1; + SomeInvalidationImplementingObject *Ivar2; +#if RUN_IVAR_INVALIDATION + // expected-warning@-2 {{Instance variable Ivar2 needs to be invalidated or set to nil}} +#endif +} +-(void)partialInvalidator __attribute__((annotate("objc_instance_variable_invalidator_partial"))); +-(void)partialInvalidatorCallsPartial __attribute__((annotate("objc_instance_variable_invalidator_partial"))); +@end +@implementation SomeNotInvalidatedInPartial { + SomeInvalidationImplementingObject *Ivar3; +#if RUN_IVAR_INVALIDATION + // expected-warning@-2 {{Instance variable Ivar3 needs to be invalidated or set to nil}} +#endif +} +-(void)partialInvalidator { + Ivar1 = 0; +} +-(void)partialInvalidatorCallsPartial { + [self partialInvalidator]; +} +@end + +@interface OnlyPartialDeclsBase : NSObject +-(void)partialInvalidator __attribute__((annotate("objc_instance_variable_invalidator_partial"))); +@end +@implementation OnlyPartialDeclsBase +-(void)partialInvalidator {} +@end + +@interface OnlyPartialDecls : OnlyPartialDeclsBase { + SomeInvalidationImplementingObject *Ivar1; +#if RUN_IVAR_INVALIDATION + // expected-warning@-2 {{Instance variable Ivar1 needs to be invalidated; no invalidation method is defined in the @implementation for OnlyPartialDecls}} +#endif +} +@end +@implementation OnlyPartialDecls +@end + // False negative. @interface PartialCallsFull : SomeInvalidationImplementingObject { SomeInvalidationImplementingObject *Ivar1; diff --git a/test/Analysis/operator-calls.cpp b/test/Analysis/operator-calls.cpp index 4f686e5..7461d75 100644 --- a/test/Analysis/operator-calls.cpp +++ b/test/Analysis/operator-calls.cpp @@ -49,3 +49,39 @@ namespace UserDefinedConversions { clang_analyzer_eval(obj); // expected-warning{{TRUE}} } } + + +namespace RValues { + struct SmallOpaque { + float x; + int operator +() const { + return (int)x; + } + }; + + struct LargeOpaque { + float x[4]; + int operator +() const { + return (int)x[0]; + } + }; + + SmallOpaque getSmallOpaque() { + SmallOpaque obj; + obj.x = 1.0; + return obj; + } + + LargeOpaque getLargeOpaque() { + LargeOpaque obj = LargeOpaque(); + obj.x[0] = 1.0; + return obj; + } + + void test(int coin) { + // Force a cache-out when we try to conjure a temporary region for the operator call. + // ...then, don't crash. + clang_analyzer_eval(+(coin ? getSmallOpaque() : getSmallOpaque())); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(+(coin ? getLargeOpaque() : getLargeOpaque())); // expected-warning{{UNKNOWN}} + } +} diff --git a/test/Analysis/plist-output-alternate.m b/test/Analysis/plist-output-alternate.m index bc9e103..93d0421 100644 --- a/test/Analysis/plist-output-alternate.m +++ b/test/Analysis/plist-output-alternate.m @@ -113,12 +113,12 @@ void rdar8331641(int x) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -130,7 +130,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -164,7 +164,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -256,12 +256,12 @@ void rdar8331641(int x) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>12</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>12</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -273,7 +273,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>12</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -307,7 +307,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>12</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -462,12 +462,12 @@ void rdar8331641(int x) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>19</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>19</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -479,7 +479,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>19</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -513,7 +513,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>19</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -618,11 +618,45 @@ void rdar8331641(int x) { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>24</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -656,7 +690,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>24</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -811,12 +845,12 @@ void rdar8331641(int x) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>31</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>31</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -828,7 +862,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>31</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -862,7 +896,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>31</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -988,12 +1022,12 @@ void rdar8331641(int x) { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>38</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>38</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -1005,7 +1039,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>38</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1039,7 +1073,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>38</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1328,7 +1362,7 @@ void rdar8331641(int x) { // CHECK-NEXT: <key>type</key><string>Leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>rdar8331641</string> -// CHECK-NEXT: <key>issue_hash</key><string>6</string> +// CHECK-NEXT: <key>issue_hash</key><string>2</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>58</integer> diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m index 80ce453..3dfd6be 100644 --- a/test/Analysis/plist-output.m +++ b/test/Analysis/plist-output.m @@ -184,6 +184,16 @@ int RDar13295437() { RDar13295437_f(sp->i); } +@interface Foo +- (int *) returnsPointer; +@end + +int testFoo(Foo *x) { + if (x) + return 1; + return *[x returnsPointer]; +} + // CHECK: <key>diagnostics</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> @@ -240,12 +250,12 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -257,7 +267,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -291,7 +301,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>6</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -383,12 +393,12 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>12</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>12</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -400,7 +410,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>12</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -434,7 +444,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>12</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -589,12 +599,12 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>19</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>19</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -606,7 +616,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>19</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -640,7 +650,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>19</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -745,11 +755,45 @@ int RDar13295437() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>24</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>24</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -783,7 +827,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>24</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -938,12 +982,12 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>31</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>31</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -955,7 +999,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>31</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -989,7 +1033,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>31</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1115,12 +1159,12 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>38</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>38</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -1132,7 +1176,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>38</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1166,7 +1210,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>38</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1418,12 +1462,12 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>50</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>50</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -1435,7 +1479,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>50</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1469,7 +1513,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>50</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -1830,12 +1874,12 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>77</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>77</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -1847,7 +1891,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>77</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1881,7 +1925,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>77</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -2097,7 +2141,7 @@ int RDar13295437() { // CHECK-NEXT: <key>type</key><string>Leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string> // CHECK-NEXT: <key>issue_context</key><string>test2</string> -// CHECK-NEXT: <key>issue_hash</key><string>4</string> +// CHECK-NEXT: <key>issue_hash</key><string>2</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>88</integer> @@ -2358,12 +2402,12 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>98</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>98</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -2375,7 +2419,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>98</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -2409,7 +2453,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>98</integer> -// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -2640,11 +2684,45 @@ int RDar13295437() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>111</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>111</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>111</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>111</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>111</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -2678,7 +2756,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>111</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -2909,11 +2987,45 @@ int RDar13295437() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>121</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>121</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>121</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>121</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>121</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -2947,7 +3059,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>121</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -3251,11 +3363,45 @@ int RDar13295437() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>130</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -3289,7 +3435,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>130</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -3656,11 +3802,45 @@ int RDar13295437() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>136</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>136</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>136</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>136</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>136</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -3694,7 +3874,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>136</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -4095,11 +4275,45 @@ int RDar13295437() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>145</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>145</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>145</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>145</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>145</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -4133,7 +4347,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>145</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -4534,11 +4748,45 @@ int RDar13295437() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>155</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>155</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>155</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>155</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>155</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -4572,6 +4820,52 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>155</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>163</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>163</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>163</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Value stored to 'x' is never read</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Value stored to 'x' is never read</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Value stored to 'x' is never read</string> +// CHECK-NEXT: <key>category</key><string>Dead store</string> +// CHECK-NEXT: <key>type</key><string>Dead increment</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>test_loop_fast_enumeration</string> +// CHECK-NEXT: <key>issue_hash</key><string>5</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>163</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -4706,11 +5000,45 @@ int RDar13295437() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>163</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>163</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>163</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>163</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>163</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -4744,53 +5072,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>163</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>path</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>163</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <key>ranges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>163</integer> -// CHECK-NEXT: <key>col</key><integer>8</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>163</integer> -// CHECK-NEXT: <key>col</key><integer>8</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>0</integer> -// CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Value stored to 'x' is never read</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Value stored to 'x' is never read</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Value stored to 'x' is never read</string> -// CHECK-NEXT: <key>category</key><string>Dead store</string> -// CHECK-NEXT: <key>type</key><string>Dead increment</string> -// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> -// CHECK-NEXT: <key>issue_context</key><string>test_loop_fast_enumeration</string> -// CHECK-NEXT: <key>issue_hash</key><string>5</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>163</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -4848,12 +5130,12 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>172</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>172</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -4865,7 +5147,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>172</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -4899,7 +5181,7 @@ int RDar13295437() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>172</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -5012,4 +5294,244 @@ int RDar13295437() { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Assuming 'x' is nil</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Assuming 'x' is nil</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>'returnsPointer' not called because the receiver is nil</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>'returnsPointer' not called because the receiver is nil</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>28</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>testFoo</string> +// CHECK-NEXT: <key>issue_hash</key><string>3</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>194</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> // CHECK-NEXT: </array> diff --git a/test/Analysis/pointer-to-member.cpp b/test/Analysis/pointer-to-member.cpp index 84dfe30..c9150e8 100644 --- a/test/Analysis/pointer-to-member.cpp +++ b/test/Analysis/pointer-to-member.cpp @@ -8,6 +8,9 @@ struct A { operator MemberPointer() const { return m_ptr ? &A::m_ptr : 0; } A *m_ptr; + + A *getPtr(); + typedef A * (A::*MemberFnPointer)(void); }; void testConditionalUse() { @@ -22,6 +25,40 @@ void testConditionalUse() { clang_analyzer_eval(obj.m_ptr); // expected-warning{{FALSE}} clang_analyzer_eval(A::MemberPointer(0)); // expected-warning{{FALSE}} clang_analyzer_eval(obj); // expected-warning{{FALSE}} + + clang_analyzer_eval(&A::getPtr); // expected-warning{{TRUE}} + clang_analyzer_eval(A::MemberFnPointer(0)); // expected-warning{{FALSE}} +} + + +void testComparison() { + clang_analyzer_eval(&A::getPtr == &A::getPtr); // expected-warning{{TRUE}} + + // FIXME: Should be TRUE. + clang_analyzer_eval(&A::m_ptr == &A::m_ptr); // expected-warning{{UNKNOWN}} +} + +namespace PR15742 { + template <class _T1, class _T2> struct A { + A (const _T1 &, const _T2 &); + }; + + typedef void *NPIdentifier; + + template <class T> class B { + public: + typedef A<NPIdentifier, bool (T::*) (const NPIdentifier *, unsigned, + NPIdentifier *)> MethodMapMember; + }; + + class C : public B<C> { + public: + bool Find(const NPIdentifier *, unsigned, NPIdentifier *); + }; + + void InitStaticData () { + C::MethodMapMember(0, &C::Find); // don't crash + } } // --------------- diff --git a/test/Analysis/properties.m b/test/Analysis/properties.m index 4aa9180..ddd0068 100644 --- a/test/Analysis/properties.m +++ b/test/Analysis/properties.m @@ -102,7 +102,7 @@ typedef struct _NSZone NSZone; else value = [[NSNumber alloc] initWithInteger:0]; - return [value autorelease]; // expected-warning {{Object sent -autorelease too many times}} + return [value autorelease]; // expected-warning {{Object autoreleased too many times}} } @end @@ -111,7 +111,7 @@ NSNumber* numberFromMyNumberProperty(MyNumber* aMyNumber) { NSNumber* result = aMyNumber.myNumber; - return [result autorelease]; // expected-warning {{Object sent -autorelease too many times}} + return [result autorelease]; // expected-warning {{Object autoreleased too many times}} } diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp index 8dd0baf..1dabe7b 100644 --- a/test/Analysis/reference.cpp +++ b/test/Analysis/reference.cpp @@ -102,7 +102,7 @@ void testRetroactiveNullReference(int *x) { // "null reference". So the 'if' statement ought to be dead code. // However, Clang (and other compilers) don't actually check that a pointer // value is non-null in the implementation of references, so it is possible - // to produce a supposed "null reference" at runtime. The analyzer shoeuld + // to produce a supposed "null reference" at runtime. The analyzer should // still warn when it can prove such errors. int &y = *x; if (x != 0) @@ -224,3 +224,13 @@ namespace rdar11212286 { return *x; // no-warning } } + +namespace PR15694 { + class C { + bool bit : 1; + template <class T> void bar(const T &obj) {} + void foo() { + bar(bit); // don't crash + } + }; +} diff --git a/test/Analysis/retain-release-path-notes-gc.m b/test/Analysis/retain-release-path-notes-gc.m index 913714e..f74d61f 100644 --- a/test/Analysis/retain-release-path-notes-gc.m +++ b/test/Analysis/retain-release-path-notes-gc.m @@ -139,7 +139,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -202,7 +202,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK-NEXT: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into 'leaked'</string> @@ -210,7 +210,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>type</key><string>Leak of object when using garbage collection</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>creationViaCFCreate</string> -// CHECK-NEXT: <key>issue_hash</key><string>2</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>44</integer> @@ -282,7 +282,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -357,7 +357,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Reference count incremented. The object now has a +2 retain count</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count incremented. The object now has a +2 retain count</string> +// CHECK-NEXT: <string>Reference count incremented. The object now has a +2 retain count</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -432,7 +432,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>In GC mode a call to 'CFMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. An object must have a 0 retain count to be garbage collected. After this call its retain count is +1</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>In GC mode a call to 'CFMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. An object must have a 0 retain count to be garbage collected. After this call its retain count is +1</string> +// CHECK-NEXT: <string>In GC mode a call to 'CFMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. An object must have a 0 retain count to be garbage collected. After this call its retain count is +1</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -507,7 +507,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>In GC mode a call to 'NSMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. Since it now has a 0 retain count the object can be automatically collected by the garbage collector</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>In GC mode a call to 'NSMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. Since it now has a 0 retain count the object can be automatically collected by the garbage collector</string> +// CHECK-NEXT: <string>In GC mode a call to 'NSMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. Since it now has a 0 retain count the object can be automatically collected by the garbage collector</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -582,7 +582,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Reference count incremented. The object now has a +1 retain count. The object is not eligible for garbage collection until the retain count reaches 0 again</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count incremented. The object now has a +1 retain count. The object is not eligible for garbage collection until the retain count reaches 0 again</string> +// CHECK-NEXT: <string>Reference count incremented. The object now has a +1 retain count. The object is not eligible for garbage collection until the retain count reaches 0 again</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -645,7 +645,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK-NEXT: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into 'leaked'</string> @@ -653,7 +653,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>type</key><string>Leak of object when using garbage collection</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>makeCollectable</string> -// CHECK-NEXT: <key>issue_hash</key><string>6</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>53</integer> @@ -725,7 +725,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Method returns an Objective-C object with a +0 retain count</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Method returns an Objective-C object with a +0 retain count</string> +// CHECK-NEXT: <string>Method returns an Objective-C object with a +0 retain count</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -800,7 +800,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>In GC mode the 'retain' message has no effect</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>In GC mode the 'retain' message has no effect</string> +// CHECK-NEXT: <string>In GC mode the 'retain' message has no effect</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -875,7 +875,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>In GC mode the 'release' message has no effect</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>In GC mode the 'release' message has no effect</string> +// CHECK-NEXT: <string>In GC mode the 'release' message has no effect</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -950,7 +950,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>In GC mode an 'autorelease' has no effect</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>In GC mode an 'autorelease' has no effect</string> +// CHECK-NEXT: <string>In GC mode an 'autorelease' has no effect</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -1013,7 +1013,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK-NEXT: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> @@ -1093,7 +1093,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -1168,7 +1168,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> +// CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> @@ -1197,7 +1197,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Object leaked: object allocated and stored into 'object' and returned from method 'getViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object leaked: object allocated and stored into 'object' and returned from method 'getViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string> +// CHECK-NEXT: <string>Object leaked: object allocated and stored into 'object' and returned from method 'getViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into 'object'</string> @@ -1205,7 +1205,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>type</key><string>Leak of returned object when using garbage collection</string> // CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string> // CHECK-NEXT: <key>issue_context</key><string>getViolation</string> -// CHECK-NEXT: <key>issue_hash</key><string>2</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>67</integer> @@ -1277,7 +1277,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK-NEXT: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -1352,7 +1352,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> +// CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> @@ -1381,7 +1381,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>extended_message</key> // CHECK-NEXT: <string>Object leaked: object allocated and stored into 'object' and returned from method 'copyViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object leaked: object allocated and stored into 'object' and returned from method 'copyViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string> +// CHECK-NEXT: <string>Object leaked: object allocated and stored into 'object' and returned from method 'copyViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into 'object'</string> @@ -1389,7 +1389,7 @@ void retainReleaseIgnored () { // CHECK-NEXT: <key>type</key><string>Leak of returned object when using garbage collection</string> // CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string> // CHECK-NEXT: <key>issue_context</key><string>copyViolation</string> -// CHECK-NEXT: <key>issue_hash</key><string>2</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>72</integer> diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m index 8809c57..a3c681a 100644 --- a/test/Analysis/retain-release-path-notes.m +++ b/test/Analysis/retain-release-path-notes.m @@ -86,15 +86,15 @@ void implicitDealloc () { void overAutorelease () { id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}} - [object autorelease]; // expected-note{{Object sent -autorelease message}} - [object autorelease]; // expected-note{{Object sent -autorelease message}} - return; // expected-warning{{Object sent -autorelease too many times}} expected-note{{Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count}} + [object autorelease]; // expected-note{{Object autoreleased}} + [object autorelease]; // expected-note{{Object autoreleased}} + return; // expected-warning{{Object autoreleased too many times}} expected-note{{Object was autoreleased 2 times but the object has a +1 retain count}} } void autoreleaseUnowned (Foo *foo) { id object = foo.propertyValue; // expected-note{{Property returns an Objective-C object with a +0 retain count}} - [object autorelease]; // expected-note{{Object sent -autorelease message}} - return; // expected-warning{{Object sent -autorelease too many times}} expected-note{{Object over-autoreleased: object was sent -autorelease but the object has a +0 retain count}} + [object autorelease]; // expected-note{{Object autoreleased}} + return; // expected-warning{{Object autoreleased too many times}} expected-note{{Object was autoreleased but has a +0 retain count}} } void makeCollectableIgnored () { @@ -137,7 +137,7 @@ CFTypeRef CFGetRuleViolation () { - (id)copyAutorelease { id result = [[Foo alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}} - [result autorelease]; // expected-note{{Object sent -autorelease message}} + [result autorelease]; // expected-note{{Object autoreleased}} return result; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} } @end @@ -190,6 +190,56 @@ void testDictionary(id key, id value) { [result release]; // expected-warning{{decrement}} expected-note{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} } +// Test that we step into the init method when the allocated object is leaked due to early escape within init. + +static int Cond; +@interface MyObj : NSObject +-(id)initX; +-(id)initY; +-(id)initZ; ++(void)test; +@end + +@implementation MyObj + +-(id)initX { + if (Cond) // expected-note {{Assuming 'Cond' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + return 0; + self = [super init]; + return self; +} + +-(id)initY { + self = [super init]; //expected-note {{Method returns an Objective-C object with a +1 retain count}} + return self; +} + +-(id)initZ { + self = [super init]; + return self; +} + ++(void)test { + // initX is inlined since we explicitely mark it as interesting + id x = [[MyObj alloc] initX]; // expected-warning {{Potential leak of an object}} + // expected-note@-1 {{Method returns an Objective-C object with a +1 retain count}} + // expected-note@-2 {{Calling 'initX'}} + // expected-note@-3 {{Returning from 'initX'}} + // expected-note@-4 {{Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1}} + // initI is inlined because the allocation happens within initY + id y = [[MyObj alloc] initY]; // expected-warning {{Potential leak of an object}} + // expected-note@-1 {{Calling 'initY'}} + // expected-note@-2 {{Returning from 'initY'}} + + // initZ is not inlined + id z = [[MyObj alloc] initZ]; + // expected-note@-1 {{Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1}} + + [x release]; + [z release]; +} +@end // CHECK: <key>diagnostics</key> // CHECK-NEXT: <array> @@ -328,7 +378,7 @@ void testDictionary(id key, id value) { // CHECK-NEXT: <key>type</key><string>Leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>creationViaAlloc</string> -// CHECK-NEXT: <key>issue_hash</key><string>2</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>47</integer> @@ -471,7 +521,7 @@ void testDictionary(id key, id value) { // CHECK-NEXT: <key>type</key><string>Leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>creationViaCFCreate</string> -// CHECK-NEXT: <key>issue_hash</key><string>2</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>52</integer> @@ -839,7 +889,7 @@ void testDictionary(id key, id value) { // CHECK-NEXT: <key>type</key><string>Leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>acquisitionViaMethod</string> -// CHECK-NEXT: <key>issue_hash</key><string>5</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>60</integer> @@ -1057,7 +1107,7 @@ void testDictionary(id key, id value) { // CHECK-NEXT: <key>type</key><string>Leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>acquisitionViaProperty</string> -// CHECK-NEXT: <key>issue_hash</key><string>3</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>66</integer> @@ -1275,7 +1325,7 @@ void testDictionary(id key, id value) { // CHECK-NEXT: <key>type</key><string>Leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>acquisitionViaCFFunction</string> -// CHECK-NEXT: <key>issue_hash</key><string>3</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>72</integer> @@ -1856,9 +1906,9 @@ void testDictionary(id key, id value) { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -1931,9 +1981,9 @@ void testDictionary(id key, id value) { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -1994,14 +2044,14 @@ void testDictionary(id key, id value) { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string> +// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string> +// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Object sent -autorelease too many times</string> +// CHECK-NEXT: <key>description</key><string>Object autoreleased too many times</string> // CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> -// CHECK-NEXT: <key>type</key><string>Object sent -autorelease too many times</string> +// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>overAutorelease</string> // CHECK-NEXT: <key>issue_hash</key><string>4</string> @@ -2149,9 +2199,9 @@ void testDictionary(id key, id value) { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -2212,14 +2262,14 @@ void testDictionary(id key, id value) { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease but the object has a +0 retain count</string> +// CHECK-NEXT: <string>Object was autoreleased but has a +0 retain count</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease but the object has a +0 retain count</string> +// CHECK-NEXT: <string>Object was autoreleased but has a +0 retain count</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Object sent -autorelease too many times</string> +// CHECK-NEXT: <key>description</key><string>Object autoreleased too many times</string> // CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> -// CHECK-NEXT: <key>type</key><string>Object sent -autorelease too many times</string> +// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>autoreleaseUnowned</string> // CHECK-NEXT: <key>issue_hash</key><string>3</string> @@ -2515,7 +2565,7 @@ void testDictionary(id key, id value) { // CHECK-NEXT: <key>type</key><string>Leak</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>makeCollectableIgnored</string> -// CHECK-NEXT: <key>issue_hash</key><string>4</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>104</integer> @@ -2883,7 +2933,7 @@ void testDictionary(id key, id value) { // CHECK-NEXT: <key>type</key><string>Leak of returned object</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>CFGetRuleViolation</string> -// CHECK-NEXT: <key>issue_hash</key><string>2</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>114</integer> @@ -3619,7 +3669,7 @@ void testDictionary(id key, id value) { // CHECK-NEXT: <key>type</key><string>Leak of returned object</string> // CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string> // CHECK-NEXT: <key>issue_context</key><string>getViolation</string> -// CHECK-NEXT: <key>issue_hash</key><string>2</string> +// CHECK-NEXT: <key>issue_hash</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>135</integer> @@ -3764,9 +3814,9 @@ void testDictionary(id key, id value) { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -4560,4 +4610,735 @@ void testDictionary(id key, id value) { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>23</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>30</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling 'initX'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling 'initX'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>205</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Entered call from 'test'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'test'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>205</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>205</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Assuming 'Cond' is not equal to 0</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Assuming 'Cond' is not equal to 0</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>208</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>208</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>30</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Returning from 'initX'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Returning from 'initX'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Potential leak of an object</string> +// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK-NEXT: <key>type</key><string>Leak</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string> +// CHECK-NEXT: <key>issue_context</key><string>test</string> +// CHECK-NEXT: <key>issue_hash</key><string>2</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>225</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>231</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>231</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>231</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>231</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>231</integer> +// CHECK-NEXT: <key>col</key><integer>30</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling 'initY'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling 'initY'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Entered call from 'test'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'test'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>231</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>231</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>231</integer> +// CHECK-NEXT: <key>col</key><integer>30</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Returning from 'initY'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Returning from 'initY'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>231</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>231</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>236</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>236</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>236</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>236</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>236</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>236</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>236</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>236</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>236</integer> +// CHECK-NEXT: <key>col</key><integer>23</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Potential leak of an object</string> +// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK-NEXT: <key>type</key><string>Leak</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string> +// CHECK-NEXT: <key>issue_context</key><string>test</string> +// CHECK-NEXT: <key>issue_hash</key><string>8</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>236</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> // CHECK-NEXT: </array> diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 5841650..bb4a1d1 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -479,20 +479,20 @@ void f13_autorelease_b() { CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); [(id) A autorelease]; [(id) A autorelease]; -} // expected-warning{{Object sent -autorelease too many times}} +} // expected-warning{{Object autoreleased too many times}} CFMutableArrayRef f13_autorelease_c() { CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); [(id) A autorelease]; [(id) A autorelease]; - return A; // expected-warning{{Object sent -autorelease too many times}} + return A; // expected-warning{{Object autoreleased too many times}} } CFMutableArrayRef f13_autorelease_d() { CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); [(id) A autorelease]; [(id) A autorelease]; - CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object sent -autorelease too many times}} + CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object autoreleased too many times}} CFRelease(B); // no-warning while (1) {} } @@ -1983,6 +1983,45 @@ void testCustomReturnsNotRetained() { CFRelease(getCustom()); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} } +//===----------------------------------------------------------------------===// +// Don't print variables which are out of the current scope. +//===----------------------------------------------------------------------===// +@interface MyObj12706177 : NSObject +-(id)initX; ++(void)test12706177; +@end +static int Cond; +@implementation MyObj12706177 +-(id)initX { + if (Cond) + return 0; + self = [super init]; + return self; +} ++(void)test12706177 { + id x = [[MyObj12706177 alloc] initX]; //expected-warning {{Potential leak of an object}} + [x release]; +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/13783514> xpc_connection_set_finalizer_f +//===----------------------------------------------------------------------===// + +typedef xpc_object_t xpc_connection_t; +typedef void (*xpc_finalizer_t)(void *value); +void xpc_connection_set_context(xpc_connection_t connection, void *ctx); +void xpc_connection_set_finalizer_f(xpc_connection_t connection, + xpc_finalizer_t finalizer); +void releaseAfterXPC(void *context) { + [(NSArray *)context release]; +} + +void rdar13783514(xpc_connection_t connection) { + xpc_connection_set_context(connection, [[NSMutableArray alloc] init]); + xpc_connection_set_finalizer_f(connection, releaseAfterXPC); +} // no-warning + // CHECK: <key>diagnostics</key> // CHECK-NEXT: <array> @@ -8910,9 +8949,9 @@ void testCustomReturnsNotRetained() { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -8985,9 +9024,9 @@ void testCustomReturnsNotRetained() { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -9033,14 +9072,14 @@ void testCustomReturnsNotRetained() { // CHECK-NEXT: </dict> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string> +// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string> +// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Object sent -autorelease too many times</string> +// CHECK-NEXT: <key>description</key><string>Object autoreleased too many times</string> // CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> -// CHECK-NEXT: <key>type</key><string>Object sent -autorelease too many times</string> +// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>f13_autorelease_b</string> // CHECK-NEXT: <key>issue_hash</key><string>4</string> @@ -9188,9 +9227,9 @@ void testCustomReturnsNotRetained() { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -9263,9 +9302,9 @@ void testCustomReturnsNotRetained() { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -9326,14 +9365,14 @@ void testCustomReturnsNotRetained() { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +0 retain count</string> +// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +0 retain count</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +0 retain count</string> +// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +0 retain count</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Object sent -autorelease too many times</string> +// CHECK-NEXT: <key>description</key><string>Object autoreleased too many times</string> // CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> -// CHECK-NEXT: <key>type</key><string>Object sent -autorelease too many times</string> +// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>f13_autorelease_c</string> // CHECK-NEXT: <key>issue_hash</key><string>4</string> @@ -9481,9 +9520,9 @@ void testCustomReturnsNotRetained() { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -9556,9 +9595,9 @@ void testCustomReturnsNotRetained() { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -9653,14 +9692,14 @@ void testCustomReturnsNotRetained() { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string> +// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string> +// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Object sent -autorelease too many times</string> +// CHECK-NEXT: <key>description</key><string>Object autoreleased too many times</string> // CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> -// CHECK-NEXT: <key>type</key><string>Object sent -autorelease too many times</string> +// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>f13_autorelease_d</string> // CHECK-NEXT: <key>issue_hash</key><string>4</string> @@ -13586,9 +13625,9 @@ void testCustomReturnsNotRetained() { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -20108,9 +20147,9 @@ void testCustomReturnsNotRetained() { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object sent -autorelease message</string> +// CHECK-NEXT: <string>Object autoreleased</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> diff --git a/test/Analysis/retain-release.mm b/test/Analysis/retain-release.mm index 47d67ea..3650d88 100644 --- a/test/Analysis/retain-release.mm +++ b/test/Analysis/retain-release.mm @@ -83,6 +83,7 @@ typedef UInt32 CFStringEncoding; enum { kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 }; extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); +extern CFStringRef CFStringCreateCopy(CFAllocatorRef alloc, CFStringRef theString); typedef double CFTimeInterval; typedef CFTimeInterval CFAbsoluteTime; extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); @@ -269,7 +270,6 @@ extern void CGContextDrawLinearGradient(CGContextRef context, CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, CGGradientDrawingOptions options); extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); - //===----------------------------------------------------------------------===// // Test cases. //===----------------------------------------------------------------------===// @@ -408,3 +408,56 @@ void testCallback() { } @end +//===----------------------------------------------------------------------===// +// Don't crash on getting a null expression from CallEnter corresponding to a +// destructor. +//===----------------------------------------------------------------------===// + +template <typename X> +class Holder { +public: + Holder() throw(); + ~Holder() throw() {} + X* get() const throw(); + void reset(X* p) throw(); +private: + X* ptr_; +}; + +template<typename X> +inline +Holder<X>::Holder() throw() +: ptr_(0){} + +template <typename X> +inline +X* Holder<X>::get() const throw() { + return ptr_; +} + +template <typename X> +inline +void Holder<X>::reset(X* p) throw() { + if (ptr_ != p) { + if (ptr_ != 0) { + ::CFRelease( ptr_ ); + } + ptr_ = p; + } +} + +class radar13722286 { +public: + radar13722286() {} +private: + void PrepareBitmap(); + Holder<const struct __CFString> mStr; +}; + +void radar13722286::PrepareBitmap() { + if (mStr.get() != 0) { + Holder<const struct __CFString> str1; + mStr.reset( CFStringCreateCopy( 0, str1.get() ) ); //expected-warning {{Potential leak of an object}} + } +} + diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp index 7aefea5..65d7571 100644 --- a/test/Analysis/stack-addr-ps.cpp +++ b/test/Analysis/stack-addr-ps.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s -// FIXME: Only the stack-address checking in Sema catches this right now, and -// the stack analyzer doesn't handle the ImplicitCastExpr (lvalue). +typedef __INTPTR_TYPE__ intptr_t; + const int& g() { int s; return s; // expected-warning{{Address of stack memory associated with local variable 's' returned}} expected-warning{{reference to stack memory associated with local variable 's' returned}} @@ -96,3 +96,40 @@ void *radar13226577() { return p; // expected-warning {{stack memory associated with local variable 'p' returned to caller}} } +namespace rdar13296133 { + class ConvertsToBool { + public: + operator bool() const { return this; } + }; + + class ConvertsToIntptr { + public: + operator intptr_t() const { return reinterpret_cast<intptr_t>(this); } + }; + + class ConvertsToPointer { + public: + operator const void *() const { return this; } + }; + + intptr_t returnAsNonLoc() { + ConvertsToIntptr obj; + return obj; // expected-warning{{Address of stack memory associated with local variable 'obj' returned to caller}} + } + + bool returnAsBool() { + ConvertsToBool obj; + return obj; // no-warning + } + + intptr_t returnAsNonLocViaPointer() { + ConvertsToPointer obj; + return reinterpret_cast<intptr_t>(static_cast<const void *>(obj)); // expected-warning{{Address of stack memory associated with local variable 'obj' returned to caller}} + } + + bool returnAsBoolViaPointer() { + ConvertsToPointer obj; + return obj; // no-warning + } +} + diff --git a/test/Analysis/stackaddrleak.c b/test/Analysis/stackaddrleak.c index 10564fa..4f81f66 100644 --- a/test/Analysis/stackaddrleak.c +++ b/test/Analysis/stackaddrleak.c @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -std=c99 -Dbool=_Bool %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -x c++ %s +typedef __INTPTR_TYPE__ intptr_t; char const *p; void f0() { @@ -15,7 +17,7 @@ void f1() { void f2() { p = (const char *) __builtin_alloca(12); -} // expected-warning{{Address of stack memory allocated by call to alloca() on line 17 is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}} +} // expected-warning{{Address of stack memory allocated by call to alloca() on line 19 is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}} // PR 7383 - previosly the stack address checker would crash on this example // because it would attempt to do a direct load from 'pr7383_list'. @@ -32,3 +34,25 @@ void test_multi_return() { a = &x; b = &x; } // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'a' upon returning}} expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'b' upon returning}} + +intptr_t returnAsNonLoc() { + int x; + return (intptr_t)&x; // expected-warning{{Address of stack memory associated with local variable 'x' returned to caller}} +} + +bool returnAsBool() { + int x; + return &x; // no-warning +} + +void assignAsNonLoc() { + extern intptr_t ip; + int x; + ip = (intptr_t)&x; +} // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'ip' upon returning}} + +void assignAsBool() { + extern bool b; + int x; + b = &x; +} // no-warning diff --git a/test/Analysis/string.c b/test/Analysis/string.c index 74cf33c..6cf52f7 100644 --- a/test/Analysis/string.c +++ b/test/Analysis/string.c @@ -1028,6 +1028,57 @@ void strncasecmp_embedded_null () { } //===----------------------------------------------------------------------=== +// strsep() +//===----------------------------------------------------------------------=== + +char *strsep(char **stringp, const char *delim); + +void strsep_null_delim(char *s) { + strsep(&s, NULL); // expected-warning{{Null pointer argument in call to strsep()}} +} + +void strsep_null_search() { + strsep(NULL, ""); // expected-warning{{Null pointer argument in call to strsep()}} +} + +void strsep_return_original_pointer(char *s) { + char *original = s; + char *result = strsep(&s, ""); // no-warning + clang_analyzer_eval(original == result); // expected-warning{{TRUE}} +} + +void strsep_null_string() { + char *s = NULL; + char *result = strsep(&s, ""); // no-warning + clang_analyzer_eval(result == NULL); // expected-warning{{TRUE}} +} + +void strsep_changes_input_pointer(char *s) { + char *original = s; + strsep(&s, ""); // no-warning + clang_analyzer_eval(s == original); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(s == NULL); // expected-warning{{UNKNOWN}} + + // Check that the value is symbolic. + if (s == NULL) { + clang_analyzer_eval(s == NULL); // expected-warning{{TRUE}} + } +} + +void strsep_changes_input_string() { + char str[] = "abc"; + + clang_analyzer_eval(str[1] == 'b'); // expected-warning{{TRUE}} + + char *s = str; + strsep(&s, "b"); // no-warning + + // The real strsep will change the first delimiter it finds into a NUL + // character. For now, we just model the invalidation. + clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}} +} + +//===----------------------------------------------------------------------=== // FIXMEs //===----------------------------------------------------------------------=== diff --git a/test/Analysis/svalbuilder-logic.c b/test/Analysis/svalbuilder-logic.c index 41d4fe2..9cf3f96 100644 --- a/test/Analysis/svalbuilder-logic.c +++ b/test/Analysis/svalbuilder-logic.c @@ -6,3 +6,11 @@ int SValBuilderLogicNoCrash(int *x) { return 3 - (int)(x +3); } + +// http://llvm.org/bugs/show_bug.cgi?id=15863 +// Don't crash when mixing 'bool' and 'int' in implicit comparisons to 0. +void pr15863() { + extern int getBool(); + _Bool a = getBool(); + (void)!a; // no-warning +} diff --git a/test/Analysis/taint-tester.c b/test/Analysis/taint-tester.c index 7b0ab2a..6287198 100644 --- a/test/Analysis/taint-tester.c +++ b/test/Analysis/taint-tester.c @@ -1,10 +1,6 @@ // RUN: %clang_cc1 -Wno-int-to-pointer-cast -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify -#include <stdarg.h> - -int scanf(const char *restrict format, ...); -int getchar(void); -typedef __typeof(sizeof(int)) size_t; +#include "Inputs/system-header-simulator.h" #define BUFSIZE 10 int Buffer[BUFSIZE]; @@ -87,15 +83,6 @@ void getenvTest(char *home) { } } -typedef struct _FILE FILE; -extern FILE *stdin; -extern FILE *stdout; -extern FILE *stderr; -int fscanf(FILE *restrict stream, const char *restrict format, ...); -int fprintf(FILE *stream, const char *format, ...); -int fclose(FILE *stream); -FILE *fopen(const char *path, const char *mode); - int fscanfTest(void) { FILE *fp; char s[80]; diff --git a/test/Analysis/temporaries.cpp b/test/Analysis/temporaries.cpp index 32a4d3b..efc0825 100644 --- a/test/Analysis/temporaries.cpp +++ b/test/Analysis/temporaries.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++03 %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++11 %s extern bool clang_analyzer_eval(bool); @@ -76,3 +77,35 @@ namespace rdar13281951 { } } +namespace compound_literals { + struct POD { + int x, y; + }; + struct HasCtor { + HasCtor(int x, int y) : x(x), y(y) {} + int x, y; + }; + struct HasDtor { + int x, y; + ~HasDtor(); + }; + struct HasCtorDtor { + HasCtorDtor(int x, int y) : x(x), y(y) {} + ~HasCtorDtor(); + int x, y; + }; + + void test() { + clang_analyzer_eval(((POD){1, 42}).y == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(((HasDtor){1, 42}).y == 42); // expected-warning{{TRUE}} + +#if __cplusplus >= 201103L + clang_analyzer_eval(((HasCtor){1, 42}).y == 42); // expected-warning{{TRUE}} + + // FIXME: should be TRUE, but we don't inline the constructors of + // temporaries because we can't model their destructors yet. + clang_analyzer_eval(((HasCtorDtor){1, 42}).y == 42); // expected-warning{{UNKNOWN}} +#endif + } +} + diff --git a/test/Analysis/uninit-vals-ps.c b/test/Analysis/uninit-vals-ps.c index 09736ef..ad40b15 100644 --- a/test/Analysis/uninit-vals-ps.c +++ b/test/Analysis/uninit-vals-ps.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -verify %s struct FPRec { void (*my_func)(int * x); @@ -122,6 +122,8 @@ int pr4631_f1_b(void) return x; // no-warning } +// <rdar://problem/12278788> - FP when returning a void-valued expression from +// a void function...or block. void foo_radar12278788() { return; } void test_radar12278788() { return foo_radar12278788(); // no-warning @@ -134,3 +136,16 @@ int test_radar12278788_FP() { RetVoidFuncType f = foo_radar12278788_fp; return ((RetIntFuncType)f)(); //expected-warning {{Undefined or garbage value returned to caller}} } + +void rdar13665798() { + ^() { + return foo_radar12278788(); // no-warning + }(); + ^void() { + return foo_radar12278788(); // no-warning + }(); + ^int() { + RetVoidFuncType f = foo_radar12278788_fp; + return ((RetIntFuncType)f)(); //expected-warning {{Undefined or garbage value returned to caller}} + }(); +} diff --git a/test/Analysis/uninit-vals.m b/test/Analysis/uninit-vals.m index 5a97bef..72b6739 100644 --- a/test/Analysis/uninit-vals.m +++ b/test/Analysis/uninit-vals.m @@ -43,6 +43,7 @@ void PR10163 (void) { typedef struct { float x; float y; + float z; } Point; typedef struct { Point origin; @@ -53,6 +54,7 @@ Point makePoint(float x, float y) { Point result; result.x = x; result.y = y; + result.z = 0.0; return result; } @@ -85,6 +87,7 @@ void PR14765_argument(Circle *testObj) { typedef struct { int x; int y; + int z; } IntPoint; typedef struct { IntPoint origin; @@ -95,6 +98,7 @@ IntPoint makeIntPoint(int x, int y) { IntPoint result; result.x = x; result.y = y; + result.z = 0; return result; } @@ -104,6 +108,7 @@ void PR14765_test_int() { clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}} clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}} clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}} testObj->origin = makeIntPoint(1, 2); if (testObj->size > 0) { ; } // warning occurs here @@ -115,6 +120,7 @@ void PR14765_test_int() { clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}} clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}} clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}} free(testObj); } @@ -127,6 +133,7 @@ void PR14765_argument_int(IntCircle *testObj) { clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}} clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}} clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}} } @@ -141,3 +148,137 @@ void rdar13292559(Circle input) { useCircle(obj); // no-warning } + +typedef struct { + int x; + int y; +} IntPoint2D; +typedef struct { + IntPoint2D origin; + int size; +} IntCircle2D; + +IntPoint2D makeIntPoint2D(int x, int y) { + IntPoint2D result; + result.x = x; + result.y = y; + return result; +} + +void testSmallStructsCopiedPerField() { + IntPoint2D a; + a.x = 0; + + IntPoint2D b = a; + extern void useInt(int); + useInt(b.x); // no-warning + useInt(b.y); // expected-warning{{uninitialized}} +} + +void testLargeStructsNotCopiedPerField() { + IntPoint a; + a.x = 0; + + IntPoint b = a; + extern void useInt(int); + useInt(b.x); // no-warning + useInt(b.y); // no-warning +} + +void testSmallStructInLargerStruct() { + IntCircle2D *testObj = calloc(sizeof(IntCircle2D), 1); + + clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}} + + testObj->origin = makeIntPoint2D(1, 2); + if (testObj->size > 0) { ; } // warning occurs here + + clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}} + + free(testObj); +} + +void testCopySmallStructIntoArgument(IntCircle2D *testObj) { + int oldSize = testObj->size; + clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}} + + testObj->origin = makeIntPoint2D(1, 2); + clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}} + clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}} +} + +void testSmallStructBitfields() { + struct { + int x : 4; + int y : 4; + } a, b; + + a.x = 1; + a.y = 2; + + b = a; + clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}} +} + +void testSmallStructBitfieldsFirstUndef() { + struct { + int x : 4; + int y : 4; + } a, b; + + a.y = 2; + + b = a; + clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}} +} + +void testSmallStructBitfieldsSecondUndef() { + struct { + int x : 4; + int y : 4; + } a, b; + + a.x = 1; + + b = a; + clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}} +} + +void testSmallStructBitfieldsFirstUnnamed() { + struct { + int : 4; + int y : 4; + } a, b, c; + + a.y = 2; + + b = a; + clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}} + + b = c; + clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}} +} + +void testSmallStructBitfieldsSecondUnnamed() { + struct { + int x : 4; + int : 4; + } a, b, c; + + a.x = 1; + + b = a; + clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}} + + b = c; + clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}} +} + diff --git a/test/Analysis/unix-fns.c b/test/Analysis/unix-fns.c index 8daac1c..46c1013 100644 --- a/test/Analysis/unix-fns.c +++ b/test/Analysis/unix-fns.c @@ -1662,11 +1662,45 @@ void test_inline_dispatch_once() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>192</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>192</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -1697,7 +1731,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>192</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -2013,11 +2047,45 @@ void test_inline_dispatch_once() { // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>202</integer> -// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> @@ -2048,7 +2116,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>202</integer> -// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp index 7da3087..6fba972 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp @@ -47,3 +47,26 @@ class Other { void Other::foo(YFloat a, YFloat b) { YFloat c = a - b; } + +// <rdar://problem/13540899> +namespace Other { + void other_foo(); +} + +namespace M2 { + using namespace Other; + + extern "C" { + namespace MInner { + extern "C" { + class Bar { + void bar(); + }; + } + } + } +} + +void M2::MInner::Bar::bar() { + other_foo(); +} diff --git a/test/CXX/basic/basic.types/p10.cpp b/test/CXX/basic/basic.types/p10.cpp index 6401c29..9d99a77 100644 --- a/test/CXX/basic/basic.types/p10.cpp +++ b/test/CXX/basic/basic.types/p10.cpp @@ -1,9 +1,16 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1y %s -DCXX1Y struct NonLiteral { NonLiteral(); }; // A type is a literal type if it is: +// [C++1y] - void +constexpr void f() {} +#ifndef CXX1Y +// expected-error@-2 {{'void' is not a literal type}} +#endif + // - a scalar type constexpr int f1(double) { return 0; } @@ -11,7 +18,6 @@ constexpr int f1(double) { return 0; } struct S { S(); }; constexpr int f2(S &) { return 0; } -// FIXME: I'm not entirely sure whether the following is legal or not... struct BeingDefined; extern BeingDefined beingdefined; struct BeingDefined { @@ -32,13 +38,13 @@ constexpr ClassTemp<int> classtemplate2[] = {}; // - it has a trivial destructor struct UserProvDtor { - constexpr int f(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}} + constexpr int f() const; // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}} ~UserProvDtor(); // expected-note {{has a user-provided destructor}} }; struct NonTrivDtor { constexpr NonTrivDtor(); - constexpr int f(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}} + constexpr int f() const; // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}} virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}} expected-note {{because it is virtual}} }; struct NonTrivDtorBase { @@ -71,11 +77,11 @@ struct CtorTemplate { }; struct CopyCtorOnly { // expected-note {{'CopyCtorOnly' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}} constexpr CopyCtorOnly(CopyCtorOnly&); - constexpr int f(); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}} + constexpr int f() const; // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}} }; struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}} constexpr MoveCtorOnly(MoveCtorOnly&&); - constexpr int f(); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}} + constexpr int f() const; // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}} }; template<typename T> struct CtorArg { @@ -104,7 +110,7 @@ constexpr int f(NonLitMember) {} // expected-error {{1st parameter type 'NonLitM struct NonLitBase : S { // expected-note {{base class 'S' of non-literal type}} constexpr NonLitBase(); - constexpr int f() { return 0; } // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}} + constexpr int f() const { return 0; } // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}} }; struct LitMemBase : Agg { Agg agg; @@ -117,7 +123,7 @@ struct MemberType { constexpr int f(MemberType<int>) { return 0; } constexpr int f(MemberType<NonLiteral>) { return 0; } // expected-error {{not a literal type}} -// - an array of literal type +// - an array of literal type [C++1y] other than an array of runtime bound struct ArrGood { Agg agg[24]; double d[12]; @@ -130,3 +136,7 @@ struct ArrBad { S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}} }; constexpr int f(ArrBad) { return 0; } // expected-error {{1st parameter type 'ArrBad' is not a literal type}} + +constexpr int arb(int n) { + int a[n]; // expected-error {{variable of non-literal type 'int [n]' cannot be defined in a constexpr function}} +} diff --git a/test/CXX/class/class.friend/p6.cpp b/test/CXX/class/class.friend/p6.cpp index 7d7a064..82ca50e 100644 --- a/test/CXX/class/class.friend/p6.cpp +++ b/test/CXX/class/class.friend/p6.cpp @@ -1,10 +1,18 @@ -// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -verify -std=c++11 %s class A { friend static class B; // expected-error {{'static' is invalid in friend declarations}} friend extern class C; // expected-error {{'extern' is invalid in friend declarations}} - friend auto class D; // expected-warning {{incompatible with C++11}} expected-error {{'auto' is invalid in friend declarations}} friend register class E; // expected-error {{'register' is invalid in friend declarations}} friend mutable class F; // expected-error {{'mutable' is invalid in friend declarations}} friend typedef class G; // expected-error {{'typedef' is invalid in friend declarations}} + friend __thread class G; // expected-error {{'__thread' is invalid in friend declarations}} + friend _Thread_local class G; // expected-error {{'_Thread_local' is invalid in friend declarations}} + friend static _Thread_local class G; // expected-error {{'static _Thread_local' is invalid in friend declarations}} +#if __cplusplus < 201103L + friend auto class D; // expected-warning {{incompatible with C++11}} expected-error {{'auto' is invalid in friend declarations}} +#else + friend thread_local class G; // expected-error {{'thread_local' is invalid in friend declarations}} +#endif }; diff --git a/test/CXX/dcl.dcl/dcl.link/p7-2.cpp b/test/CXX/dcl.dcl/dcl.link/p7-2.cpp new file mode 100644 index 0000000..40f61c6 --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.link/p7-2.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -ast-print -o - %s | FileCheck %s + +extern "C" void f(void); +// CHECK: extern "C" void f() + +extern "C" void v; +// CHECK: extern "C" void v diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp index a3a964a..122a400 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp @@ -71,7 +71,7 @@ struct ConstexprDtor { template <typename T> constexpr T ft(T t) { return t; } template <typename T> T gt(T t) { return t; } struct S { - template<typename T> constexpr T f(); + template<typename T> constexpr T f(); // expected-warning {{C++1y}} template<typename T> T g() const; }; @@ -81,7 +81,7 @@ template <> char ft(char c) { return c; } // expected-note {{previous}} template <> constexpr char ft(char nl); // expected-error {{constexpr declaration of 'ft<char>' follows non-constexpr declaration}} template <> constexpr int gt(int nl) { return nl; } template <> notlit S::f() const { return notlit(); } -template <> constexpr int S::g() { return 0; } // expected-note {{previous}} +template <> constexpr int S::g() { return 0; } // expected-note {{previous}} expected-warning {{C++1y}} template <> int S::g() const; // expected-error {{non-constexpr declaration of 'g<int>' follows constexpr declaration}} // specializations can drop the 'constexpr' but not the implied 'const'. template <> char S::g() { return 0; } // expected-error {{no function template matches}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp index cafdd63..4393727 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -verify -std=c++11 %s +// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++1y-extensions %s +// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++1y -DCXX1Y %s namespace N { typedef char C; @@ -8,7 +9,7 @@ namespace M { typedef double D; } -struct NonLiteral { // expected-note 2{{no constexpr constructors}} +struct NonLiteral { // expected-note 3{{no constexpr constructors}} NonLiteral() {} NonLiteral(int) {} }; @@ -28,45 +29,53 @@ struct SS : S { // constraints: struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}} constexpr T(); - constexpr int f(); // expected-error {{non-literal type 'T' cannot have constexpr members}} + constexpr int f() const; // expected-error {{non-literal type 'T' cannot have constexpr members}} // - it shall not be virtual; - virtual constexpr int ExplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}} + virtual constexpr int ExplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}} - constexpr int ImplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}} + constexpr int ImplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}} // - its return type shall be a literal type; - constexpr NonLiteral NonLiteralReturn() { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} - constexpr void VoidReturn() { return; } // expected-error {{constexpr function's return type 'void' is not a literal type}} + constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} + constexpr void VoidReturn() const { return; } +#ifndef CXX1Y + // expected-error@-2 {{constexpr function's return type 'void' is not a literal type}} +#endif constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}} - typedef NonLiteral F(); + typedef NonLiteral F() const; constexpr F NonLiteralReturn2; // ok until definition // - each of its parameter types shall be a literal type; - constexpr int NonLiteralParam(NonLiteral) { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} - typedef int G(NonLiteral); + constexpr int NonLiteralParam(NonLiteral) const { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} + typedef int G(NonLiteral) const; constexpr G NonLiteralParam2; // ok until definition // - its function-body shall be = delete, = default, - constexpr int Deleted() = delete; - // It's not possible for the function-body to legally be "= default" here. + constexpr int Deleted() const = delete; + // It's not possible for the function-body to legally be "= default" here + // (that is, for a non-constructor function) in C++11. // Other than constructors, only the copy- and move-assignment operators and // destructor can be defaulted. Destructors can't be constexpr since they // don't have a literal return type. Defaulted assignment operators can't be // constexpr since they can't be const. - constexpr T &operator=(const T&) = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} + constexpr T &operator=(const T&) = default; +#ifndef CXX1Y + // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} + // expected-warning@-3 {{C++1y}} +#endif }; struct U { - constexpr U SelfReturn(); - constexpr int SelfParam(U); + constexpr U SelfReturn() const; + constexpr int SelfParam(U) const; }; struct V : virtual U { // expected-note {{here}} - constexpr int F() { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}} + constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}} }; -// or a compound-statememt that contains only -constexpr int AllowedStmts() { +// or a compound-statememt that contains only [CXX11] +constexpr int AllowedStmtsCXX11() { // - null statements ; @@ -91,34 +100,118 @@ constexpr int AllowedStmts() { // - and exactly one return statement return sizeof(K) + sizeof(C) + sizeof(K); } + +// or a compound-statement that does not contain [CXX1Y] +constexpr int DisallowedStmtsCXX1Y_1() { + // - an asm-definition + asm("int3"); // expected-error {{statement not allowed in constexpr function}} + return 0; +} +constexpr int DisallowedStmtsCXX1Y_2() { + // - a goto statement + goto x; // expected-error {{statement not allowed in constexpr function}} +x: + return 0; +} +constexpr int DisallowedStmtsCXX1Y_3() { + // - a try-block, + try {} catch (...) {} // expected-error {{statement not allowed in constexpr function}} + return 0; +} +constexpr int DisallowedStmtsCXX1Y_4() { + // - a definition of a variable of non-literal type + NonLiteral nl; // expected-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function}} + return 0; +} +constexpr int DisallowedStmtsCXX1Y_5() { + // - a definition of a variable of static storage duration + static constexpr int n = 123; // expected-error {{static variable not permitted in a constexpr function}} + return n; +} +constexpr int DisallowedStmtsCXX1Y_6() { + // - a definition of a variable of thread storage duration + thread_local constexpr int n = 123; // expected-error {{thread_local variable not permitted in a constexpr function}} + return n; +} +constexpr int DisallowedStmtsCXX1Y_7() { + // - a definition of a variable for which no initialization is performed + int n; // expected-error {{variables defined in a constexpr function must be initialized}} + return 0; +} + constexpr int ForStmt() { - for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr function}} + for (int n = 0; n < 10; ++n) +#ifndef CXX1Y + // expected-error@-2 {{statement not allowed in constexpr function}} +#endif return 0; } constexpr int VarDecl() { - constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr function}} + int a = 0; +#ifndef CXX1Y + // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} +#endif + return 0; +} +constexpr int ConstexprVarDecl() { + constexpr int a = 0; +#ifndef CXX1Y + // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} +#endif return 0; } +constexpr int VarWithCtorDecl() { + Literal a; +#ifndef CXX1Y + // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} +#endif + return 0; +} +NonLiteral nl; +constexpr NonLiteral &ExternNonLiteralVarDecl() { + extern NonLiteral nl; +#ifndef CXX1Y + // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} +#endif + return nl; +} +static_assert(&ExternNonLiteralVarDecl() == &nl, ""); constexpr int FuncDecl() { - constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr function}} + constexpr int ForwardDecl(int); +#ifndef CXX1Y + // expected-error@-2 {{use of this statement in a constexpr function is a C++1y extension}} +#endif return ForwardDecl(42); } constexpr int ClassDecl1() { - typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr function}} + typedef struct { } S1; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}} +#endif return 0; } constexpr int ClassDecl2() { - using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr function}} + using S2 = struct { }; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}} +#endif return 0; } constexpr int ClassDecl3() { - struct S3 { }; // expected-error {{types cannot be defined in a constexpr function}} + struct S3 { }; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}} +#endif return 0; } constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}} constexpr int MultiReturn() { - return 0; // expected-note {{return statement}} - return 0; // expected-error {{multiple return statements in constexpr function}} + return 0; + return 0; +#ifndef CXX1Y + // expected-error@-2 {{multiple return statements in constexpr function}} + // expected-note@-4 {{return statement}} +#endif } // - every constructor call and implicit conversion used in initializing the @@ -137,3 +230,60 @@ namespace DR1364 { return kGlobal; // expected-note {{read of non-const}} } } + +namespace rdar13584715 { + typedef __PTRDIFF_TYPE__ ptrdiff_t; + + template<typename T> struct X { + static T value() {}; + }; + + void foo(ptrdiff_t id) { + switch (id) { + case reinterpret_cast<ptrdiff_t>(&X<long>::value): // expected-error{{case value is not a constant expression}} \ + // expected-note{{reinterpret_cast is not allowed in a constant expression}} + break; + } + } +} + +namespace std_example { + constexpr int square(int x) { + return x * x; + } + constexpr long long_max() { + return 2147483647; + } + constexpr int abs(int x) { + if (x < 0) +#ifndef CXX1Y + // expected-error@-2 {{C++1y}} +#endif + x = -x; + return x; + } + constexpr int first(int n) { + static int value = n; // expected-error {{static variable not permitted}} + return value; + } + constexpr int uninit() { + int a; // expected-error {{must be initialized}} + return a; + } + constexpr int prev(int x) { + return --x; + } +#ifndef CXX1Y + // expected-error@-4 {{never produces a constant expression}} + // expected-note@-4 {{subexpression}} +#endif + constexpr int g(int x, int n) { + int r = 1; + while (--n > 0) r *= x; + return r; + } +#ifndef CXX1Y + // expected-error@-5 {{C++1y}} + // expected-error@-5 {{statement not allowed}} +#endif +} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp index ad156c8..8a4fa42 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions %s +// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions -Werror=c++1y-extensions %s +// RUN: %clang_cc1 -verify -std=c++1y -fcxx-exceptions -DCXX1Y %s namespace N { typedef char C; @@ -82,26 +83,47 @@ struct V { } constexpr V(int(&)[1]) { - for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr constructor}} + for (int n = 0; n < 10; ++n) /**/; +#ifndef CXX1Y + // expected-error@-3 {{statement not allowed in constexpr constructor}} +#endif } constexpr V(int(&)[2]) { - constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr constructor}} + constexpr int a = 0; +#ifndef CXX1Y + // expected-error@-2 {{variable declaration in a constexpr constructor is a C++1y extension}} +#endif } constexpr V(int(&)[3]) { - constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr constructor}} + constexpr int ForwardDecl(int); +#ifndef CXX1Y + // expected-error@-2 {{use of this statement in a constexpr constructor is a C++1y extension}} +#endif } constexpr V(int(&)[4]) { - typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr constructor}} + typedef struct { } S1; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr constructor is a C++1y extension}} +#endif } constexpr V(int(&)[5]) { - using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr constructor}} + using S2 = struct { }; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr constructor is a C++1y extension}} +#endif } constexpr V(int(&)[6]) { - struct S3 { }; // expected-error {{types cannot be defined in a constexpr constructor}} + struct S3 { }; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr constructor is a C++1y extension}} +#endif } constexpr V(int(&)[7]) { - return; // expected-error {{statement not allowed in constexpr constructor}} + return; +#ifndef CXX1Y + // expected-error@-2 {{use of this statement in a constexpr constructor is a C++1y extension}} +#endif } }; diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp index bca73ee..5e40f69 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp @@ -102,7 +102,7 @@ X x = cmin(X(), X()); // ok, not constexpr template<typename T> struct Y { constexpr Y() {} - constexpr int get() { return T(); } + constexpr int get() { return T(); } // expected-warning {{C++1y}} }; struct Z { operator int(); }; diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp index 1a6dc9e..bb7f7ac 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp @@ -24,7 +24,7 @@ struct S { struct T {}; template<typename T> struct ImplicitVirtualFromDependentBase : T { - constexpr int ImplicitlyVirtual() { return 0; } + constexpr int ImplicitlyVirtual() const { return 0; } }; constexpr int a = ImplicitVirtualFromDependentBase<S>().ImplicitlyVirtual(); // expected-error {{constant expression}} expected-note {{cannot evaluate virtual function call}} @@ -32,7 +32,7 @@ constexpr int b = ImplicitVirtualFromDependentBase<T>().ImplicitlyVirtual(); // constexpr int c = ImplicitVirtualFromDependentBase<S>().ImplicitVirtualFromDependentBase<S>::ImplicitlyVirtual(); template<typename R> struct ConstexprMember { - constexpr R F() { return 0; } + constexpr R F() const { return 0; } }; constexpr int d = ConstexprMember<int>().F(); // ok constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp index 344f8ce..40aa600 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp @@ -3,13 +3,13 @@ using size_t = decltype(sizeof(int)); struct S { - constexpr int f(); + constexpr int f(); // expected-warning {{C++1y}} constexpr int g() const; - constexpr int h(); + constexpr int h(); // expected-warning {{C++1y}} int h(); static constexpr int Sf(); /*static*/ constexpr void *operator new(size_t) noexcept; - template<typename T> constexpr T tm(); + template<typename T> constexpr T tm(); // expected-warning {{C++1y}} template<typename T> static constexpr T ts(); }; @@ -26,12 +26,12 @@ void f(const S &s) { } constexpr int S::f() const { return 0; } -constexpr int S::g() { return 1; } -constexpr int S::h() { return 0; } +constexpr int S::g() { return 1; } // expected-warning {{C++1y}} +constexpr int S::h() { return 0; } // expected-warning {{C++1y}} int S::h() { return 0; } constexpr int S::Sf() { return 2; } constexpr void *S::operator new(size_t) noexcept { return 0; } -template<typename T> constexpr T S::tm() { return T(); } +template<typename T> constexpr T S::tm() { return T(); } // expected-warning {{C++1y}} template<typename T> constexpr T S::ts() { return T(); } namespace std_example { @@ -39,7 +39,7 @@ namespace std_example { class debug_flag { // expected-note {{not an aggregate and has no constexpr constructors}} public: explicit debug_flag(bool); - constexpr bool is_on(); // expected-error {{non-literal type 'std_example::debug_flag' cannot have constexpr members}} + constexpr bool is_on() const; // expected-error {{non-literal type 'std_example::debug_flag' cannot have constexpr members}} private: bool flag; }; diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp index a385aa9..83b12d4 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp @@ -7,7 +7,7 @@ struct S { // Note, this is not permitted: conversion-declarator cannot have a trailing return type. // FIXME: don't issue the second diagnostic for this. - operator auto(*)()->int(); // expected-error{{'auto' not allowed here}} expected-error {{C++ requires a type specifier}} + operator auto(*)()->int(); // expected-error{{'auto' not allowed in conversion function type}} expected-error {{C++ requires a type specifier}} }; typedef auto Fun(int a) -> decltype(a + a); diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp new file mode 100644 index 0000000..39c547b --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-c++1y-extensions + +// FIXME: This is in p11 (?) in C++1y. +void f() { + decltype(auto) a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}} + if (decltype(auto) b = b) {} // expected-error {{variable 'b' declared with 'auto' type cannot appear in its own initializer}} + decltype(auto) c = ({ decltype(auto) d = c; 0; }); // expected-error {{variable 'c' declared with 'auto' type cannot appear in its own initializer}} +} + +void g() { + decltype(auto) a; // expected-error{{declaration of variable 'a' with type 'decltype(auto)' requires an initializer}} + + decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with type 'decltype(auto) *' requires an initializer}} + + if (decltype(auto) b) {} // expected-error {{must have an initializer}} + for (;decltype(auto) b;) {} // expected-error {{must have an initializer}} + while (decltype(auto) b) {} // expected-error {{must have an initializer}} + if (decltype(auto) b = true) { (void)b; } +} + +decltype(auto) n(1,2,3); // expected-error{{initializer for variable 'n' with type 'decltype(auto)' contains multiple expressions}} + +namespace N +{ + // All of these are references, because a string literal is an lvalue. + decltype(auto) a = "const char (&)[19]", b = a, c = (a); +} + +void h() { + decltype(auto) b = 42ULL; + + for (decltype(auto) c = 0; c < b; ++c) { + } +} + +template<typename T, typename U> struct same; +template<typename T> struct same<T, T> {}; + +void i() { + decltype(auto) x = 5; + decltype(auto) int r; // expected-error {{cannot combine with previous 'decltype(auto)' declaration specifier}} expected-error {{requires an initializer}} +} + +namespace p3_example { + template<typename T, typename U> struct is_same_impl { + static const bool value = false; + }; + template<typename T> struct is_same_impl<T, T> { + static const bool value = true; + }; + template<typename T, typename U> constexpr bool is_same() { + return is_same_impl<T,U>::value; + } + + auto x = 5; + const auto *v = &x, u = 6; + static auto y = 0.0; + auto int r; // expected-warning {{storage class}} expected-error {{file-scope}} + + static_assert(is_same<decltype(x), int>(), ""); + static_assert(is_same<decltype(v), const int*>(), ""); + static_assert(is_same<decltype(u), const int>(), ""); + static_assert(is_same<decltype(y), double>(), ""); + +#ifdef CXX1Y + auto f() -> int; + auto g() { return 0.0; } + auto h(); + + static_assert(is_same<decltype(f), int()>(), ""); + static_assert(is_same<decltype(g), double()>(), ""); +#endif +} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp index 7499829..0cdf3c6 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp @@ -11,7 +11,7 @@ struct S { friend auto; // expected-error{{'auto' not allowed in non-static struct member}} - operator auto(); // expected-error{{'auto' not allowed here}} + operator auto(); // expected-error{{'auto' not allowed in conversion function type}} }; // PR 9278: auto is not allowed in typedefs, except with a trailing return type. diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6-1y.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6-1y.cpp new file mode 100644 index 0000000..66085ed --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6-1y.cpp @@ -0,0 +1,97 @@ +// RUN: %clang_cc1 -verify -std=c++1y %s + +namespace std { + template<typename T> struct initializer_list { + const T *p; + unsigned long n; + initializer_list(const T *p, unsigned long n); + }; +} + +// FIXME: This may not be p6 in C++1y; N3638 isn't very clear whether paragraphs +// were added. It might be p8? + +int i; +int &&f(); + +using Int = int; +using IntLRef = int&; +using IntRRef = int&&; +using InitListInt = std::initializer_list<int>; +using IntPtr = int*; + +auto x3a = i; +decltype(auto) x3d = i; +using Int = decltype(x3a); +using Int = decltype(x3d); + +auto x4a = (i); +decltype(auto) x4d = (i); +using Int = decltype(x4a); +using IntLRef = decltype(x4d); + +auto x5a = f(); +decltype(auto) x5d = f(); +using Int = decltype(x5a); +using IntRRef = decltype(x5d); + +auto x6a = { 1, 2 }; +decltype(auto) x6d = { 1, 2 }; // expected-error {{cannot deduce 'decltype(auto)' from initializer list}} +using InitListInt = decltype(x6a); + +auto *x7a = &i; +decltype(auto) *x7d = &i; // expected-error {{cannot form pointer to 'decltype(auto)'}} +using IntPtr = decltype(x7a); + +struct S {}; + +decltype(auto) f1(); +decltype(auto) (*f2)(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{requires an initializer}} +decltype(auto) *f3(); // expected-error {{cannot form pointer to 'decltype(auto)'}} +const decltype(auto) f4(); // expected-error {{'decltype(auto)' cannot be combined with other type specifiers}} +typedef decltype(auto) f5(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} +decltype(auto) ((((((f6))))())); // ok +decltype(auto) f7()(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{function cannot return function type}} +decltype(auto) (S::*f8)(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{requires an initializer}} +decltype(auto) &f9(); // expected-error {{cannot form reference to 'decltype(auto)'}} +decltype(auto) (&f10())[10]; // expected-error {{cannot form array of 'decltype(auto)'}} + +decltype(auto) ((((((v1)))))) = 0; // ok +decltype(auto) v2[1] = { 0 }; // expected-error {{cannot form array of 'decltype(auto)'}} +decltype(auto) &v3 = { 0 }; // expected-error {{cannot form reference to 'decltype(auto)'}} +decltype(auto) *v4 = { 0 }; // expected-error {{cannot form pointer to 'decltype(auto)'}} + +auto multi1a = 0, &multi1b = multi1a; +auto multi1c = multi1a, multi1d = multi1b; +decltype(auto) multi1e = multi1a, multi1f = multi1b; // expected-error {{'decltype(auto)' deduced as 'int' in declaration of 'multi1e' and deduced as 'int &' in declaration of 'multi1f'}} + +auto f1a() { return 0; } +decltype(auto) f1d() { return 0; } +using Int = decltype(f1a()); +using Int = decltype(f1d()); + +auto f2a(int n) { return n; } +decltype(auto) f2d(int n) { return n; } +using Int = decltype(f2a(0)); +using Int = decltype(f2d(0)); + +auto f3a(int n) { return (n); } +decltype(auto) f3d(int n) { return (n); } // expected-warning {{reference to stack memory}} +using Int = decltype(f3a(0)); +using IntLRef = decltype(f3d(0)); + +auto f4a(int n) { return f(); } +decltype(auto) f4d(int n) { return f(); } +using Int = decltype(f4a(0)); +using IntRRef = decltype(f4d(0)); + +auto f5aa(int n) { auto x = f(); return x; } +auto f5ad(int n) { decltype(auto) x = f(); return x; } +decltype(auto) f5da(int n) { auto x = f(); return x; } +decltype(auto) f5dd(int n) { decltype(auto) x = f(); return x; } // expected-error {{rvalue reference to type 'int' cannot bind to lvalue}} +using Int = decltype(f5aa(0)); +using Int = decltype(f5ad(0)); +using Int = decltype(f5da(0)); + +auto init_list_1() { return { 1, 2, 3 }; } // expected-error {{cannot deduce return type from initializer list}} +decltype(auto) init_list_2() { return { 1, 2, 3 }; } // expected-error {{cannot deduce return type from initializer list}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp index 093bc14..1ed93b1 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp @@ -41,7 +41,9 @@ decltype( PD(), // expected-error {{private destructor}} PD()) pd1; // expected-error {{private destructor}} decltype(DD(), // expected-error {{deleted function}} - DD()) dd1; // expected-error {{deleted function}} + DD()) dd1; +decltype(A(), + DD()) dd2; // expected-error {{deleted function}} decltype( PD(), // expected-error {{temporary of type 'PD' has private destructor}} 0) pd2; @@ -76,7 +78,7 @@ namespace libcxx_example { template<typename T> struct swappable { typedef decltype(swap(declval<T&>(), declval<T&>())) type; static const bool value = !is_same<type, nat>::value; - constexpr operator bool() { return value; } + constexpr operator bool() const { return value; } }; static_assert(swappable<int>(), ""); diff --git a/test/CXX/dcl.dcl/p4-0x.cpp b/test/CXX/dcl.dcl/p4-0x.cpp index 31d4912..1f4cdda 100644 --- a/test/CXX/dcl.dcl/p4-0x.cpp +++ b/test/CXX/dcl.dcl/p4-0x.cpp @@ -2,15 +2,15 @@ struct S { constexpr S(bool b) : b(b) {} - constexpr explicit operator bool() { return b; } + constexpr explicit operator bool() const { return b; } bool b; }; struct T { - constexpr operator int() { return 1; } + constexpr operator int() const { return 1; } }; struct U { - constexpr operator int() { return 1; } // expected-note {{candidate}} - constexpr operator long() { return 0; } // expected-note {{candidate}} + constexpr operator int() const { return 1; } // expected-note {{candidate}} + constexpr operator long() const { return 0; } // expected-note {{candidate}} }; static_assert(S(true), ""); diff --git a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp index 783aba1..b9a1bc5 100644 --- a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp +++ b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp @@ -6,8 +6,8 @@ struct S1 { constexpr S1() = default; // expected-error {{defaulted definition of default constructor is not constexpr}} constexpr S1(const S1&) = default; constexpr S1(S1&&) = default; - constexpr S1 &operator=(const S1&) = default; // expected-error {{explicitly-defaulted copy assignment operator may not have}} - constexpr S1 &operator=(S1&&) = default; // expected-error {{explicitly-defaulted move assignment operator may not have}} + constexpr S1 &operator=(const S1&) const = default; // expected-error {{explicitly-defaulted copy assignment operator may not have}} + constexpr S1 &operator=(S1&&) const = default; // expected-error {{explicitly-defaulted move assignment operator may not have}} constexpr ~S1() = default; // expected-error {{destructor cannot be marked constexpr}} int n; }; diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp index fef3692..8767678 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1y %s -DCXX1Y // An aggregate is an array or a class... struct Aggr { @@ -18,9 +19,6 @@ struct NonAggr1a { // expected-note 2 {{candidate constructor}} NonAggr1a(int, int); // expected-note {{candidate constructor}} int k; }; -// In C++0x, 'user-provided' is only defined for special member functions, so -// this type is considered to be an aggregate. This is considered to be -// a language defect. NonAggr1a na1a = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr1a'}} struct NonAggr1b { @@ -30,10 +28,15 @@ struct NonAggr1b { NonAggr1b na1b = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr1b'}} // no brace-or-equal-initializers for non-static data members, ... -struct NonAggr2 { // expected-note 3 {{candidate constructor}} +// Note, this bullet was removed in C++1y. +struct NonAggr2 { int m = { 123 }; }; -NonAggr2 na2 = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr2'}} +NonAggr2 na2 = { 42 }; +#ifndef CXX1Y +// expected-error@-2 {{no matching constructor for initialization of 'NonAggr2'}} +// expected-note@-6 3 {{candidate constructor}} +#endif // no private... struct NonAggr3 { // expected-note 3 {{candidate constructor}} diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p7.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p7.cpp new file mode 100644 index 0000000..d1fbe76 --- /dev/null +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p7.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++1y %s -verify + +// expected-no-diagnostics + +struct S { int a; const char *b; int c; int d = b[a]; }; +constexpr S ss = { 1, "asdf" }; + +static_assert(ss.a == 1, ""); +static_assert(ss.b[2] == 'd', ""); +static_assert(ss.c == 0, ""); +static_assert(ss.d == 's', ""); + +struct X { int i, j, k = 42; }; +constexpr X a[] = { 1, 2, 3, 4, 5, 6 }; +constexpr X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } }; + +constexpr bool operator==(X a, X b) { + return a.i == b.i && a.j == b.j && a.k == b.k; +} + +static_assert(sizeof(a) == sizeof(b), ""); +static_assert(a[0] == b[0], ""); +static_assert(a[1] == b[1], ""); diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp index 812d0de..fdfa678 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp @@ -200,3 +200,37 @@ namespace rdar13278115 { X &&f1(Y &y) { return y; } // expected-error{{rvalue reference to type 'rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::Y'}} const X &&f2(Y &y) { return y; } // expected-error{{rvalue reference to type 'const rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::Y'}} } + +namespace bitfields { + struct IntBitfield { + int i : 17; // expected-note 3 {{bit-field is declared here}} + }; + + // A simplified version of std::move. + template <typename T> + T &&move(T &obj) { + return static_cast<T &&>(obj); + } + + void test() { + int & ir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}} + int & ir2 = (xvalue<IntBitfield>().i); // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}} + int && ir3 = (xvalue<IntBitfield>().i); // no-warning + int && ir4 = move(lvalue<IntBitfield>()).i; // no-warning + + volatile int & vir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}} + volatile int & vir2 = (xvalue<IntBitfield>().i); // expected-error{{volatile lvalue reference to type 'volatile int' cannot bind to a temporary of type 'int'}} + volatile int && vir3 = (xvalue<IntBitfield>().i); // no-warning + volatile int && vir4 = move(lvalue<IntBitfield>()).i; // no-warning + + const int & cir1 = (lvalue<IntBitfield>().i); // no-warning + const int & cir2 = (xvalue<IntBitfield>().i); // no-warning + const int && cir3 = (xvalue<IntBitfield>().i); // no-warning + const int && cir4 = move(lvalue<IntBitfield>()).i; // no-warning + + const volatile int & cvir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}} + const volatile int & cvir2 = (xvalue<IntBitfield>().i); // expected-error{{volatile lvalue reference to type 'const volatile int' cannot bind to a temporary of type 'int'}} + const volatile int && cvir3 = (xvalue<IntBitfield>().i); // no-warning + const volatile int && cvir4 = move(lvalue<IntBitfield>()).i; // no-warning + } +} diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp index 51d61a5..263f661 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp @@ -38,3 +38,26 @@ namespace PR6066 { return 0; } } + +namespace test3 { + struct A { + unsigned bitX : 4; // expected-note 4 {{bit-field is declared here}} + unsigned bitY : 4; // expected-note {{bit-field is declared here}} + unsigned var; + + void foo(); + }; + + void test(A *a) { + unsigned &t0 = a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}} + unsigned &t1 = (unsigned&) a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}} + unsigned &t2 = const_cast<unsigned&>(a->bitX); // expected-error {{const_cast from bit-field lvalue to reference type 'unsigned int &'}} + unsigned &t3 = (a->foo(), a->bitX); // expected-error {{non-const reference cannot bind to bit-field 'bitX'}} + unsigned &t4 = (a->var ? a->bitX : a->bitY); // expected-error {{non-const reference cannot bind to bit-field}} + unsigned &t5 = (a->var ? a->bitX : a->bitX); // expected-error {{non-const reference cannot bind to bit-field}} + unsigned &t6 = (a->var ? a->bitX : a->var); // expected-error {{non-const reference cannot bind to bit-field}} + unsigned &t7 = (a->var ? a->var : a->bitY); // expected-error {{non-const reference cannot bind to bit-field}} + unsigned &t8 = (a->bitX = 3); // expected-error {{non-const reference cannot bind to bit-field 'bitX'}} + unsigned &t9 = (a->bitY += 3); // expected-error {{non-const reference cannot bind to bit-field 'bitY'}} + } +} diff --git a/test/CXX/except/except.spec/p1.cpp b/test/CXX/except/except.spec/p1.cpp index e184ec4..a32f37d 100644 --- a/test/CXX/except/except.spec/p1.cpp +++ b/test/CXX/except/except.spec/p1.cpp @@ -55,7 +55,7 @@ namespace noex { struct A {}; void g1() noexcept(A()); // expected-error {{not contextually convertible}} - void g2(bool b) noexcept(b); // expected-error {{argument to noexcept specifier must be a constant expression}} + void g2(bool b) noexcept(b); // expected-error {{argument to noexcept specifier must be a constant expression}} expected-note {{read of non-const variable 'b'}} expected-note {{here}} } diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp index 99ed2fd..dda69e9 100644 --- a/test/CXX/except/except.spec/p14.cpp +++ b/test/CXX/except/except.spec/p14.cpp @@ -112,3 +112,26 @@ namespace rdar13017229 { Typo foo(); // expected-error{{unknown type name 'Typo'}} }; } + +namespace InhCtor { + template<int> struct X {}; + struct Base { + Base(X<0>) noexcept(true); + Base(X<1>) noexcept(false); + Base(X<2>) throw(X<2>); + template<typename T> Base(T) throw(T); + }; + template<typename T> struct Throw { + Throw() throw(T); + }; + struct Derived : Base, Throw<X<3>> { + using Base::Base; + Throw<X<4>> x; + }; + struct Test { + friend Derived::Derived(X<0>) throw(X<3>, X<4>); + friend Derived::Derived(X<1>) noexcept(false); + friend Derived::Derived(X<2>) throw(X<2>, X<3>, X<4>); + }; + static_assert(!noexcept(Derived{X<5>{}}), ""); +} diff --git a/test/CXX/expr/expr.ass/p9-cxx11.cpp b/test/CXX/expr/expr.ass/p9-cxx11.cpp index 206c82c..ecc6d2c 100644 --- a/test/CXX/expr/expr.ass/p9-cxx11.cpp +++ b/test/CXX/expr/expr.ass/p9-cxx11.cpp @@ -24,8 +24,8 @@ struct S { int a, b; }; struct T { - constexpr int operator=(S s) { return s.a; } - constexpr int operator+=(S s) { return s.b; } + constexpr int operator=(S s) const { return s.a; } + constexpr int operator+=(S s) const { return s.b; } }; static_assert((T() = {4, 9}) == 4, ""); static_assert((T() += {4, 9}) == 9, ""); diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp index 065a12b..634dee3 100644 --- a/test/CXX/expr/expr.const/p2-0x.cpp +++ b/test/CXX/expr/expr.const/p2-0x.cpp @@ -118,7 +118,7 @@ namespace IncompleteClassTypeAddr { constexpr S (*p2)[] = &sArr; // ok struct S { - constexpr S *operator&() { return nullptr; } + constexpr S *operator&() const { return nullptr; } }; constexpr S *q = &s; // ok static_assert(!q, ""); @@ -205,7 +205,7 @@ namespace UndefinedBehavior { constexpr const int &np = (*(int(*)[4])nullptr)[2]; // expected-error {{constant expression}} expected-note {{cannot access array element of null pointer}} struct C { - constexpr int f() { return 0; } + constexpr int f() const { return 0; } } constexpr c = C(); constexpr int k1 = c.f(); // ok constexpr int k2 = ((C*)nullptr)->f(); // expected-error {{constant expression}} expected-note {{cannot call member function on null pointer}} @@ -481,14 +481,14 @@ namespace UnspecifiedRelations { public: constexpr A() : a(0), b(0) {} int a; - constexpr bool cmp() { return &a < &b; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'A' with differing access specifiers (public vs private) has unspecified value}} + constexpr bool cmp() const { return &a < &b; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'A' with differing access specifiers (public vs private) has unspecified value}} private: int b; }; class B { public: A a; - constexpr bool cmp() { return &a.a < &b.a; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'B' with differing access specifiers (public vs protected) has unspecified value}} + constexpr bool cmp() const { return &a.a < &b.a; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'B' with differing access specifiers (public vs protected) has unspecified value}} protected: A b; }; diff --git a/test/CXX/expr/expr.const/p3-0x.cpp b/test/CXX/expr/expr.const/p3-0x.cpp index 6ddd11b..047e238 100644 --- a/test/CXX/expr/expr.const/p3-0x.cpp +++ b/test/CXX/expr/expr.const/p3-0x.cpp @@ -101,7 +101,7 @@ int n = Val<bool, &S::operator int>::value; // expected-error {{conversion from namespace NonConstLValue { struct S { - constexpr operator int() { return 10; } + constexpr operator int() const { return 10; } }; S s; // not constexpr // Under the FDIS, this is not a converted constant expression. diff --git a/test/CXX/expr/expr.const/p5-0x.cpp b/test/CXX/expr/expr.const/p5-0x.cpp index bdb2b23..0a4ac22 100644 --- a/test/CXX/expr/expr.const/p5-0x.cpp +++ b/test/CXX/expr/expr.const/p5-0x.cpp @@ -7,8 +7,8 @@ namespace std_example { struct A { constexpr A(int i) : val(i) { } - constexpr operator int() { return val; } - constexpr operator long() { return 43; } + constexpr operator int() const { return val; } + constexpr operator long() const { return 43; } private: int val; }; @@ -21,17 +21,17 @@ int ary[a]; // expected-error {{size of array has non-integer type 'const std_ex struct OK { constexpr OK() {} - constexpr operator int() { return 8; } + constexpr operator int() const { return 8; } } constexpr ok; extern struct Incomplete incomplete; // expected-note 4{{forward decl}} struct Explicit { constexpr Explicit() {} - constexpr explicit operator int() { return 4; } // expected-note 4{{here}} + constexpr explicit operator int() const { return 4; } // expected-note 4{{here}} } constexpr expl; struct Ambiguous { constexpr Ambiguous() {} - constexpr operator int() { return 2; } // expected-note 4{{here}} - constexpr operator long() { return 1; } // expected-note 4{{here}} + constexpr operator int() const { return 2; } // expected-note 4{{here}} + constexpr operator long() const { return 1; } // expected-note 4{{here}} } constexpr ambig; constexpr int test_ok = ok; // ok diff --git a/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp b/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp index be89876..76ea96f 100644 --- a/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp +++ b/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// expected-no-diagnostics // The result of the expression const_cast<T>(v) is of type T. If T is // an lvalue reference to object type, the result is an lvalue; if T @@ -16,3 +15,19 @@ void test_classification(const int *ptr) { int *ptr1 = const_cast<int *&&>(xvalue<const int*>()); int *ptr2 = const_cast<int *&&>(prvalue<const int*>()); } + +struct A { + volatile unsigned ubf : 4; + volatile unsigned uv; + volatile int sv; + void foo(); + bool pred(); +}; + +void test(A &a) { + unsigned &t0 = const_cast<unsigned&>(a.ubf); // expected-error {{const_cast from bit-field lvalue to reference type}} + unsigned &t1 = const_cast<unsigned&>(a.foo(), a.ubf); // expected-error {{const_cast from bit-field lvalue to reference type}} + unsigned &t2 = const_cast<unsigned&>(a.pred() ? a.ubf : a.ubf); // expected-error {{const_cast from bit-field lvalue to reference type}} + unsigned &t3 = const_cast<unsigned&>(a.pred() ? a.ubf : a.uv); // expected-error {{const_cast from bit-field lvalue to reference type}} + unsigned &t4 = const_cast<unsigned&>(a.pred() ? a.ubf : a.sv); // expected-error {{const_cast from rvalue to reference type}} +} diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp index 5dac886..38d5d0a 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -Wno-lambda-extensions -verify +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify void defargs() { auto l1 = [](int i, int j = 17, int k = 18) { return i + j + k; }; diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp index 9dffc1f..dc2c209 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp @@ -39,12 +39,10 @@ void test_quals() { bogus_override_if_virtual<decltype(l)> bogus; } -// Default arguments (8.3.6) shall not be specified in the -// parameter-declaration-clause of a lambda- declarator. -// Note: Removed by core issue 974. +// Core issue 974: default arguments (8.3.6) may be specified in the +// parameter-declaration-clause of a lambda-declarator. int test_default_args() { - return [](int i = 5, // expected-warning{{C++11 forbids default arguments for lambda expressions}} - int j = 17) { return i+j;}(5, 6); + return [](int i = 5, int j = 17) { return i+j;}(5, 6); } // Any exception-specification specified on a lambda-expression diff --git a/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp b/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp new file mode 100644 index 0000000..6a59e3d --- /dev/null +++ b/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A { + unsigned bitX : 4; + unsigned bitY : 4; + unsigned var; + + void foo(); +}; + +void test(A *a) { + int x; + x = sizeof(a->bitX); // expected-error {{invalid application of 'sizeof' to bit-field}} + x = sizeof((unsigned) a->bitX); + x = sizeof(a->foo(), a->bitX); // expected-error {{invalid application of 'sizeof' to bit-field}} + x = sizeof(a->var ? a->bitX : a->bitY); // expected-error {{invalid application of 'sizeof' to bit-field}} + x = sizeof(a->var ? a->bitX : a->bitX); // expected-error {{invalid application of 'sizeof' to bit-field}} + x = sizeof(a->bitX = 3); // expected-error {{invalid application of 'sizeof' to bit-field}} + x = sizeof(a->bitY += 3); // expected-error {{invalid application of 'sizeof' to bit-field}} +} diff --git a/test/CXX/over/over.oper/over.literal/p2.cpp b/test/CXX/over/over.oper/over.literal/p2.cpp index c012104..00466fb 100644 --- a/test/CXX/over/over.oper/over.literal/p2.cpp +++ b/test/CXX/over/over.oper/over.literal/p2.cpp @@ -33,3 +33,12 @@ template<char...> void operator "" _h() {} template<> void operator "" _h<'a', 'b', 'c'>() {} template void operator "" _h<'a', 'b', 'c', 'd'>(); + +namespace rdar13605348 { + +class C { + double operator"" _x(long double value) { return double(value); } // expected-error{{literal operator 'operator "" _x' must be in a namespace or global scope}} + double value() { return 3.2_x; } // expected-error{{no matching literal operator for call to}} +}; + +} diff --git a/test/CXX/special/class.inhctor/elsewhere.cpp b/test/CXX/special/class.inhctor/elsewhere.cpp index 184e902..b986f65 100644 --- a/test/CXX/special/class.inhctor/elsewhere.cpp +++ b/test/CXX/special/class.inhctor/elsewhere.cpp @@ -55,3 +55,10 @@ template<typename T> struct F : D<bool> { using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}} }; F<bool> fb; // expected-note {{here}} + +template<typename T> +struct G : T { + using T::T; + G(int &) : G(0) {} +}; +G<B1> g(123); diff --git a/test/CXX/special/class.inhctor/p1.cpp b/test/CXX/special/class.inhctor/p1.cpp index 57e9150..8721dec 100644 --- a/test/CXX/special/class.inhctor/p1.cpp +++ b/test/CXX/special/class.inhctor/p1.cpp @@ -2,17 +2,24 @@ // Per a core issue (no number yet), an ellipsis is always dropped. struct A { A(...); // expected-note {{here}} - A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 5{{here}} + A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 9{{here}} A(int = 0, int = 0, ...); // expected-note {{here}} + + template<typename T> A(T, int = 0, ...); // expected-note 5{{here}} + + template<typename T, int N> A(const T (&)[N]); // expected-note 2{{here}} + template<typename T, int N> A(const T (&)[N], int = 0); // expected-note 2{{here}} }; -struct B : A { // expected-note 3{{candidate}} - using A::A; // expected-warning 3{{inheriting constructor does not inherit ellipsis}} expected-note 4{{candidate}} expected-note 2{{deleted}} +struct B : A { // expected-note 6{{candidate}} + using A::A; // expected-warning 4{{inheriting constructor does not inherit ellipsis}} expected-note 16{{candidate}} expected-note 3{{deleted}} }; +struct C {} c; + B b0{}; // expected-error@-1 {{call to implicitly-deleted default constructor}} -// expected-note@9 {{default constructor of 'B' is implicitly deleted because base class 'A' has multiple default constructors}} +// expected-note@-8 {{default constructor of 'B' is implicitly deleted because base class 'A' has multiple default constructors}} B b1{1}; // FIXME: explain why the inheriting constructor was deleted @@ -29,3 +36,29 @@ B b4{1,2,3,4}; B b5{1,2,3,4,5}; // expected-error@-1 {{no matching constructor for initialization of 'B'}} + +B b6{c}; +// ok + +B b7{c,0}; +// ok + +B b8{c,0,1}; +// expected-error@-1 {{no matching constructor}} + +B b9{"foo"}; +// FIXME: explain why the inheriting constructor was deleted +// expected-error@-2 {{call to deleted constructor of 'B'}} + +namespace PR15755 { + struct X { + template<typename...Ts> X(int, Ts...); + }; + struct Y : X { + using X::X; + }; + struct Z : Y { + using Y::Y; + }; + Z z(0); +} diff --git a/test/CXX/special/class.inhctor/p2.cpp b/test/CXX/special/class.inhctor/p2.cpp index e426738..e6abd68 100644 --- a/test/CXX/special/class.inhctor/p2.cpp +++ b/test/CXX/special/class.inhctor/p2.cpp @@ -3,7 +3,7 @@ template<int> struct X {}; // Constructor characteristics are: -// - the template parameter list [FIXME] +// - the template parameter list // - the parameter-type-list // - absence or presence of explicit // - absence or presence of constexpr @@ -85,3 +85,37 @@ struct ConstexprEval3 : ConstexprEval, ConstexprEval2 { constexpr ConstexprEval3 ce{4, "foobar"}; static_assert(ce.k == 'a', ""); static_assert(ce.k2 == 'x', ""); + + +struct TemplateCtors { + constexpr TemplateCtors() {} + template<template<int> class T> TemplateCtors(X<0>, T<0>); + template<int N> TemplateCtors(X<1>, X<N>); + template<typename T> TemplateCtors(X<2>, T); + + template<typename T = int> TemplateCtors(int, int = 0, int = 0); // expected-note {{inherited from here}} +}; + +struct UsingTemplateCtors : TemplateCtors { + using TemplateCtors::TemplateCtors; // expected-note 4{{here}} expected-note {{candidate}} + + constexpr UsingTemplateCtors(X<0>, X<0>) {} + constexpr UsingTemplateCtors(X<1>, X<1>) {} + constexpr UsingTemplateCtors(X<2>, X<2>) {} + + template<int = 0> constexpr UsingTemplateCtors(int) {} // expected-note {{candidate}} + template<typename T = void> constexpr UsingTemplateCtors(int, int) {} + template<typename T, typename U> constexpr UsingTemplateCtors(int, int, int) {} +}; + +template<int> struct Y {}; +constexpr UsingTemplateCtors uct1{ X<0>{}, X<0>{} }; +constexpr UsingTemplateCtors uct2{ X<0>{}, Y<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} +constexpr UsingTemplateCtors uct3{ X<1>{}, X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} +constexpr UsingTemplateCtors uct4{ X<1>{}, X<1>{} }; +constexpr UsingTemplateCtors uct5{ X<2>{}, 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} +constexpr UsingTemplateCtors uct6{ X<2>{}, X<2>{} }; + +constexpr UsingTemplateCtors utc7{ 0 }; // expected-error {{ambiguous}} +constexpr UsingTemplateCtors utc8{ 0, 0 }; // ok +constexpr UsingTemplateCtors utc9{ 0, 0, 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} diff --git a/test/CXX/special/class.inhctor/p3.cpp b/test/CXX/special/class.inhctor/p3.cpp index f71ab16..7aaaa7a 100644 --- a/test/CXX/special/class.inhctor/p3.cpp +++ b/test/CXX/special/class.inhctor/p3.cpp @@ -46,3 +46,13 @@ struct U { friend T3<int>::T3(int); friend T3<int>::T3(int, int); }; + +struct B4 { + template<typename T> explicit B4(T, int = 0); +}; +template<typename T> struct T4 : B4 { + using B4::B4; // expected-note {{here}} + template<typename U> T4(U); +}; +T4<void> t4a = {0}; +T4<void> t4b = {0, 0}; // expected-error {{chosen constructor is explicit}} diff --git a/test/CXX/special/class.inhctor/p4.cpp b/test/CXX/special/class.inhctor/p4.cpp index eea3bf2..512705e 100644 --- a/test/CXX/special/class.inhctor/p4.cpp +++ b/test/CXX/special/class.inhctor/p4.cpp @@ -44,11 +44,13 @@ FA fa2{X<2>{}}; // expected-error {{calling a private constructor}} // It is deleted if the corresponding constructor [...] is deleted. struct G { G(int) = delete; + template<typename T> G(T*) = delete; }; struct H : G { - using G::G; // expected-note {{marked deleted here}} + using G::G; // expected-note 2{{marked deleted here}} }; -H h(5); // expected-error {{call to implicitly-deleted function of 'H'}} +H h1(5); // expected-error {{call to implicitly-deleted function of 'H'}} +H h2("foo"); // expected-error {{call to deleted constructor of 'H'}} // Core defect: It is also deleted if multiple base constructors generate the diff --git a/test/CXX/special/class.inhctor/p7.cpp b/test/CXX/special/class.inhctor/p7.cpp index 9ae160f..a57e855 100644 --- a/test/CXX/special/class.inhctor/p7.cpp +++ b/test/CXX/special/class.inhctor/p7.cpp @@ -27,3 +27,21 @@ template<typename T> struct B4 : B3<T>, B1 { }; B4<char> b4c; B4<int> b4i; // expected-note {{here}} + +struct B5 { + template<typename T> B5(T); // expected-note {{previous constructor}} +}; +struct B6 { + template<typename T> B6(T); // expected-note {{conflicting constructor}} +}; +struct B7 { + template<typename T, int> B7(T); +}; +struct D56 : B5, B6, B7 { + using B5::B5; // expected-note {{inherited here}} + using B6::B6; // expected-error {{already inherited}} +}; +struct D57 : B5, B6, B7 { + using B5::B5; + using B7::B7; // ok, not the same signature +}; diff --git a/test/CXX/special/class.inhctor/p8.cpp b/test/CXX/special/class.inhctor/p8.cpp index e2b07df..0c85738 100644 --- a/test/CXX/special/class.inhctor/p8.cpp +++ b/test/CXX/special/class.inhctor/p8.cpp @@ -19,3 +19,12 @@ constexpr B b0{0}; constexpr B b1{k}; static_assert(a0.rval && !a1.rval && b0.rval && !b1.rval, ""); + +struct C { + template<typename T> constexpr C(T t) : v(t) {} + int v; +}; +struct D : C { + using C::C; +}; +static_assert(D(123).v == 123, ""); diff --git a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp index 3952afd..b159a15 100644 --- a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp +++ b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -242,3 +242,13 @@ void example() { for (int &x : array) x *= 2; } + +namespace rdar13712739 { + template<typename T> + void foo(const T& t) { + auto &x = t.get(); // expected-error{{member reference base type 'const int' is not a structure or union}} + for (auto &blah : x) { } + } + + template void foo(const int&); // expected-note{{in instantiation of function template specialization}} +} diff --git a/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp b/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp index d0f15d4..fda0c5c 100644 --- a/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp +++ b/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp @@ -3,12 +3,12 @@ struct Value { constexpr Value(int n) : n(n) {} - constexpr operator short() { return n; } + constexpr operator short() const { return n; } int n; }; enum E { E0, E1 }; struct Alt { - constexpr operator E() { return E0; } + constexpr operator E() const { return E0; } }; constexpr short s = Alt(); diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp index 59ce8b6..3f65466 100644 --- a/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp +++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp @@ -1,19 +1,23 @@ -// RUN: %clang_cc1 -std=c++11 %s -verify +// RUN: %clang_cc1 -std=c++11 %s -verify -triple x86_64-linux-gnu namespace std { typedef decltype(nullptr) nullptr_t; } -template<int *ip> struct IP { // expected-note 4 {{template parameter is declared here}} +template<int *ip> struct IP { // expected-note 5 {{template parameter is declared here}} IP<ip> *ip2; }; +template<int &ip> struct IR {}; + constexpr std::nullptr_t get_nullptr() { return nullptr; } constexpr std::nullptr_t np = nullptr; std::nullptr_t nonconst_np; // expected-note{{declared here}} +thread_local int tl; // expected-note {{refers here}} + IP<0> ip0; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}} IP<(0)> ip1; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}} IP<nullptr> ip2; @@ -23,6 +27,9 @@ IP<np> ip5; IP<nonconst_np> ip5; // expected-error{{non-type template argument of type 'std::nullptr_t' (aka 'nullptr_t') is not a constant expression}} \ // expected-note{{read of non-constexpr variable 'nonconst_np' is not allowed in a constant expression}} IP<(float*)0> ip6; // expected-error{{null non-type template argument of type 'float *' does not match template parameter of type 'int *'}} +IP<&tl> ip7; // expected-error{{non-type template argument of type 'int *' is not a constant expression}} + +IR<tl> ir1; // expected-error{{non-type template argument refers to thread-local object}} struct X { }; template<int X::*pm> struct PM { // expected-note 2 {{template parameter is declared here}} diff --git a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp index e0ffef5..82114cf 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp @@ -193,18 +193,18 @@ namespace PacksAtDifferentLevels { template<typename...A> struct X6 { template<typename...B> - constexpr auto f1(A ...a) -> decltype(g(A(a + B())...)) { return g(A(a + B())...); } + constexpr auto f1(A ...a) const -> decltype(g(A(a + B())...)) { return g(A(a + B())...); } template<typename...B> - constexpr auto f2(A ...a, B ...b) -> decltype(g((&a)[b] ...)) { return g((&a)[b] ...); } // expected-note {{past-the-end}} + constexpr auto f2(A ...a, B ...b) const -> decltype(g((&a)[b] ...)) { return g((&a)[b] ...); } // expected-note {{past-the-end}} template<typename...B> struct Inner { template<typename...C> - constexpr auto f(A ...a, B ...b, C ...c) -> decltype(g(a+b+c...)) { return g(a+b+c...); } + constexpr auto f(A ...a, B ...b, C ...c) const -> decltype(g(a+b+c...)) { return g(a+b+c...); } }; }; - struct A { constexpr operator int() { return 2; } }; - struct B { constexpr operator int() { return 1; } }; + struct A { constexpr operator int() const { return 2; } }; + struct B { constexpr operator int() const { return 1; } }; static_assert(X6<unsigned char, int>().f1<A, B>(255, 1) == 12, ""); static_assert(X6<int, int>().f2(3, 4, 0, 0) == 34, ""); diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp index e0c7b35..f804d4d 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp @@ -9,7 +9,7 @@ template inline void X<int>::f(); // expected-error{{explicit instantiation cann template<typename T> struct Y { - constexpr int f() { return 0; } + constexpr int f() { return 0; } // expected-warning{{C++1y}} }; template constexpr int Y<int>::f() const; // expected-error{{explicit instantiation cannot be 'constexpr'}} diff --git a/test/CodeGen/2010-02-10-PointerName.c b/test/CodeGen/2010-02-10-PointerName.c index 2837de4..2321c01 100644 --- a/test/CodeGen/2010-02-10-PointerName.c +++ b/test/CodeGen/2010-02-10-PointerName.c @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 %s -emit-llvm -g -o - | grep DW_TAG_pointer_type | grep -v {"char"} +// RUN: %clang_cc1 %s -emit-llvm -g -o - | FileCheck %s +// CHECK: DW_TAG_pointer_type +// CHECK-NOT: {"char"} char i = 1; void foo() { diff --git a/test/CodeGen/arm-asm-diag.c b/test/CodeGen/arm-asm-diag.c new file mode 100644 index 0000000..eea7920 --- /dev/null +++ b/test/CodeGen/arm-asm-diag.c @@ -0,0 +1,23 @@ +// REQUIRES: arm-registered-target +// RUN: %clang_cc1 -triple armv7 %s -S -o /dev/null 2>&1 | FileCheck %s + +// rdar://13446483 +typedef __attribute__((neon_vector_type(2))) long long int64x2_t; +typedef struct int64x2x4_t { + int64x2_t val[4]; +} int64x2x4_t; +int64x2x4_t t1(const long long a[]) { + int64x2x4_t r; + __asm__("vldm %[a], { %q[r0], %q[r1], %q[r2], %q[r3] }" + : [r0] "=r"(r.val[0]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}} + [r1] "=r"(r.val[1]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}} + [r2] "=r"(r.val[2]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}} + [r3] "=r"(r.val[3]) // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}} + : [a] "r"(a)); + return r; +} +// We should see all four errors, rather than report a fatal error after the first. +// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type +// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type +// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type +// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type diff --git a/test/CodeGen/builtins-aarch64.c b/test/CodeGen/builtins-aarch64.c new file mode 100644 index 0000000..8a93cb4 --- /dev/null +++ b/test/CodeGen/builtins-aarch64.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -O3 -emit-llvm -o - %s | FileCheck %s + +void f0(char *a, char *b) { + __clear_cache(a,b); +// CHECK: call {{.*}} @__clear_cache +} diff --git a/test/CodeGen/c-strings.c b/test/CodeGen/c-strings.c index 1021010..60a6b01 100644 --- a/test/CodeGen/c-strings.c +++ b/test/CodeGen/c-strings.c @@ -3,12 +3,19 @@ // Should be 3 hello strings, two global (of different sizes), the rest are // shared. +// CHECK: @align = global i8 [[ALIGN:[0-9]+]] // CHECK: @.str = private unnamed_addr constant [6 x i8] c"hello\00" // CHECK: @f1.x = internal global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0) -// CHECK: @f2.x = internal global [6 x i8] c"hello\00", align 1 -// CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00", align 1 +// CHECK: @f2.x = internal global [6 x i8] c"hello\00", align [[ALIGN]] +// CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00", align [[ALIGN]] // CHECK: @f4.x = internal global %struct.s { i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0) } -// CHECK: @x = global [3 x i8] c"ola", align 1 +// CHECK: @x = global [3 x i8] c"ola", align [[ALIGN]] + +#if defined(__s390x__) +unsigned char align = 2; +#else +unsigned char align = 1; +#endif void bar(const char *); diff --git a/test/CodeGen/le32-regparm.c b/test/CodeGen/le32-regparm.c index 8c1ae5e..c8f7069 100644 --- a/test/CodeGen/le32-regparm.c +++ b/test/CodeGen/le32-regparm.c @@ -1,41 +1,4 @@ -// RUN: %clang_cc1 -triple le32-unknown-nacl %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple le32-unknown-nacl %s -fsyntax-only -verify -#define FASTCALL __attribute__((regparm(2))) +void __attribute__((regparm(2))) fc_f1(int i, int j, int k) {} // expected-error{{'regparm' is not valid on this platform}} -typedef struct { - int aaa; - double bbbb; - int ccc[200]; -} foo; - -// 2 inreg arguments are supported. -void FASTCALL f1(int i, int j, int k); -// CHECK: define void @f1(i32 inreg %i, i32 inreg %j, i32 %k) -void f1(int i, int j, int k) { } - -// inreg structs are not supported. -// CHECK: define void @f2(%struct.foo* inreg %a) -void __attribute__((regparm(1))) f2(foo* a) {} - -// Only the first 2 arguments can be passed inreg, and the first -// non-integral type consumes remaining available registers. -// CHECK: define void @f3(%struct.foo* byval %a, i32 %b) -void __attribute__((regparm(2))) f3(foo a, int b) {} - -// Only 64 total bits are supported -// CHECK: define void @f4(i64 inreg %g, i32 %h) -void __attribute__((regparm(2))) f4(long long g, int h) {} - -typedef void (*FType)(int, int) __attribute ((regparm (2))); -FType bar; -extern void FASTCALL reduced(char b, double c, foo* d, double e, int f); - -int -main(void) { - // The presence of double c means that foo* d is not passed inreg. This - // behavior is different from current x86-32 behavior - // CHECK: call void @reduced(i8 inreg signext 0, {{.*}} %struct.foo* null - reduced(0, 0.0, 0, 0.0, 0); - // CHECK: call void {{.*}}(i32 inreg 1, i32 inreg 2) - bar(1,2); -} diff --git a/test/CodeGen/linetable-endscope.c b/test/CodeGen/linetable-endscope.c new file mode 100644 index 0000000..236f605 --- /dev/null +++ b/test/CodeGen/linetable-endscope.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin10 %s -o - | FileCheck %s + +// Check the line numbers for the ret instruction. We expect it to be +// at the closing of the lexical scope in this case. See the comments in +// CodeGenFunction::FinishFunction() for more details. + +// CHECK: define {{.*}}foo +// CHECK: store {{.*}}, !dbg ![[CONV:[0-9]+]] +// CHECK: ret {{.*}}, !dbg ![[RET:[0-9]+]] + +void foo(char c) +{ + int i; + // CHECK: ![[CONV]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + i = c; + // CHECK: ![[RET]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} +} diff --git a/test/CodeGen/linux-arm-atomic.c b/test/CodeGen/linux-arm-atomic.c new file mode 100644 index 0000000..c7ce1d2 --- /dev/null +++ b/test/CodeGen/linux-arm-atomic.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-linux | FileCheck %s +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv6-unknown-linux | FileCheck %s +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-unknown-linux | FileCheck %s + +typedef int _Atomic_word; +_Atomic_word exchange_and_add(volatile _Atomic_word *__mem, int __val) { + return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); +} + +// CHECK: define {{.*}} @exchange_and_add +// CHECK: atomicrmw {{.*}} add diff --git a/test/CodeGen/may-alias.c b/test/CodeGen/may-alias.c index b73ee15..c767244 100644 --- a/test/CodeGen/may-alias.c +++ b/test/CodeGen/may-alias.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-optzns -o %t %s -// RUN: FileCheck < %t %s +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-optzns -o - %s | FileCheck %s +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -struct-path-tbaa -disable-llvm-optzns -o - %s | FileCheck %s -check-prefix=PATH // Types with the may_alias attribute should be considered equivalent // to char for aliasing. @@ -9,8 +9,10 @@ typedef int __attribute__((may_alias)) aliasing_int; void test0(aliasing_int *ai, int *i) { // CHECK: store i32 0, i32* %{{.*}}, !tbaa !1 +// PATH: store i32 0, i32* %{{.*}}, !tbaa [[TAG_CHAR:!.*]] *ai = 0; // CHECK: store i32 1, i32* %{{.*}}, !tbaa !3 +// PATH: store i32 1, i32* %{{.*}}, !tbaa [[TAG_INT:!.*]] *i = 1; } @@ -19,8 +21,10 @@ struct Test1 { int x; }; struct Test1MA { int x; } __attribute__((may_alias)); void test1(struct Test1MA *p1, struct Test1 *p2) { // CHECK: store i32 2, i32* {{%.*}}, !tbaa !1 + // PATH: store i32 2, i32* {{%.*}}, !tbaa [[TAG_CHAR]] p1->x = 2; // CHECK: store i32 3, i32* {{%.*}}, !tbaa !3 + // PATH: store i32 3, i32* {{%.*}}, !tbaa [[TAG_test1_x:!.*]] p2->x = 3; } @@ -28,3 +32,10 @@ void test1(struct Test1MA *p1, struct Test1 *p2) { // CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2} // CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"} // CHECK: !3 = metadata !{metadata !"int", metadata !1} + +// PATH: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !{{.*}} +// PATH: [[TAG_CHAR]] = metadata !{metadata [[TYPE_CHAR]], metadata [[TYPE_CHAR]], i64 0} +// PATH: [[TAG_INT]] = metadata !{metadata [[TYPE_INT:!.*]], metadata [[TYPE_INT]], i64 0} +// PATH: [[TYPE_INT]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]] +// PATH: [[TAG_test1_x]] = metadata !{metadata [[TYPE_test1:!.*]], metadata [[TYPE_INT]], i64 0} +// PATH: [[TYPE_test1]] = metadata !{metadata !"_ZTS5Test1", metadata [[TYPE_INT]], i64 0} diff --git a/test/CodeGen/mips-inline-asm-modifiers.c b/test/CodeGen/mips-inline-asm-modifiers.c new file mode 100644 index 0000000..7c4ca2c --- /dev/null +++ b/test/CodeGen/mips-inline-asm-modifiers.c @@ -0,0 +1,35 @@ +// RUN: %clang -target mipsel-unknown-linux -S -o - -emit-llvm %s \ +// RUN: | FileCheck %s + +// This checks that the frontend will accept inline asm operand modifiers + +int printf(const char*, ...); + + // CHECK: %{{[0-9]+}} = call i32 asm ".set noreorder;\0Alw $0,$1;\0A.set reorder;\0A", "=r,*m"(i32* getelementptr inbounds ([8 x i32]* @b, i32 {{[0-9]+}}, i32 {{[0-9]+}})) #2, !srcloc !0 + // CHECK: %{{[0-9]+}} = call i32 asm "lw $0,${1:D};\0A", "=r,*m"(i32* getelementptr inbounds ([8 x i32]* @b, i32 {{[0-9]+}}, i32 {{[0-9]+}})) #2, !srcloc !1 +int b[8] = {0,1,2,3,4,5,6,7}; +int main() +{ + int i; + + // The first word. Notice, no 'D' + {asm ( + ".set noreorder;\n" + "lw %0,%1;\n" + ".set reorder;\n" + : "=r" (i) + : "m" (*(b+4)));} + + printf("%d\n",i); + + // The second word + {asm ( + "lw %0,%D1;\n" + : "=r" (i) + : "m" (*(b+4)) + );} + + printf("%d\n",i); + + return 1; +} diff --git a/test/CodeGen/ms-inline-asm-64.c b/test/CodeGen/ms-inline-asm-64.c index 8d2940d..dd7b9b3 100644 --- a/test/CodeGen/ms-inline-asm-64.c +++ b/test/CodeGen/ms-inline-asm-64.c @@ -5,14 +5,42 @@ void t1() { int var = 10; __asm mov rax, offset var ; rax = address of myvar // CHECK: t1 -// CHECK: call void asm sideeffect inteldialect "mov rax, $0", "r,~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW:#[0-9]+]] +// CHECK: call void asm sideeffect inteldialect "mov rax, $0", "r,~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) } void t2() { int var = 10; __asm mov [eax], offset var // CHECK: t2 -// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) } -// CHECK: attributes [[NUW]] = { nounwind } +struct t3_type { int a, b; }; + +int t3() { + struct t3_type foo; + foo.a = 1; + foo.b = 2; + __asm { + lea ebx, foo + mov eax, [ebx].0 + mov [ebx].4, ecx + } + return foo.b; +// CHECK: t3 +// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr $0\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}}) +} + +int t4() { + struct t3_type foo; + foo.a = 1; + foo.b = 2; + __asm { + lea ebx, foo + mov eax, [ebx].foo.a + mov [ebx].foo.b, ecx + } + return foo.b; +// CHECK: t4 +// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr $0\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}}) +} diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c index d50ecfe..c71a8df 100644 --- a/test/CodeGen/ms-inline-asm.c +++ b/test/CodeGen/ms-inline-asm.c @@ -169,36 +169,6 @@ void t17() { // CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"() } -struct t18_type { int a, b; }; - -int t18() { - struct t18_type foo; - foo.a = 1; - foo.b = 2; - __asm { - lea ebx, foo - mov eax, [ebx].0 - mov [ebx].4, ecx - } - return foo.b; -// CHECK: t18 -// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"() -} - -int t19() { - struct t18_type foo; - foo.a = 1; - foo.b = 2; - __asm { - lea ebx, foo - mov eax, [ebx].foo.a - mov [ebx].foo.b, ecx - } - return foo.b; -// CHECK: t19 -// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"() -} - void t20() { char bar; int foo; @@ -284,9 +254,9 @@ void t25() { __asm mov eax, 0xa2h __asm mov eax, 0xa2 // CHECK: t25 -// CHECK: call void asm sideeffect inteldialect "mov eax, $$0ffffffffh", "~{eax},~{dirflag},~{fpsr},~{flags}"() -// CHECK: call void asm sideeffect inteldialect "mov eax, $$0fh", "~{eax},~{dirflag},~{fpsr},~{flags}"() -// CHECK: call void asm sideeffect inteldialect "mov eax, $$0a2h", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967295", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$15", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$162", "~{eax},~{dirflag},~{fpsr},~{flags}"() // CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2h", "~{eax},~{dirflag},~{fpsr},~{flags}"() // CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2", "~{eax},~{dirflag},~{fpsr},~{flags}"() } @@ -310,7 +280,7 @@ void t26() { void t27() { __asm mov eax, fs:[0h] // CHECK: t27 -// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[0h]", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0h]", "~{eax},~{dirflag},~{fpsr},~{flags}"() } void t28() { @@ -390,3 +360,81 @@ void t34() { // CHECK: call void asm sideeffect inteldialect "prefetchnta $$64[eax]", "~{dirflag},~{fpsr},~{flags}"() // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4[eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"() } + +void t35() { + __asm prefetchnta [eax + (200*64)] + __asm mov eax, dword ptr [eax + (200*64)] +// CHECK: t35 +// CHECK: call void asm sideeffect inteldialect "prefetchnta [eax + ($$200*$$64)]", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr [eax + ($$200*$$64)]", "~{eax},~{dirflag},~{fpsr},~{flags}"() +} + +void t36() { + int arr[4]; + __asm mov eax, 4[arr] + __asm mov eax, 4[arr + 4] + __asm mov eax, 8[arr + 4 + 32*2 - 4] + __asm mov eax, 12[4 + arr] + __asm mov eax, 4[4 + arr + 4] + __asm mov eax, 4[64 + arr + (2*32)] + __asm mov eax, 4[64 + arr - 2*32] + __asm mov eax, [arr + 4] + __asm mov eax, [arr + 4 + 32*2 - 4] + __asm mov eax, [4 + arr] + __asm mov eax, [4 + arr + 4] + __asm mov eax, [64 + arr + (2*32)] + __asm mov eax, [64 + arr - 2*32] +// CHECK: t36 +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +} + +void t37() { + __asm mov eax, 4 + 8 + __asm mov eax, 4 + 8 * 16 + __asm mov eax, -4 + 8 * 16 + __asm mov eax, (4 + 4) * 16 + __asm mov eax, 4 + 8 * -16 + __asm mov eax, 4 + 16 / -8 + __asm mov eax, (16 + 16) / -8 +// CHECK: t37 +// CHECK: call void asm sideeffect inteldialect "mov eax, $$12", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$132", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$124", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$128", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967172", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967292", "~{eax},~{dirflag},~{fpsr},~{flags}"() +} + +void t38() { + int arr[4]; + __asm mov eax, 4+4[arr] + __asm mov eax, (4+4)[arr + 4] + __asm mov eax, 8*2[arr + 4 + 32*2 - 4] + __asm mov eax, 12+20[4 + arr] + __asm mov eax, 4*16+4[4 + arr + 4] + __asm mov eax, 4*4[64 + arr + (2*32)] + __asm mov eax, 4*(4-2)[64 + arr - 2*32] + __asm mov eax, 32*(4-2)[arr - 2*32] +// CHECK: t38 +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$80$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$36$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$76$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$144$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$0$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +} diff --git a/test/CodeGen/ms-inline-asm.cpp b/test/CodeGen/ms-inline-asm.cpp index 9c160be..8f824f9 100644 --- a/test/CodeGen/ms-inline-asm.cpp +++ b/test/CodeGen/ms-inline-asm.cpp @@ -1,26 +1,105 @@ // REQUIRES: x86-64-registered-target // RUN: %clang_cc1 -x c++ %s -triple i386-apple-darwin10 -O0 -fasm-blocks -emit-llvm -o - | FileCheck %s +// rdar://13645930 + struct Foo { static int *ptr; static int a, b; + int arr[4]; struct Bar { static int *ptr; + char arr[2]; }; }; void t1() { Foo::ptr = (int *)0xDEADBEEF; Foo::Bar::ptr = (int *)0xDEADBEEF; - __asm mov eax, Foo::ptr - __asm mov eax, Foo::Bar::ptr - __asm mov eax, [Foo::ptr] - __asm mov eax, dword ptr [Foo::ptr] - __asm mov eax, dword ptr [Foo::ptr] + __asm mov eax, Foo ::ptr + __asm mov eax, Foo :: Bar :: ptr + __asm mov eax, [Foo:: ptr] + __asm mov eax, dword ptr [Foo :: ptr] + __asm mov eax, dword ptr [Foo :: ptr] // CHECK: @_Z2t1v -// CHECK: call void asm sideeffect inteldialect "mov eax, Foo::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"() -// CHECK: call void asm sideeffect inteldialect "mov eax, Foo::Bar::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"() -// CHECK: call void asm sideeffect inteldialect "mov eax, [Foo::ptr]", "~{eax},~{dirflag},~{fpsr},~{flags}"() -// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr [Foo::ptr]", "~{eax},~{dirflag},~{fpsr},~{flags}"() -// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr [Foo::ptr]", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3Bar3ptrE) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE) +} + +int gvar = 10; +void t2() { + int lvar = 10; + __asm mov eax, offset Foo::ptr + __asm mov eax, offset Foo::Bar::ptr +// CHECK: t2 +// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3Bar3ptrE) +} + +// CHECK: define void @_Z2t3v() +void t3() { + __asm mov eax, LENGTH Foo::ptr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() + __asm mov eax, LENGTH Foo::Bar::ptr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() + __asm mov eax, LENGTH Foo::arr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() + __asm mov eax, LENGTH Foo::Bar::arr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"() + + __asm mov eax, TYPE Foo::ptr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() + __asm mov eax, TYPE Foo::Bar::ptr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() + __asm mov eax, TYPE Foo::arr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() + __asm mov eax, TYPE Foo::Bar::arr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() + + __asm mov eax, SIZE Foo::ptr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() + __asm mov eax, SIZE Foo::Bar::ptr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() + __asm mov eax, SIZE Foo::arr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"() + __asm mov eax, SIZE Foo::Bar::arr +// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"() + +} + +struct T4 { + int x; + static int y; + void test(); +}; + +// CHECK: define void @_ZN2T44testEv( +void T4::test() { +// CHECK: [[T0:%.*]] = alloca [[T4:%.*]]*, +// CHECK: [[THIS:%.*]] = load [[T4]]** [[T0]] +// CHECK: [[X:%.*]] = getelementptr inbounds [[T4]]* [[THIS]], i32 0, i32 0 + __asm mov eax, x; +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* [[X]]) + __asm mov y, eax; +// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, eax", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE) +} + +template <class T> struct T5 { + template <class U> static T create(U); + void run(); +}; +// CHECK: define void @_Z5test5v() +void test5() { + // CHECK: [[X:%.*]] = alloca i32 + // CHECK: [[Y:%.*]] = alloca i32 + int x, y; + __asm push y + // CHECK: call void asm sideeffect inteldialect "push dword ptr $0", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* [[Y]]) + __asm call T5<int>::create<float> + // CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(i32 (float)* @_ZN2T5IiE6createIfEEiT_) + __asm mov x, eax + // CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, eax", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* [[X]]) } diff --git a/test/CodeGen/mult-alt-generic.c b/test/CodeGen/mult-alt-generic.c index 6cf6f0a..111679e 100644 --- a/test/CodeGen/mult-alt-generic.c +++ b/test/CodeGen/mult-alt-generic.c @@ -6,7 +6,9 @@ // RUN: %clang_cc1 -triple mipsel %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple powerpc %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple powerpc64 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple s390x %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple sparc %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple sparcv9 %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple thumb %s -emit-llvm -o - | FileCheck %s int mout0; diff --git a/test/CodeGen/pragma-pack-1.c b/test/CodeGen/pragma-pack-1.c index c30a62a..2a71c8f 100644 --- a/test/CodeGen/pragma-pack-1.c +++ b/test/CodeGen/pragma-pack-1.c @@ -1,7 +1,68 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s | FileCheck %s // PR4610 #pragma pack(4) struct ref { struct ref *next; } refs; + +// PR13580 +struct S +{ + char a[3]; +#pragma pack(1) + struct T + { + char b; + int c; + } d; +#pragma pack() + struct T2 + { + char b; + int c; + } d2; +} ss; + +struct S3 +{ + char a[3]; +#pragma pack(push, 2) + struct T3 + { + char b; + int c; + } d; +#pragma pack(pop) + struct T32 + { + char b; + int c; + } e; +} s3; + +struct S4 +{ + char a[3]; +#pragma align=packed + struct T4 + { + char b; + int c; + } d; + int e; +} s4; + +// CHECK: [[struct_ref:%[a-zA-Z0-9_.]+]] = type <{ [[struct_ref]]* }> +// CHECK: [[struct_S:%[a-zA-Z0-9_.]+]] = type { [3 x i8], [[struct_T:%[a-zA-Z0-9_.]+]], [[struct_T2:%[a-zA-Z0-9_.]+]] } +// CHECK: [[struct_T]] = type <{ i8, i32 }> +// CHECK: [[struct_T2]] = type { i8, i32 } + +// CHECK: %struct.S3 = type <{ [3 x i8], i8, %struct.T3, [2 x i8], %struct.T32 }> +// CHECK: %struct.T3 = type <{ i8, i8, i32 }> +// CHECK: %struct.T32 = type { i8, i32 } +// CHECK: %struct.S4 = type { [3 x i8], %struct.T4, i32 } +// CHECK: %struct.T4 = type <{ i8, i32 }> + +// CHECK: @refs = common global [[struct_ref]] +// CHECK: @ss = common global [[struct_S]] diff --git a/test/CodeGen/sparc-target-data.c b/test/CodeGen/sparc-target-data.c new file mode 100644 index 0000000..bb32a21 --- /dev/null +++ b/test/CodeGen/sparc-target-data.c @@ -0,0 +1,5 @@ +// RUN: %clang -target sparc-sun-solaris -o - -emit-llvm -S %s | FileCheck %s -check-prefix=V8 +// RUN: %clang -target sparcv9-sun-solaris -o - -emit-llvm -S %s | FileCheck %s -check-prefix=V9 + +// V8: E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64 +// V9: E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32:64-S128 diff --git a/test/CodeGen/systemz-inline-asm.c b/test/CodeGen/systemz-inline-asm.c new file mode 100644 index 0000000..8e5854f --- /dev/null +++ b/test/CodeGen/systemz-inline-asm.c @@ -0,0 +1,131 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s | FileCheck %s + +unsigned int gi; +unsigned long gl; + +void test_store_m(unsigned int i) { + asm("st %1, %0" : "=m" (gi) : "r" (i)); +// CHECK: define void @test_store_m(i32 zeroext %i) +// CHECK: call void asm "st $1, $0", "=*m,r"(i32* @gi, i32 %i) +} + +void test_store_Q(unsigned int i) { + asm("st %1, %0" : "=Q" (gi) : "r" (i)); +// CHECK: define void @test_store_Q(i32 zeroext %i) +// CHECK: call void asm "st $1, $0", "=*Q,r"(i32* @gi, i32 %i) +} + +void test_store_R(unsigned int i) { + asm("st %1, %0" : "=R" (gi) : "r" (i)); +// CHECK: define void @test_store_R(i32 zeroext %i) +// CHECK: call void asm "st $1, $0", "=*R,r"(i32* @gi, i32 %i) +} + +void test_store_S(unsigned int i) { + asm("st %1, %0" : "=S" (gi) : "r" (i)); +// CHECK: define void @test_store_S(i32 zeroext %i) +// CHECK: call void asm "st $1, $0", "=*S,r"(i32* @gi, i32 %i) +} + +void test_store_T(unsigned int i) { + asm("st %1, %0" : "=T" (gi) : "r" (i)); +// CHECK: define void @test_store_T(i32 zeroext %i) +// CHECK: call void asm "st $1, $0", "=*T,r"(i32* @gi, i32 %i) +} + +int test_load_m() { + unsigned int i; + asm("l %0, %1" : "=r" (i) : "m" (gi)); + return i; +// CHECK: define signext i32 @test_load_m() +// CHECK: call i32 asm "l $0, $1", "=r,*m"(i32* @gi) +} + +int test_load_Q() { + unsigned int i; + asm("l %0, %1" : "=r" (i) : "Q" (gi)); + return i; +// CHECK: define signext i32 @test_load_Q() +// CHECK: call i32 asm "l $0, $1", "=r,*Q"(i32* @gi) +} + +int test_load_R() { + unsigned int i; + asm("l %0, %1" : "=r" (i) : "R" (gi)); + return i; +// CHECK: define signext i32 @test_load_R() +// CHECK: call i32 asm "l $0, $1", "=r,*R"(i32* @gi) +} + +int test_load_S() { + unsigned int i; + asm("l %0, %1" : "=r" (i) : "S" (gi)); + return i; +// CHECK: define signext i32 @test_load_S() +// CHECK: call i32 asm "l $0, $1", "=r,*S"(i32* @gi) +} + +int test_load_T() { + unsigned int i; + asm("l %0, %1" : "=r" (i) : "T" (gi)); + return i; +// CHECK: define signext i32 @test_load_T() +// CHECK: call i32 asm "l $0, $1", "=r,*T"(i32* @gi) +} + +void test_mI(unsigned char *c) { + asm volatile("cli %0, %1" :: "Q" (*c), "I" (100)); +// CHECK: define void @test_mI(i8* %c) +// CHECK: call void asm sideeffect "cli $0, $1", "*Q,I"(i8* %c, i32 100) +} + +unsigned int test_dJa(unsigned int i, unsigned int j) { + asm("sll %0, %2(%3)" : "=d" (i) : "0" (i), "J" (1000), "a" (j)); + return i; +// CHECK: define zeroext i32 @test_dJa(i32 zeroext %i, i32 zeroext %j) +// CHECK: call i32 asm "sll $0, $2($3)", "=d,0,J,a"(i32 %i, i32 1000, i32 %j) +} + +unsigned long test_rK(unsigned long i) { + asm("aghi %0, %2" : "=r" (i) : "0" (i), "K" (-30000)); + return i; +// CHECK: define i64 @test_rK(i64 %i) +// CHECK: call i64 asm "aghi $0, $2", "=r,0,K"(i64 %i, i32 -30000) +} + +unsigned long test_rL(unsigned long i) { + asm("sllg %0, %1, %2" : "=r" (i) : "r" (i), "L" (500000)); + return i; +// CHECK: define i64 @test_rL(i64 %i) +// CHECK: call i64 asm "sllg $0, $1, $2", "=r,r,L"(i64 %i, i32 500000) +} + +void test_M() { + asm volatile("#FOO %0" :: "M"(0x7fffffff)); +// CHECK: define void @test_M() +// CHECK: call void asm sideeffect "#FOO $0", "M"(i32 2147483647) +} + +float test_f32(float f, float g) { + asm("aebr %0, %2" : "=f" (f) : "0" (f), "f" (g)); + return f; +// CHECK: define float @test_f32(float %f, float %g) +// CHECK: call float asm "aebr $0, $2", "=f,0,f"(float %f, float %g) +} + +double test_f64(double f, double g) { + asm("adbr %0, %2" : "=f" (f) : "0" (f), "f" (g)); + return f; +// CHECK: define double @test_f64(double %f, double %g) +// CHECK: call double asm "adbr $0, $2", "=f,0,f"(double %f, double %g) +} + +long double test_f128(long double f, long double g) { + asm("axbr %0, %2" : "=f" (f) : "0" (f), "f" (g)); + return f; +// CHECK: define void @test_f128(fp128* noalias nocapture sret [[DEST:%.*]], fp128* byval nocapture, fp128* byval nocapture) +// CHECK: %f = load fp128* %0 +// CHECK: %g = load fp128* %1 +// CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g) +// CHECK: store fp128 [[RESULT]], fp128* [[DEST]] +} diff --git a/test/CodeGen/tbaa-class.cpp b/test/CodeGen/tbaa-class.cpp new file mode 100644 index 0000000..967ba19 --- /dev/null +++ b/test/CodeGen/tbaa-class.cpp @@ -0,0 +1,226 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH +// Test TBAA metadata generated by front-end. + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +class StructA +{ +public: + uint16_t f16; + uint32_t f32; + uint16_t f16_2; + uint32_t f32_2; +}; +class StructB +{ +public: + uint16_t f16; + StructA a; + uint32_t f32; +}; +class StructC +{ +public: + uint16_t f16; + StructB b; + uint32_t f32; +}; +class StructD +{ +public: + uint16_t f16; + StructB b; + uint32_t f32; + uint8_t f8; +}; + +class StructS +{ +public: + uint16_t f16; + uint32_t f32; +}; +class StructS2 : public StructS +{ +public: + uint16_t f16_2; + uint32_t f32_2; +}; + +uint32_t g(uint32_t *s, StructA *A, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]] + *s = 1; + A->f32 = 4; + return *s; +} + +uint32_t g2(uint32_t *s, StructA *A, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]] +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_A_f16:!.*]] + *s = 1; + A->f16 = 4; + return *s; +} + +uint32_t g3(StructA *A, StructB *B, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]] + A->f32 = 1; + B->a.f32 = 4; + return A->f32; +} + +uint32_t g4(StructA *A, StructB *B, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_B_a_f16:!.*]] + A->f32 = 1; + B->a.f16 = 4; + return A->f32; +} + +uint32_t g5(StructA *A, StructB *B, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]] + A->f32 = 1; + B->f32 = 4; + return A->f32; +} + +uint32_t g6(StructA *A, StructB *B, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]] + A->f32 = 1; + B->a.f32_2 = 4; + return A->f32; +} + +uint32_t g7(StructA *A, StructS *S, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]] + A->f32 = 1; + S->f32 = 4; + return A->f32; +} + +uint32_t g8(StructA *A, StructS *S, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_S_f16:!.*]] + A->f32 = 1; + S->f16 = 4; + return A->f32; +} + +uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]] + S->f32 = 1; + S2->f32 = 4; + return S->f32; +} + +uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S2_f32_2:!.*]] + S->f32 = 1; + S2->f32_2 = 4; + return S->f32; +} + +uint32_t g11(StructC *C, StructD *D, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_C_b_a_f32:!.*]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_D_b_a_f32:!.*]] + C->b.a.f32 = 1; + D->b.a.f32 = 4; + return C->b.a.f32; +} + +uint32_t g12(StructC *C, StructD *D, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// TODO: differentiate the two accesses. +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]] + StructB *b1 = &(C->b); + StructB *b2 = &(D->b); + // b1, b2 have different context. + b1->a.f32 = 1; + b2->a.f32 = 4; + return b1->a.f32; +} + +// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2} +// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"} +// CHECK: !4 = metadata !{metadata !"int", metadata !1} +// CHECK: !5 = metadata !{metadata !"short", metadata !1} + +// PATH: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !3 +// PATH: [[TAG_i32]] = metadata !{metadata [[TYPE_INT:!.*]], metadata [[TYPE_INT]], i64 0} +// PATH: [[TYPE_INT]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]] +// PATH: [[TAG_A_f32]] = metadata !{metadata [[TYPE_A:!.*]], metadata [[TYPE_INT]], i64 4} +// PATH: [[TYPE_A]] = metadata !{metadata !"_ZTS7StructA", metadata [[TYPE_SHORT:!.*]], i64 0, metadata [[TYPE_INT]], i64 4, metadata [[TYPE_SHORT]], i64 8, metadata [[TYPE_INT]], i64 12} +// PATH: [[TYPE_SHORT:!.*]] = metadata !{metadata !"short", metadata [[TYPE_CHAR]] +// PATH: [[TAG_A_f16]] = metadata !{metadata [[TYPE_A]], metadata [[TYPE_SHORT]], i64 0} +// PATH: [[TAG_B_a_f32]] = metadata !{metadata [[TYPE_B:!.*]], metadata [[TYPE_INT]], i64 8} +// PATH: [[TYPE_B]] = metadata !{metadata !"_ZTS7StructB", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_A]], i64 4, metadata [[TYPE_INT]], i64 20} +// PATH: [[TAG_B_a_f16]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_SHORT]], i64 4} +// PATH: [[TAG_B_f32]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 20} +// PATH: [[TAG_B_a_f32_2]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 16} +// PATH: [[TAG_S_f32]] = metadata !{metadata [[TYPE_S:!.*]], metadata [[TYPE_INT]], i64 4} +// PATH: [[TYPE_S]] = metadata !{metadata !"_ZTS7StructS", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_INT]], i64 4} +// PATH: [[TAG_S_f16]] = metadata !{metadata [[TYPE_S]], metadata [[TYPE_SHORT]], i64 0} +// PATH: [[TAG_S2_f32_2]] = metadata !{metadata [[TYPE_S2:!.*]], metadata [[TYPE_INT]], i64 12} +// PATH: [[TYPE_S2]] = metadata !{metadata !"_ZTS8StructS2", metadata [[TYPE_SHORT]], i64 8, metadata [[TYPE_INT]], i64 12} +// PATH: [[TAG_C_b_a_f32]] = metadata !{metadata [[TYPE_C:!.*]], metadata [[TYPE_INT]], i64 12} +// PATH: [[TYPE_C]] = metadata !{metadata !"_ZTS7StructC", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28} +// PATH: [[TAG_D_b_a_f32]] = metadata !{metadata [[TYPE_D:!.*]], metadata [[TYPE_INT]], i64 12} +// PATH: [[TYPE_D]] = metadata !{metadata !"_ZTS7StructD", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28, metadata [[TYPE_CHAR]], i64 32} diff --git a/test/CodeGen/tbaa-struct.cpp b/test/CodeGen/tbaa-struct.cpp index 12a6f4d..6d593a3 100644 --- a/test/CodeGen/tbaa-struct.cpp +++ b/test/CodeGen/tbaa-struct.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - -O1 %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - -O1 %s | FileCheck %s // // Check that we generate !tbaa.struct metadata for struct copies. struct A { @@ -39,8 +39,36 @@ void copy3 (T1 *a, T1 *b) { // CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 12, i32 4, i1 false), !tbaa.struct [[TS3:!.*]] +// Make sure that zero-length bitfield works. +#define ATTR __attribute__ ((ms_struct)) +struct five { + char a; + int :0; /* ignored; prior field is not a bitfield. */ + char b; + char c; +} ATTR; +void copy4(struct five *a, struct five *b) { + *a = *b; +} +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 3, i32 1, i1 false), !tbaa.struct [[TS4:!.*]] + +struct six { + char a; + int :0; + char b; + char c; +}; +void copy5(struct six *a, struct six *b) { + *a = *b; +} +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 6, i32 1, i1 false), !tbaa.struct [[TS5:!.*]] + // CHECK: [[TS]] = metadata !{i64 0, i64 2, metadata !{{.*}}, i64 4, i64 4, metadata !{{.*}}, i64 8, i64 1, metadata !{{.*}}, i64 12, i64 4, metadata !{{.*}}} +// CHECK: [[CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !{{.*}}} +// CHECK: [[INT:!.*]] = metadata !{metadata !"int", metadata [[CHAR]]} // (offset, size) = (0,1) char; (4,2) short; (8,4) int; (12,1) char; (16,4) int; (20,4) int // CHECK: [[TS2]] = metadata !{i64 0, i64 1, metadata !{{.*}}, i64 4, i64 2, metadata !{{.*}}, i64 8, i64 4, metadata !{{.*}}, i64 12, i64 1, metadata !{{.*}}, i64 16, i64 4, metadata {{.*}}, i64 20, i64 4, metadata {{.*}}} // (offset, size) = (0,8) char; (0,2) char; (4,8) char // CHECK: [[TS3]] = metadata !{i64 0, i64 8, metadata !{{.*}}, i64 0, i64 2, metadata !{{.*}}, i64 4, i64 8, metadata !{{.*}}} +// CHECK: [[TS4]] = metadata !{i64 0, i64 1, metadata [[CHAR]], i64 1, i64 1, metadata [[CHAR]], i64 2, i64 1, metadata [[CHAR]]} +// CHECK: [[TS5]] = metadata !{i64 0, i64 1, metadata [[CHAR]], i64 4, i64 4, metadata [[INT]], i64 4, i64 1, metadata [[CHAR]], i64 5, i64 1, metadata [[CHAR]]} diff --git a/test/CodeGen/tbaa.cpp b/test/CodeGen/tbaa.cpp index c30e4a3..afb8893 100644 --- a/test/CodeGen/tbaa.cpp +++ b/test/CodeGen/tbaa.cpp @@ -1,8 +1,11 @@ -// RUN: %clang_cc1 -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH // Test TBAA metadata generated by front-end. -#include <stdint.h> +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; typedef struct { uint16_t f16; @@ -46,8 +49,8 @@ uint32_t g(uint32_t *s, StructA *A, uint64_t count) { // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !5 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]] *s = 1; A->f32 = 4; return *s; @@ -58,8 +61,8 @@ uint32_t g2(uint32_t *s, StructA *A, uint64_t count) { // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 // CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !8 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]] +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_A_f16:!.*]] *s = 1; A->f16 = 4; return *s; @@ -70,8 +73,8 @@ uint32_t g3(StructA *A, StructB *B, uint64_t count) { // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]] A->f32 = 1; B->a.f32 = 4; return A->f32; @@ -82,8 +85,8 @@ uint32_t g4(StructA *A, StructB *B, uint64_t count) { // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 // CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !11 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_B_a_f16:!.*]] A->f32 = 1; B->a.f16 = 4; return A->f32; @@ -94,8 +97,8 @@ uint32_t g5(StructA *A, StructB *B, uint64_t count) { // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !12 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]] A->f32 = 1; B->f32 = 4; return A->f32; @@ -106,8 +109,8 @@ uint32_t g6(StructA *A, StructB *B, uint64_t count) { // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !13 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]] A->f32 = 1; B->a.f32_2 = 4; return A->f32; @@ -118,8 +121,8 @@ uint32_t g7(StructA *A, StructS *S, uint64_t count) { // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !14 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]] A->f32 = 1; S->f32 = 4; return A->f32; @@ -130,8 +133,8 @@ uint32_t g8(StructA *A, StructS *S, uint64_t count) { // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 // CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !16 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_S_f16:!.*]] A->f32 = 1; S->f16 = 4; return A->f32; @@ -142,8 +145,8 @@ uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) { // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !17 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S2_f32:!.*]] S->f32 = 1; S2->f32 = 4; return S->f32; @@ -154,8 +157,8 @@ uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) { // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 // CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14 -// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !19 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]] +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_S2_f16:!.*]] S->f32 = 1; S2->f16 = 4; return S->f32; @@ -166,8 +169,8 @@ uint32_t g11(StructC *C, StructD *D, uint64_t count) { // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !20 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !22 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_C_b_a_f32:!.*]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_D_b_a_f32:!.*]] C->b.a.f32 = 1; D->b.a.f32 = 4; return C->b.a.f32; @@ -179,8 +182,8 @@ uint32_t g12(StructC *C, StructD *D, uint64_t count) { // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 // TODO: differentiate the two accesses. // PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !9 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9 +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]] +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]] StructB *b1 = &(C->b); StructB *b2 = &(D->b); // b1, b2 have different context. @@ -189,29 +192,64 @@ uint32_t g12(StructC *C, StructD *D, uint64_t count) { return b1->a.f32; } +// Make sure that zero-length bitfield works. +#define ATTR __attribute__ ((ms_struct)) +struct five { + char a; + int :0; /* ignored; prior field is not a bitfield. */ + char b; + char c; +} ATTR; +char g13(struct five *a, struct five *b) { + return a->b; +// CHECK: define signext i8 @{{.*}}( +// CHECK: load i8* %{{.*}}, align 1, !tbaa !1 +// PATH: define signext i8 @{{.*}}( +// PATH: load i8* %{{.*}}, align 1, !tbaa [[TAG_five_b:!.*]] +} + +struct six { + char a; + int :0; + char b; + char c; +}; +char g14(struct six *a, struct six *b) { +// CHECK: define signext i8 @{{.*}}( +// CHECK: load i8* %{{.*}}, align 1, !tbaa !1 +// PATH: define signext i8 @{{.*}}( +// PATH: load i8* %{{.*}}, align 1, !tbaa [[TAG_six_b:!.*]] + return a->b; +} + // CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2} // CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"} // CHECK: !4 = metadata !{metadata !"int", metadata !1} // CHECK: !5 = metadata !{metadata !"short", metadata !1} -// PATH: !1 = metadata !{metadata !"omnipotent char", metadata !2} -// PATH: !4 = metadata !{metadata !"int", metadata !1} -// PATH: !5 = metadata !{metadata !6, metadata !4, i64 4} -// PATH: !6 = metadata !{metadata !"_ZTS7StructA", i64 0, metadata !7, i64 4, metadata !4} -// PATH: !7 = metadata !{metadata !"short", metadata !1} -// PATH: !8 = metadata !{metadata !6, metadata !7, i64 0} -// PATH: !9 = metadata !{metadata !10, metadata !4, i64 8} -// PATH: !10 = metadata !{metadata !"_ZTS7StructB", i64 0, metadata !7, i64 4, metadata !6, i64 20, metadata !4} -// PATH: !11 = metadata !{metadata !10, metadata !7, i64 4} -// PATH: !12 = metadata !{metadata !10, metadata !4, i64 20} -// PATH: !13 = metadata !{metadata !10, metadata !4, i64 16} -// PATH: !14 = metadata !{metadata !15, metadata !4, i64 4} -// PATH: !15 = metadata !{metadata !"_ZTS7StructS", i64 0, metadata !7, i64 4, metadata !4} -// PATH: !16 = metadata !{metadata !15, metadata !7, i64 0} -// PATH: !17 = metadata !{metadata !18, metadata !4, i64 4} -// PATH: !18 = metadata !{metadata !"_ZTS8StructS2", i64 0, metadata !7, i64 4, metadata !4} -// PATH: !19 = metadata !{metadata !18, metadata !7, i64 0} -// PATH: !20 = metadata !{metadata !21, metadata !4, i64 12} -// PATH: !21 = metadata !{metadata !"_ZTS7StructC", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4} -// PATH: !22 = metadata !{metadata !23, metadata !4, i64 12} -// PATH: !23 = metadata !{metadata !"_ZTS7StructD", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4, i64 32, metadata !1} +// PATH: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !3 +// PATH: [[TAG_i32]] = metadata !{metadata [[TYPE_INT:!.*]], metadata [[TYPE_INT]], i64 0} +// PATH: [[TYPE_INT]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]] +// PATH: [[TAG_A_f32]] = metadata !{metadata [[TYPE_A:!.*]], metadata [[TYPE_INT]], i64 4} +// PATH: [[TYPE_A]] = metadata !{metadata !"_ZTS7StructA", metadata [[TYPE_SHORT:!.*]], i64 0, metadata [[TYPE_INT]], i64 4, metadata [[TYPE_SHORT]], i64 8, metadata [[TYPE_INT]], i64 12} +// PATH: [[TYPE_SHORT:!.*]] = metadata !{metadata !"short", metadata [[TYPE_CHAR]] +// PATH: [[TAG_A_f16]] = metadata !{metadata [[TYPE_A]], metadata [[TYPE_SHORT]], i64 0} +// PATH: [[TAG_B_a_f32]] = metadata !{metadata [[TYPE_B:!.*]], metadata [[TYPE_INT]], i64 8} +// PATH: [[TYPE_B]] = metadata !{metadata !"_ZTS7StructB", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_A]], i64 4, metadata [[TYPE_INT]], i64 20} +// PATH: [[TAG_B_a_f16]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_SHORT]], i64 4} +// PATH: [[TAG_B_f32]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 20} +// PATH: [[TAG_B_a_f32_2]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 16} +// PATH: [[TAG_S_f32]] = metadata !{metadata [[TYPE_S:!.*]], metadata [[TYPE_INT]], i64 4} +// PATH: [[TYPE_S]] = metadata !{metadata !"_ZTS7StructS", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_INT]], i64 4} +// PATH: [[TAG_S_f16]] = metadata !{metadata [[TYPE_S]], metadata [[TYPE_SHORT]], i64 0} +// PATH: [[TAG_S2_f32]] = metadata !{metadata [[TYPE_S2:!.*]], metadata [[TYPE_INT]], i64 4} +// PATH: [[TYPE_S2]] = metadata !{metadata !"_ZTS8StructS2", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_INT]], i64 4} +// PATH: [[TAG_S2_f16]] = metadata !{metadata [[TYPE_S2]], metadata [[TYPE_SHORT]], i64 0} +// PATH: [[TAG_C_b_a_f32]] = metadata !{metadata [[TYPE_C:!.*]], metadata [[TYPE_INT]], i64 12} +// PATH: [[TYPE_C]] = metadata !{metadata !"_ZTS7StructC", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28} +// PATH: [[TAG_D_b_a_f32]] = metadata !{metadata [[TYPE_D:!.*]], metadata [[TYPE_INT]], i64 12} +// PATH: [[TYPE_D]] = metadata !{metadata !"_ZTS7StructD", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28, metadata [[TYPE_CHAR]], i64 32} +// PATH: [[TAG_five_b]] = metadata !{metadata [[TYPE_five:!.*]], metadata [[TYPE_CHAR]], i64 1} +// PATH: [[TYPE_five]] = metadata !{metadata !"_ZTS4five", metadata [[TYPE_CHAR]], i64 0, metadata [[TYPE_CHAR]], i64 1, metadata [[TYPE_CHAR]], i64 2} +// PATH: [[TAG_six_b]] = metadata !{metadata [[TYPE_six:!.*]], metadata [[TYPE_CHAR]], i64 4} +// PATH: [[TYPE_six]] = metadata !{metadata !"_ZTS3six", metadata [[TYPE_CHAR]], i64 0, metadata [[TYPE_INT]], i64 4, metadata [[TYPE_CHAR]], i64 4, metadata [[TYPE_CHAR]], i64 5} diff --git a/test/CodeGen/thread-specifier.c b/test/CodeGen/thread-specifier.c index a2d3e62..8e21651 100644 --- a/test/CodeGen/thread-specifier.c +++ b/test/CodeGen/thread-specifier.c @@ -10,6 +10,9 @@ // CHECK: @i = thread_local(initialexec) global // CHECK: @j = thread_local(localexec) global +// CHECK-NOT: @_ZTW +// CHECK-NOT: @_ZTH + __thread int a; extern __thread int b; int c() { return *&b; } diff --git a/test/CodeGen/x86_32-arguments-win32.c b/test/CodeGen/x86_32-arguments-win32.c index f18bb30..77ff9e2 100644 --- a/test/CodeGen/x86_32-arguments-win32.c +++ b/test/CodeGen/x86_32-arguments-win32.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -w -triple i386-pc-win32 -emit-llvm -o - %s | FileCheck %s // CHECK: define i64 @f1_1() -// CHECK: define void @f1_2(i32 %a0.0, i32 %a0.1) +// CHECK: define void @f1_2(%struct.s1* byval align 4 %a0) struct s1 { int a; int b; @@ -31,7 +31,7 @@ struct s4 { struct s4 f4_1(void) { while (1) {} } // CHECK: define i64 @f5_1() -// CHECK: define void @f5_2(double %a0.0) +// CHECK: define void @f5_2(%struct.s5* byval align 4) struct s5 { double a; }; @@ -39,7 +39,7 @@ struct s5 f5_1(void) { while (1) {} } void f5_2(struct s5 a0) {} // CHECK: define i32 @f6_1() -// CHECK: define void @f6_2(float %a0.0) +// CHECK: define void @f6_2(%struct.s6* byval align 4 %a0) struct s6 { float a; }; diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp index 8d9fce0..d683493 100644 --- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -51,6 +51,12 @@ struct wantslist1 { // CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, i32 0, i32 0), i{{32|64}} 3 } std::initializer_list<int> globalInitList1 = {1, 2, 3}; +namespace thread_local_global_array { + // CHECK: @_ZN25thread_local_global_arrayL11x__initlistE = internal thread_local global [4 x i32] [i32 1, i32 2, i32 3, i32 4] + // CHECK: @_ZN25thread_local_global_array1xE = thread_local global {{.*}} @_ZN25thread_local_global_arrayL11x__initlistE, {{.*}} i64 4 + std::initializer_list<int> thread_local x = { 1, 2, 3, 4 }; +} + // CHECK: @_ZL25globalInitList2__initlist = internal global [2 x %{{[^ ]*}}] zeroinitializer // CHECK: @globalInitList2 = global %{{[^ ]+}} { %[[WITHARG:[^ *]+]]* getelementptr inbounds ([2 x // CHECK: appending global @@ -250,3 +256,22 @@ namespace PR12178 { map m{ {1, 2}, {3, 4} }; } + +namespace rdar13325066 { + struct X { ~X(); }; + + // CHECK: define void @_ZN12rdar133250664loopERNS_1XES1_ + void loop(X &x1, X &x2) { + // CHECK: br label + // CHECK: br i1 + // CHECK: br label + // CHECK call void @_ZN12rdar133250661XD1Ev + // CHECK: br label + // CHECK: br label + // CHECK: call void @_ZN12rdar133250661XD1Ev + // CHECK: br i1 + // CHECK: br label + // CHECK: ret void + for (X x : { x1, x2 }) { } + } +} diff --git a/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/test/CodeGenCXX/cxx11-thread-local-reference.cpp new file mode 100644 index 0000000..2ea9acd --- /dev/null +++ b/test/CodeGenCXX/cxx11-thread-local-reference.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s + +int &f(); + +// CHECK: @r = thread_local global i32* null +thread_local int &r = f(); + +// CHECK: @_ZTH1r = alias void ()* @__tls_init + +int &g() { return r; } + +// CHECK: define {{.*}} @[[R_INIT:.*]]() +// CHECK: call i32* @_Z1fv() +// CHECK: store i32* %{{.*}}, i32** @r, align 8 + +// CHECK: define i32* @_Z1gv() +// CHECK: call i32* @_ZTW1r() +// CHECK: ret i32* %{{.*}} + +// CHECK: define weak_odr hidden i32* @_ZTW1r() { +// CHECK: call void @_ZTH1r() +// CHECK: load i32** @r, align 8 +// CHECK: ret i32* %{{.*}} + +// CHECK: define internal void @__tls_init() +// CHECK: call void @[[R_INIT]]() diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp new file mode 100644 index 0000000..a7141d1 --- /dev/null +++ b/test/CodeGenCXX/cxx11-thread-local.cpp @@ -0,0 +1,173 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s + +int f(); +int g(); + +// CHECK: @a = thread_local global i32 0 +thread_local int a = f(); +extern thread_local int b; +// CHECK: @c = global i32 0 +int c = b; +// CHECK: @_ZL1d = internal thread_local global i32 0 +static thread_local int d = g(); + +struct U { static thread_local int m; }; +// CHECK: @_ZN1U1mE = thread_local global i32 0 +thread_local int U::m = f(); + +template<typename T> struct V { static thread_local int m; }; +template<typename T> thread_local int V<T>::m = g(); + +// CHECK: @e = global i32 0 +int e = V<int>::m; + +// CHECK: @_ZN1VIiE1mE = weak_odr thread_local global i32 0 + +// CHECK: @_ZZ1fvE1n = internal thread_local global i32 0 + +// CHECK: @_ZGVZ1fvE1n = internal thread_local global i8 0 + +// CHECK: @_ZZ8tls_dtorvE1s = internal thread_local global +// CHECK: @_ZGVZ8tls_dtorvE1s = internal thread_local global i8 0 + +// CHECK: @_ZZ8tls_dtorvE1t = internal thread_local global +// CHECK: @_ZGVZ8tls_dtorvE1t = internal thread_local global i8 0 + +// CHECK: @_ZZ8tls_dtorvE1u = internal thread_local global +// CHECK: @_ZGVZ8tls_dtorvE1u = internal thread_local global i8 0 +// CHECK: @_ZGRZ8tls_dtorvE1u = internal thread_local global + +// CHECK: @_ZGVN1VIiE1mE = weak_odr thread_local global i64 0 + +// CHECK: @__tls_guard = internal thread_local global i8 0 + +// CHECK: @llvm.global_ctors = appending global {{.*}} @[[GLOBAL_INIT:[^ ]*]] + +// CHECK: @_ZTH1a = alias void ()* @__tls_init +// CHECK: @_ZTHL1d = alias internal void ()* @__tls_init +// CHECK: @_ZTHN1U1mE = alias void ()* @__tls_init +// CHECK: @_ZTHN1VIiE1mE = alias weak_odr void ()* @__tls_init + + +// Individual variable initialization functions: + +// CHECK: define {{.*}} @[[A_INIT:.*]]() +// CHECK: call i32 @_Z1fv() +// CHECK-NEXT: store i32 {{.*}}, i32* @a, align 4 + +// CHECK: define i32 @_Z1fv() +int f() { + // CHECK: %[[GUARD:.*]] = load i8* @_ZGVZ1fvE1n, align 1 + // CHECK: %[[NEED_INIT:.*]] = icmp eq i8 %[[GUARD]], 0 + // CHECK: br i1 %[[NEED_INIT]] + + // CHECK: %[[CALL:.*]] = call i32 @_Z1gv() + // CHECK: store i32 %[[CALL]], i32* @_ZZ1fvE1n, align 4 + // CHECK: store i8 1, i8* @_ZGVZ1fvE1n + // CHECK: br label + static thread_local int n = g(); + + // CHECK: load i32* @_ZZ1fvE1n, align 4 + return n; +} + +// CHECK: define {{.*}} @[[C_INIT:.*]]() +// CHECK: call i32* @_ZTW1b() +// CHECK-NEXT: load i32* %{{.*}}, align 4 +// CHECK-NEXT: store i32 %{{.*}}, i32* @c, align 4 + +// CHECK: define weak_odr hidden i32* @_ZTW1b() +// CHECK: br i1 icmp ne (void ()* @_ZTH1b, void ()* null), +// not null: +// CHECK: call void @_ZTH1b() +// CHECK: br label +// finally: +// CHECK: ret i32* @b + +// CHECK: define {{.*}} @[[D_INIT:.*]]() +// CHECK: call i32 @_Z1gv() +// CHECK-NEXT: store i32 %{{.*}}, i32* @_ZL1d, align 4 + +// CHECK: define {{.*}} @[[U_M_INIT:.*]]() +// CHECK: call i32 @_Z1fv() +// CHECK-NEXT: store i32 %{{.*}}, i32* @_ZN1U1mE, align 4 + +// CHECK: define {{.*}} @[[E_INIT:.*]]() +// CHECK: call i32* @_ZTWN1VIiE1mE() +// CHECK-NEXT: load i32* %{{.*}}, align 4 +// CHECK-NEXT: store i32 %{{.*}}, i32* @e, align 4 + +// CHECK: define weak_odr hidden i32* @_ZTWN1VIiE1mE() +// CHECK: call void @_ZTHN1VIiE1mE() +// CHECK: ret i32* @_ZN1VIiE1mE + + +struct S { S(); ~S(); }; +struct T { ~T(); }; + +// CHECK: define void @_Z8tls_dtorv() +void tls_dtor() { + // CHECK: load i8* @_ZGVZ8tls_dtorvE1s + // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZZ8tls_dtorvE1s) + // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZZ8tls_dtorvE1s{{.*}} @__dso_handle + // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1s + static thread_local S s; + + // CHECK: load i8* @_ZGVZ8tls_dtorvE1t + // CHECK-NOT: _ZN1T + // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1TD1Ev {{.*}}@_ZZ8tls_dtorvE1t{{.*}} @__dso_handle + // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1t + static thread_local T t; + + // CHECK: load i8* @_ZGVZ8tls_dtorvE1u + // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZGRZ8tls_dtorvE1u) + // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZGRZ8tls_dtorvE1u{{.*}} @__dso_handle + // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1u + static thread_local const S &u = S(); +} + +// CHECK: declare i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*) + +// CHECK: define {{.*}} @[[V_M_INIT:.*]]() +// CHECK: load i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*) +// CHECK: %[[V_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0 +// CHECK: br i1 %[[V_M_INITIALIZED]], +// need init: +// CHECK: call i32 @_Z1gv() +// CHECK: store i32 %{{.*}}, i32* @_ZN1VIiE1mE, align 4 +// CHECK: store i64 1, i64* @_ZGVN1VIiE1mE +// CHECK: br label + +// CHECK: define {{.*}}@[[GLOBAL_INIT:.*]]() +// CHECK: call void @[[C_INIT]]() +// CHECK: call void @[[E_INIT]]() + + +// CHECK: define {{.*}}@__tls_init() +// CHECK: load i8* @__tls_guard +// CHECK: %[[NEED_TLS_INIT:.*]] = icmp eq i8 %{{.*}}, 0 +// CHECK: store i8 1, i8* @__tls_guard +// CHECK: br i1 %[[NEED_TLS_INIT]], +// init: +// CHECK: call void @[[A_INIT]]() +// CHECK: call void @[[D_INIT]]() +// CHECK: call void @[[U_M_INIT]]() +// CHECK: call void @[[V_M_INIT]]() + + +// CHECK: define weak_odr hidden i32* @_ZTW1a() { +// CHECK: call void @_ZTH1a() +// CHECK: ret i32* @a +// CHECK: } + + +// CHECK: declare extern_weak void @_ZTH1b() + + +// CHECK: define internal hidden i32* @_ZTWL1d() +// CHECK: call void @_ZTHL1d() +// CHECK: ret i32* @_ZL1d + +// CHECK: define weak_odr hidden i32* @_ZTWN1U1mE() +// CHECK: call void @_ZTHN1U1mE() +// CHECK: ret i32* @_ZN1U1mE diff --git a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp new file mode 100644 index 0000000..ef78c43 --- /dev/null +++ b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -std=c++1y %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s + +struct A { + int n = 0; + const char *p; + char k = p[n]; + int f(); + int x = f(); + union { + char c; + double d = 1.0; + }; +}; + +int f(); + +union B { + int a; + int f(); + int b = f(); +}; + +A a { .p = "foobar" }; +A b { 4, "bazquux", .x = 42, .c = 9 }; +A c { 1, 0, 'A', f(), { 3 } }; + +// CHECK: @[[STR_A:.*]] = {{.*}} [7 x i8] c"foobar\00" +// CHECK: @[[STR_B:.*]] = {{.*}} [8 x i8] c"bazquux\00" + +B x; +B y {}; +B z { 1 }; +// CHECK: @z = global {{.*}} { i32 1 } + +// Initialization of 'a': + +// CHECK: store i32 0, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0) +// CHECK: store i8* {{.*}} @[[STR_A]]{{.*}}, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1) +// CHECK: load i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0) +// CHECK: load i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1) +// CHECK: getelementptr inbounds i8* %{{.*}}, {{.*}} %{{.*}} +// CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @a, i32 0, i32 2) +// CHECK: call i32 @_ZN1A1fEv({{.*}} @a) +// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}* @a, i32 0, i32 3) +// CHECK: call void @{{.*}}C1Ev({{.*}} getelementptr inbounds (%struct.A* @a, i32 0, i32 4)) + +// Initialization of 'b': + +// CHECK: store i32 4, i32* getelementptr inbounds ({{.*}} @b, i32 0, i32 0) +// CHECK: store i8* {{.*}} @[[STR_B]]{{.*}}, i8** getelementptr inbounds ({{.*}} @b, i32 0, i32 1) +// CHECK: load i32* getelementptr inbounds ({{.*}} @b, i32 0, i32 0) +// CHECK: load i8** getelementptr inbounds ({{.*}} @b, i32 0, i32 1) +// CHECK: getelementptr inbounds i8* %{{.*}}, {{.*}} %{{.*}} +// CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @b, i32 0, i32 2) +// CHECK-NOT: @_ZN1A1fEv +// CHECK: store i32 42, i32* getelementptr inbounds ({{.*}}* @b, i32 0, i32 3) +// CHECK-NOT: C1Ev +// CHECK: store i8 9, i8* {{.*}} @b, i32 0, i32 4) + +// Initialization of 'c': + +// CHECK: store i32 1, i32* getelementptr inbounds ({{.*}} @c, i32 0, i32 0) +// CHECK: store i8* null, i8** getelementptr inbounds ({{.*}} @c, i32 0, i32 1) +// CHECK-NOT: load +// CHECK: store i8 65, i8* getelementptr inbounds ({{.*}} @c, i32 0, i32 2) +// CHECK: call i32 @_Z1fv() +// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}* @c, i32 0, i32 3) +// CHECK-NOT: C1Ev +// CHECK: store i8 3, i8* {{.*}} @c, i32 0, i32 4) + +// CHECK: call void @_ZN1BC1Ev({{.*}} @x) + +// CHECK: call i32 @_ZN1B1fEv({{.*}} @y) +// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}} @y, i32 0, i32 0) diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp index 262e996..13a7914 100644 --- a/test/CodeGenCXX/debug-info-namespace.cpp +++ b/test/CodeGenCXX/debug-info-namespace.cpp @@ -5,13 +5,33 @@ namespace A { namespace B { int i; } +using namespace B; } +using namespace A; + +int func(bool b) { + if (b) { + using namespace A::B; + return i; + } + using namespace A; + return B::i; +} + +// CHECK: [[CU:![0-9]*]] = {{.*}}[[MODULES:![0-9]*]], metadata !""} ; [ DW_TAG_compile_unit ] // CHECK: [[FILE:![0-9]*]] {{.*}}debug-info-namespace.cpp" +// CHECK: [[FUNC:![0-9]*]] {{.*}} ; [ DW_TAG_subprogram ] [line 9] [def] [func] +// CHECK: [[FILE2:![0-9]*]]} ; [ DW_TAG_file_type ] [{{.*}}foo.cpp] // CHECK: [[VAR:![0-9]*]] = {{.*}}, metadata [[NS:![0-9]*]], metadata !"i", {{.*}} ; [ DW_TAG_variable ] [i] -// CHECK: [[NS]] = {{.*}}, metadata [[FILE2:![0-9]*]], metadata [[CTXT:![0-9]*]], {{.*}} ; [ DW_TAG_namespace ] [B] [line 1] +// CHECK: [[NS]] = {{.*}}, metadata [[FILE2]], metadata [[CTXT:![0-9]*]], {{.*}} ; [ DW_TAG_namespace ] [B] [line 1] // CHECK: [[CTXT]] = {{.*}}, metadata [[FILE]], null, {{.*}} ; [ DW_TAG_namespace ] [A] [line 3] -// CHECK: [[FILE2]]} ; [ DW_TAG_file_type ] [{{.*}}foo.cpp] +// CHECK: [[MODULES]] = metadata !{metadata [[M1:![0-9]*]], metadata [[M2:![0-9]*]], metadata [[M3:![0-9]*]], metadata [[M4:![0-9]*]]} +// CHECK: [[M1]] = metadata !{i32 {{[0-9]*}}, metadata [[CTXT]], metadata [[NS]], i32 4} ; [ DW_TAG_imported_module ] +// CHECK: [[M2]] = metadata !{i32 {{[0-9]*}}, metadata [[CU]], metadata [[CTXT]], i32 7} ; [ DW_TAG_imported_module ] +// CHECK: [[M3]] = metadata !{i32 {{[0-9]*}}, metadata [[LEX:![0-9]*]], metadata [[NS]], i32 11} ; [ DW_TAG_imported_module ] +// CHECK: [[LEX]] = metadata !{i32 {{[0-9]*}}, metadata [[FILE2]], metadata [[FUNC]], i32 10, i32 0, i32 0} ; [ DW_TAG_lexical_block ] +// CHECK: [[M4]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[CTXT]], i32 14} ; [ DW_TAG_imported_module ] // FIXME: It is confused on win32 to generate file entry when dosish filename is given. // REQUIRES: shell diff --git a/test/CodeGenCXX/extern-c.cpp b/test/CodeGenCXX/extern-c.cpp index a8c4f0c..5899b93 100644 --- a/test/CodeGenCXX/extern-c.cpp +++ b/test/CodeGenCXX/extern-c.cpp @@ -36,3 +36,30 @@ namespace test2 { extern "C" X test2_b; X test2_b; } + +extern "C" { + static int unused_var; + static int unused_fn() { return 0; } + + __attribute__((used)) static int internal_var; + __attribute__((used)) static int internal_fn() { return 0; } + + __attribute__((used)) static int duplicate_internal_var; + __attribute__((used)) static int duplicate_internal_fn() { return 0; } + + namespace N { + __attribute__((used)) static int duplicate_internal_var; + __attribute__((used)) static int duplicate_internal_fn() { return 0; } + } + + // CHECK: @llvm.used = appending global {{.*}} @internal_var {{.*}} @internal_fn + + // CHECK-NOT: @unused + // CHECK-NOT: @duplicate_internal + // CHECK: @internal_var = alias internal i32* @_Z12internal_var + // CHECK-NOT: @unused + // CHECK-NOT: @duplicate_internal + // CHECK: @internal_fn = alias internal i32 ()* @_Z11internal_fnv + // CHECK-NOT: @unused + // CHECK-NOT: @duplicate_internal +} diff --git a/test/CodeGenCXX/inheriting-constructor.cpp b/test/CodeGenCXX/inheriting-constructor.cpp index adb9f6d..0f39784 100644 --- a/test/CodeGenCXX/inheriting-constructor.cpp +++ b/test/CodeGenCXX/inheriting-constructor.cpp @@ -7,6 +7,10 @@ B::~B() {} B b(123); +struct C { template<typename T> C(T); }; +struct D : C { using C::C; }; +D d(123); + // CHECK: define void @_ZN1BD0Ev // CHECK: define void @_ZN1BD1Ev // CHECK: define void @_ZN1BD2Ev @@ -14,5 +18,11 @@ B b(123); // CHECK: define linkonce_odr void @_ZN1BC1Ei( // CHECK: call void @_ZN1BC2Ei( +// CHECK: define linkonce_odr void @_ZN1DC1IiEET_( +// CHECK: call void @_ZN1DC2IiEET_( + +// CHECK: define linkonce_odr void @_ZN1DC2IiEET_( +// CHECK: call void @_ZN1CC2IiEET_( + // CHECK: define linkonce_odr void @_ZN1BC2Ei( // CHECK: call void @_ZN1AC2Ei( diff --git a/test/CodeGenCXX/linetable-cleanup.cpp b/test/CodeGenCXX/linetable-cleanup.cpp new file mode 100644 index 0000000..4077af6 --- /dev/null +++ b/test/CodeGenCXX/linetable-cleanup.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin10 %s -o - | FileCheck %s + +// Check the line numbers for cleanup code with EH in combinatin with +// simple return expressions. + +// CHECK: define {{.*}}foo +// CHECK: call void @_ZN1CD1Ev(%class.C* {{.*}}), !dbg ![[CLEANUP:[0-9]+]] +// CHECK: ret i32 0, !dbg ![[RET:[0-9]+]] + +class C { +public: + ~C() {} + int i; +}; + +int foo() +{ + C c; + c.i = 42; + // This breakpoint should be at/before the cleanup code. + // CHECK: ![[CLEANUP]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + return 0; + // CHECK: ![[RET]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} +} diff --git a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp index 0ac9b3f..d03ba52 100644 --- a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp +++ b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp @@ -60,6 +60,51 @@ void foo_pcrbd(const char * volatile* x) {} void foo_pcrcd(volatile char * volatile* x) {} // CHECK: "\01?foo_pcrcd@@YAXPCRCD@Z" +void foo_aad(char &x) {} +// CHECK: "\01?foo_aad@@YAXAAD@Z" + +void foo_abd(const char &x) {} +// CHECK: "\01?foo_abd@@YAXABD@Z" + +void foo_aapad(char *&x) {} +// CHECK: "\01?foo_aapad@@YAXAAPAD@Z" + +void foo_aapbd(const char *&x) {} +// CHECK: "\01?foo_aapbd@@YAXAAPBD@Z" + +void foo_abqad(char * const &x) {} +// CHECK: "\01?foo_abqad@@YAXABQAD@Z" + +void foo_abqbd(const char * const &x) {} +// CHECK: "\01?foo_abqbd@@YAXABQBD@Z" + +void foo_aay144h(int (&x)[5][5]) {} +// CHECK: "\01?foo_aay144h@@YAXAAY144H@Z" + +void foo_aay144cbh(const int (&x)[5][5]) {} +// CHECK: "\01?foo_aay144cbh@@YAXAAY144$$CBH@Z" + +void foo_qay144h(int (&&x)[5][5]) {} +// CHECK: "\01?foo_qay144h@@YAX$$QAY144H@Z" + +void foo_qay144cbh(const int (&&x)[5][5]) {} +// CHECK: "\01?foo_qay144cbh@@YAX$$QAY144$$CBH@Z" + +void foo_p6ahxz(int x()) {} +// CHECK: "\01?foo_p6ahxz@@YAXP6AHXZ@Z" + +void foo_a6ahxz(int (&x)()) {} +// CHECK: "\01?foo_a6ahxz@@YAXA6AHXZ@Z" + +void foo_q6ahxz(int (&&x)()) {} +// CHECK: "\01?foo_q6ahxz@@YAX$$Q6AHXZ@Z" + +void foo_qay04h(int x[5][5]) {} +// CHECK: "\01?foo_qay04h@@YAXQAY04H@Z" + +void foo_qay04cbh(const int x[5][5]) {} +// CHECK: "\01?foo_qay04cbh@@YAXQAY04$$CBH@Z" + typedef double Vector[3]; void foo(Vector*) {} diff --git a/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp index 63bc4a9..87e04c6 100644 --- a/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp +++ b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp @@ -155,6 +155,15 @@ const volatile struct S* f5() { return 0; } struct S& f6() { return *(struct S*)0; } // CHECK: "\01?f6@@YAAAUS@@XZ" +struct S* const f7() { return 0; } +// CHECK: "\01?f7@@YAQAUS@@XZ" + +int S::* f8() { return 0; } +// CHECK: "\01?f8@@YAPQS@@HXZ" + +int S::* const f9() { return 0; } +// CHECK: "\01?f9@@YAQQS@@HXZ" + typedef int (*function_pointer)(int); function_pointer g1() { return 0; } diff --git a/test/CodeGenCXX/mangle-ms-templates.cpp b/test/CodeGenCXX/mangle-ms-templates.cpp index d0e8af4..10e6824 100644 --- a/test/CodeGenCXX/mangle-ms-templates.cpp +++ b/test/CodeGenCXX/mangle-ms-templates.cpp @@ -3,7 +3,7 @@ template<typename T> class Class { public: - void method() {} + Class() {} }; class Typename { }; @@ -32,12 +32,30 @@ class BoolTemplate<true> { void template_mangling() { Class<Typename> c1; - c1.method(); -// CHECK: call {{.*}} @"\01?method@?$Class@VTypename@@@@QAEXXZ" +// CHECK: call {{.*}} @"\01??0?$Class@VTypename@@@@QAE@XZ" + + Class<const Typename> c1_const; +// CHECK: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QAE@XZ" + Class<volatile Typename> c1_volatile; +// CHECK: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QAE@XZ" + Class<const volatile Typename> c1_cv; +// CHECK: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QAE@XZ" Class<Nested<Typename> > c2; - c2.method(); -// CHECK: call {{.*}} @"\01?method@?$Class@V?$Nested@VTypename@@@@@@QAEXXZ" +// CHECK: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QAE@XZ" + + Class<int * const> c_intpc; +// CHECK: call {{.*}} @"\01??0?$Class@QAH@@QAE@XZ" + Class<int()> c_ft; +// CHECK: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QAE@XZ" + Class<int[]> c_inti; +// CHECK: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QAE@XZ" + Class<int[5]> c_int5; +// CHECK: call {{.*}} @"\01??0?$Class@$$BY04H@@QAE@XZ" + Class<const int[5]> c_intc5; +// CHECK: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QAE@XZ" + Class<int * const[5]> c_intpc5; +// CHECK: call {{.*}} @"\01??0?$Class@$$BY04QAH@@QAE@XZ" BoolTemplate<false> _false; // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QAE@XZ" diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp index 6441d67..1b98a84 100644 --- a/test/CodeGenCXX/mangle-ms.cpp +++ b/test/CodeGenCXX/mangle-ms.cpp @@ -17,11 +17,8 @@ // CHECK: @"\01?l@@3P8foo@@AEHH@ZA" // CHECK: @"\01?color1@@3PANA" // CHECK: @"\01?color2@@3QBNB" - -// FIXME: The following three tests currently fail, see http://llvm.org/PR13182 -// Replace "CHECK-NOT" with "CHECK" when it is fixed. -// CHECK-NOT: @"\01?color3@@3QAY02$$CBNA" -// CHECK-NOT: @"\01?color4@@3QAY02$$CBNA" +// CHECK: @"\01?color3@@3QAY02$$CBNA" +// CHECK: @"\01?color4@@3QAY02$$CBNA" int a; diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp index 997e007..3fffc9d 100755 --- a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp +++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp @@ -1,10 +1,110 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s +// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s + +struct B1 { + void foo(); + int b; +}; +struct B2 { + void foo(); +}; +struct Single : B1 { + void foo(); +}; +struct Multiple : B1, B2 { + void foo(); +}; +struct Virtual : virtual B1 { + int v; + void foo(); +}; struct POD { int a; int b; }; +struct Polymorphic { + virtual void myVirtual(); + int a; + int b; +}; + +// This class uses the virtual inheritance model, yet its vbptr offset is not 0. +// We still use zero for the null field offset, despite it being a valid field +// offset. +struct NonZeroVBPtr : POD, Virtual { + int n; +}; + +struct Unspecified; + +// Check that we can lower the LLVM types and get the null initializers right. +int Single ::*s_d_memptr; +int Polymorphic::*p_d_memptr; +int Multiple ::*m_d_memptr; +int Virtual ::*v_d_memptr; +int NonZeroVBPtr::*n_d_memptr; +int Unspecified::*u_d_memptr; +// CHECK: @"\01?s_d_memptr@@3PQSingle@@HA" = global i32 -1, align 4 +// CHECK: @"\01?p_d_memptr@@3PQPolymorphic@@HA" = global i32 0, align 4 +// CHECK: @"\01?m_d_memptr@@3PQMultiple@@HA" = global i32 -1, align 4 +// CHECK: @"\01?v_d_memptr@@3PQVirtual@@HA" = global { i32, i32 } +// CHECK: { i32 0, i32 -1 }, align 4 +// CHECK: @"\01?n_d_memptr@@3PQNonZeroVBPtr@@HA" = global { i32, i32 } +// CHECK: { i32 0, i32 -1 }, align 4 +// CHECK: @"\01?u_d_memptr@@3PQUnspecified@@HA" = global { i32, i32, i32 } +// CHECK: { i32 0, i32 0, i32 -1 }, align 4 + +void (Single ::*s_f_memptr)(); +void (Multiple::*m_f_memptr)(); +void (Virtual ::*v_f_memptr)(); +// CHECK: @"\01?s_f_memptr@@3P8Single@@AEXXZA" = global i8* null, align 4 +// CHECK: @"\01?m_f_memptr@@3P8Multiple@@AEXXZA" = global { i8*, i32 } zeroinitializer, align 4 +// CHECK: @"\01?v_f_memptr@@3P8Virtual@@AEXXZA" = global { i8*, i32, i32 } zeroinitializer, align 4 + +// We can define Unspecified after locking in the inheritance model. +struct Unspecified : Virtual { + void foo(); + int u; +}; + +struct UnspecWithVBPtr; +int UnspecWithVBPtr::*forceUnspecWithVBPtr; +struct UnspecWithVBPtr : B1, virtual B2 { + int u; + void foo(); +}; + +// Test emitting non-virtual member pointers in a non-constexpr setting. +void EmitNonVirtualMemberPointers() { + void (Single ::*s_f_memptr)() = &Single::foo; + void (Multiple ::*m_f_memptr)() = &Multiple::foo; + void (Virtual ::*v_f_memptr)() = &Virtual::foo; + void (Unspecified::*u_f_memptr)() = &Unspecified::foo; + void (UnspecWithVBPtr::*u2_f_memptr)() = &UnspecWithVBPtr::foo; +// CHECK: define void @"\01?EmitNonVirtualMemberPointers@@YAXXZ"() #0 { +// CHECK: alloca i8*, align 4 +// CHECK: alloca { i8*, i32 }, align 4 +// CHECK: alloca { i8*, i32, i32 }, align 4 +// CHECK: alloca { i8*, i32, i32, i32 }, align 4 +// CHECK: store i8* bitcast (void (%{{.*}}*)* @"\01?foo@Single@@QAEXXZ" to i8*), i8** %{{.*}}, align 4 +// CHECK: store { i8*, i32 } +// CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Multiple@@QAEXXZ" to i8*), i32 0 }, +// CHECK: { i8*, i32 }* %{{.*}}, align 4 +// CHECK: store { i8*, i32, i32 } +// CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, +// CHECK: { i8*, i32, i32 }* %{{.*}}, align 4 +// CHECK: store { i8*, i32, i32, i32 } +// CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, +// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4 +// CHECK: store { i8*, i32, i32, i32 } +// CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@UnspecWithVBPtr@@QAEXXZ" to i8*), +// CHECK: i32 0, i32 4, i32 0 }, +// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4 +// CHECK: ret void +// CHECK: } +} + void podMemPtrs() { int POD::*memptr; memptr = &POD::a; @@ -24,12 +124,6 @@ void podMemPtrs() { // CHECK: } } -struct Polymorphic { - virtual void myVirtual(); - int a; - int b; -}; - void polymorphicMemPtrs() { int Polymorphic::*memptr; memptr = &Polymorphic::a; @@ -49,3 +143,221 @@ void polymorphicMemPtrs() { // CHECK: ret void // CHECK: } } + +bool nullTestDataUnspecified(int Unspecified::*mp) { + return mp; +// CHECK: define zeroext i1 @"\01?nullTestDataUnspecified@@YA_NPQUnspecified@@H@Z"{{.*}} { +// CHECK: %{{.*}} = load { i32, i32, i32 }* %{{.*}}, align 4 +// CHECK: store { i32, i32, i32 } {{.*}} align 4 +// CHECK: %[[mp:.*]] = load { i32, i32, i32 }* %{{.*}}, align 4 +// CHECK: %[[mp0:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 0 +// CHECK: %[[cmp0:.*]] = icmp ne i32 %[[mp0]], 0 +// CHECK: %[[mp1:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 1 +// CHECK: %[[cmp1:.*]] = icmp ne i32 %[[mp1]], 0 +// CHECK: %[[and0:.*]] = and i1 %[[cmp0]], %[[cmp1]] +// CHECK: %[[mp2:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 2 +// CHECK: %[[cmp2:.*]] = icmp ne i32 %[[mp2]], -1 +// CHECK: %[[and1:.*]] = and i1 %[[and0]], %[[cmp2]] +// CHECK: ret i1 %[[and1]] +// CHECK: } +} + +bool nullTestFunctionUnspecified(void (Unspecified::*mp)()) { + return mp; +// CHECK: define zeroext i1 @"\01?nullTestFunctionUnspecified@@YA_NP8Unspecified@@AEXXZ@Z"{{.*}} { +// CHECK: %{{.*}} = load { i8*, i32, i32, i32 }* %{{.*}}, align 4 +// CHECK: store { i8*, i32, i32, i32 } {{.*}} align 4 +// CHECK: %[[mp:.*]] = load { i8*, i32, i32, i32 }* %{{.*}}, align 4 +// CHECK: %[[mp0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[mp]], 0 +// CHECK: %[[cmp0:.*]] = icmp ne i8* %[[mp0]], null +// CHECK: ret i1 %[[cmp0]] +// CHECK: } +} + +int loadDataMemberPointerVirtual(Virtual *o, int Virtual::*memptr) { + return o->*memptr; +// Test that we can unpack this aggregate member pointer and load the member +// data pointer. +// CHECK: define i32 @"\01?loadDataMemberPointerVirtual@@YAHPAUVirtual@@PQ1@H@Z"{{.*}} { +// CHECK: %[[o:.*]] = load %{{.*}}** %{{.*}}, align 4 +// CHECK: %[[memptr:.*]] = load { i32, i32 }* %{{.*}}, align 4 +// CHECK: %[[memptr0:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 0 +// CHECK: %[[memptr1:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 1 +// CHECK: %[[v6:.*]] = bitcast %{{.*}}* %[[o]] to i8* +// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8* %[[v6]], i32 0 +// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8** +// CHECK: %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]] +// CHECK: %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr1]] +// CHECK: %[[v8:.*]] = bitcast i8* %[[v7]] to i32* +// CHECK: %[[vbase_offs:.*]] = load i32* %[[v8]] +// CHECK: %[[v10:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]] +// CHECK: %[[offset:.*]] = getelementptr inbounds i8* %[[v10]], i32 %[[memptr0]] +// CHECK: %[[v11:.*]] = bitcast i8* %[[offset]] to i32* +// CHECK: %[[v12:.*]] = load i32* %[[v11]] +// CHECK: ret i32 %[[v12]] +// CHECK: } +} + +int loadDataMemberPointerUnspecified(Unspecified *o, int Unspecified::*memptr) { + return o->*memptr; +// Test that we can unpack this aggregate member pointer and load the member +// data pointer. +// CHECK: define i32 @"\01?loadDataMemberPointerUnspecified@@YAHPAUUnspecified@@PQ1@H@Z"{{.*}} { +// CHECK: %[[o:.*]] = load %{{.*}}** %{{.*}}, align 4 +// CHECK: %[[memptr:.*]] = load { i32, i32, i32 }* %{{.*}}, align 4 +// CHECK: %[[memptr0:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 0 +// CHECK: %[[memptr1:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 1 +// CHECK: %[[memptr2:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 2 +// CHECK: %[[base:.*]] = bitcast %{{.*}}* %[[o]] to i8* +// CHECK: %[[is_vbase:.*]] = icmp ne i32 %[[memptr2]], 0 +// CHECK: br i1 %[[is_vbase]], label %[[vadjust:.*]], label %[[skip:.*]] +// +// CHECK: [[vadjust]] +// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8* %[[base]], i32 %[[memptr1]] +// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8** +// CHECK: %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]] +// CHECK: %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr2]] +// CHECK: %[[v8:.*]] = bitcast i8* %[[v7]] to i32* +// CHECK: %[[vbase_offs:.*]] = load i32* %[[v8]] +// CHECK: %[[base_adj:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]] +// +// CHECK: [[skip]] +// CHECK: %[[new_base:.*]] = phi i8* [ %[[base]], %{{.*}} ], [ %[[base_adj]], %[[vadjust]] ] +// CHECK: %[[offset:.*]] = getelementptr inbounds i8* %[[new_base]], i32 %[[memptr0]] +// CHECK: %[[v11:.*]] = bitcast i8* %[[offset]] to i32* +// CHECK: %[[v12:.*]] = load i32* %[[v11]] +// CHECK: ret i32 %[[v12]] +// CHECK: } +} + +void callMemberPointerSingle(Single *o, void (Single::*memptr)()) { + (o->*memptr)(); +// Just look for an indirect thiscall. +// CHECK: define void @"\01?callMemberPointerSingle@@{{.*}} #0 { +// CHECK: call x86_thiscallcc void %{{.*}}(%{{.*}} %{{.*}}) +// CHECK: ret void +// CHECK: } +} + +void callMemberPointerMultiple(Multiple *o, void (Multiple::*memptr)()) { + (o->*memptr)(); +// CHECK: define void @"\01?callMemberPointerMultiple@@{{.*}} #0 { +// CHECK: %[[memptr0:.*]] = extractvalue { i8*, i32 } %{{.*}}, 0 +// CHECK: %[[memptr1:.*]] = extractvalue { i8*, i32 } %{{.*}}, 1 +// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8* %{{.*}}, i32 %[[memptr1]] +// CHECK: %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}} +// CHECK: %[[fptr:.*]] = bitcast i8* %[[memptr0]] to {{.*}} +// CHECK: call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]]) +// CHECK: ret void +// CHECK: } +} + +void callMemberPointerVirtualBase(Virtual *o, void (Virtual::*memptr)()) { + (o->*memptr)(); +// This shares a lot with virtual data member pointers. +// CHECK: define void @"\01?callMemberPointerVirtualBase@@{{.*}} #0 { +// CHECK: %[[memptr0:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 0 +// CHECK: %[[memptr1:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 1 +// CHECK: %[[memptr2:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 2 +// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8* %{{.*}}, i32 0 +// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8** +// CHECK: %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]] +// CHECK: %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr2]] +// CHECK: %[[v8:.*]] = bitcast i8* %[[v7]] to i32* +// CHECK: %[[vbase_offs:.*]] = load i32* %[[v8]] +// CHECK: %[[v10:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]] +// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8* %[[v10]], i32 %[[memptr1]] +// CHECK: %[[fptr:.*]] = bitcast i8* %[[memptr0]] to void ({{.*}}) +// CHECK: %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}} +// CHECK: call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]]) +// CHECK: ret void +// CHECK: } +} + +bool compareSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) { + return l == r; +// Should only be one comparison here. +// CHECK: define zeroext i1 @"\01?compareSingleFunctionMemptr@@YA_NP8Single@@AEXXZ0@Z"{{.*}} { +// CHECK-NOT: icmp +// CHECK: %[[r:.*]] = icmp eq +// CHECK-NOT: icmp +// CHECK: ret i1 %[[r]] +// CHECK: } +} + +bool compareNeqSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) { + return l != r; +// Should only be one comparison here. +// CHECK: define zeroext i1 @"\01?compareNeqSingleFunctionMemptr@@YA_NP8Single@@AEXXZ0@Z"{{.*}} { +// CHECK-NOT: icmp +// CHECK: %[[r:.*]] = icmp ne +// CHECK-NOT: icmp +// CHECK: ret i1 %[[r]] +// CHECK: } +} + +bool unspecFuncMemptrEq(void (Unspecified::*l)(), void (Unspecified::*r)()) { + return l == r; +// CHECK: define zeroext i1 @"\01?unspecFuncMemptrEq@@YA_NP8Unspecified@@AEXXZ0@Z"{{.*}} { +// CHECK: %[[lhs0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[l:.*]], 0 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r:.*]], 0 +// CHECK: %[[cmp0:.*]] = icmp eq i8* %[[lhs0]], %{{.*}} +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 1 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 1 +// CHECK: %[[cmp1:.*]] = icmp eq i32 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 2 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 2 +// CHECK: %[[cmp2:.*]] = icmp eq i32 +// CHECK: %[[res12:.*]] = and i1 %[[cmp1]], %[[cmp2]] +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 3 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 3 +// CHECK: %[[cmp3:.*]] = icmp eq i32 +// CHECK: %[[res123:.*]] = and i1 %[[res12]], %[[cmp3]] +// CHECK: %[[iszero:.*]] = icmp eq i8* %[[lhs0]], null +// CHECK: %[[bits_or_null:.*]] = or i1 %[[res123]], %[[iszero]] +// CHECK: %{{.*}} = and i1 %[[bits_or_null]], %[[cmp0]] +// CHECK: ret i1 %{{.*}} +// CHECK: } +} + +bool unspecFuncMemptrNeq(void (Unspecified::*l)(), void (Unspecified::*r)()) { + return l != r; +// CHECK: define zeroext i1 @"\01?unspecFuncMemptrNeq@@YA_NP8Unspecified@@AEXXZ0@Z"{{.*}} { +// CHECK: %[[lhs0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[l:.*]], 0 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r:.*]], 0 +// CHECK: %[[cmp0:.*]] = icmp ne i8* %[[lhs0]], %{{.*}} +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 1 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 1 +// CHECK: %[[cmp1:.*]] = icmp ne i32 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 2 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 2 +// CHECK: %[[cmp2:.*]] = icmp ne i32 +// CHECK: %[[res12:.*]] = or i1 %[[cmp1]], %[[cmp2]] +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 3 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 3 +// CHECK: %[[cmp3:.*]] = icmp ne i32 +// CHECK: %[[res123:.*]] = or i1 %[[res12]], %[[cmp3]] +// CHECK: %[[iszero:.*]] = icmp ne i8* %[[lhs0]], null +// CHECK: %[[bits_or_null:.*]] = and i1 %[[res123]], %[[iszero]] +// CHECK: %{{.*}} = or i1 %[[bits_or_null]], %[[cmp0]] +// CHECK: ret i1 %{{.*}} +// CHECK: } +} + +bool unspecDataMemptrEq(int Unspecified::*l, int Unspecified::*r) { + return l == r; +// CHECK: define zeroext i1 @"\01?unspecDataMemptrEq@@YA_NPQUnspecified@@H0@Z"{{.*}} { +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 0 +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 0 +// CHECK: icmp eq i32 +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 1 +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 1 +// CHECK: icmp eq i32 +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 2 +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 2 +// CHECK: icmp eq i32 +// CHECK: and i1 +// CHECK: and i1 +// CHECK: ret i1 +// CHECK: } +} diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp new file mode 100644 index 0000000..060c172 --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp @@ -0,0 +1,169 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-linux | FileCheck -check-prefix LINUX %s +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -cxx-abi microsoft | FileCheck -check-prefix WIN32 %s +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 -cxx-abi microsoft | FileCheck -check-prefix WIN64 %s + +struct Empty {}; + +struct EmptyWithCtor { + EmptyWithCtor() {} +}; + +struct Small { + int x; +}; + +// This is a C++11 trivial and standard-layout struct but not a C++03 POD. +struct SmallCpp11NotCpp03Pod : Empty { + int x; +}; + +struct SmallWithCtor { + SmallWithCtor() {} + int x; +}; + +struct SmallWithVftable { + int x; + virtual void foo(); +}; + +struct Medium { + int x, y; +}; + +struct MediumWithCopyCtor { + MediumWithCopyCtor(); + MediumWithCopyCtor(const struct MediumWithCopyCtor &); + int x, y; +}; + +struct Big { + int a, b, c, d, e, f; +}; + +// Returning structs that fit into a register. +Small small_return() { return Small(); } +// LINUX: define void @_Z12small_returnv(%struct.Small* noalias sret %agg.result) +// WIN32: define i32 @"\01?small_return@@YA?AUSmall@@XZ"() +// WIN64: define i32 @"\01?small_return@@YA?AUSmall@@XZ"() + +Medium medium_return() { return Medium(); } +// LINUX: define void @_Z13medium_returnv(%struct.Medium* noalias sret %agg.result) +// WIN32: define i64 @"\01?medium_return@@YA?AUMedium@@XZ"() +// WIN64: define i64 @"\01?medium_return@@YA?AUMedium@@XZ"() + +// Returning structs that fit into a register but are not POD. +SmallCpp11NotCpp03Pod small_non_pod_return() { return SmallCpp11NotCpp03Pod(); } +// LINUX: define void @_Z20small_non_pod_returnv(%struct.SmallCpp11NotCpp03Pod* noalias sret %agg.result) +// WIN32: define void @"\01?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(%struct.SmallCpp11NotCpp03Pod* noalias sret %agg.result) +// WIN64: define void @"\01?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(%struct.SmallCpp11NotCpp03Pod* noalias sret %agg.result) + +SmallWithCtor small_with_ctor_return() { return SmallWithCtor(); } +// LINUX: define void @_Z22small_with_ctor_returnv(%struct.SmallWithCtor* noalias sret %agg.result) +// WIN32: define void @"\01?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result) +// WIN64: define void @"\01?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result) + +SmallWithVftable small_with_vftable_return() { return SmallWithVftable(); } +// LINUX: define void @_Z25small_with_vftable_returnv(%struct.SmallWithVftable* noalias sret %agg.result) +// WIN32: define void @"\01?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(%struct.SmallWithVftable* noalias sret %agg.result) +// WIN64: define void @"\01?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(%struct.SmallWithVftable* noalias sret %agg.result) + +MediumWithCopyCtor medium_with_copy_ctor_return() { return MediumWithCopyCtor(); } +// LINUX: define void @_Z28medium_with_copy_ctor_returnv(%struct.MediumWithCopyCtor* noalias sret %agg.result) +// WIN32: define void @"\01?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result) +// WIN64: define void @"\01?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result) + +// Returning a large struct that doesn't fit into a register. +Big big_return() { return Big(); } +// LINUX: define void @_Z10big_returnv(%struct.Big* noalias sret %agg.result) +// WIN32: define void @"\01?big_return@@YA?AUBig@@XZ"(%struct.Big* noalias sret %agg.result) +// WIN64: define void @"\01?big_return@@YA?AUBig@@XZ"(%struct.Big* noalias sret %agg.result) + + +void small_arg(Small s) {} +// LINUX: define void @_Z9small_arg5Small(%struct.Small* byval align 4 %s) +// WIN32: define void @"\01?small_arg@@YAXUSmall@@@Z"(%struct.Small* byval align 4 %s) +// WIN64: define void @"\01?small_arg@@YAXUSmall@@@Z"(i32 %s.coerce) + +void medium_arg(Medium s) {} +// LINUX: define void @_Z10medium_arg6Medium(%struct.Medium* byval align 4 %s) +// WIN32: define void @"\01?medium_arg@@YAXUMedium@@@Z"(%struct.Medium* byval align 4 %s) +// WIN64: define void @"\01?medium_arg@@YAXUMedium@@@Z"(i64 %s.coerce) + +void small_arg_with_ctor(SmallWithCtor s) {} +// LINUX: define void @_Z19small_arg_with_ctor13SmallWithCtor(%struct.SmallWithCtor* byval align 4 %s) +// WIN32: define void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(%struct.SmallWithCtor* byval align 4 %s) +// WIN64: define void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.coerce) + +void small_arg_with_vftable(SmallWithVftable s) {} +// LINUX: define void @_Z22small_arg_with_vftable16SmallWithVftable(%struct.SmallWithVftable* %s) +// WIN32: define void @"\01?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* byval align 4 %s) +// WIN64: define void @"\01?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* byval %s) + +void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {} +// LINUX: define void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* %s) +// WIN32: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* byval align 4 %s) +// WIN64: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* byval %s) + +void big_arg(Big s) {} +// LINUX: define void @_Z7big_arg3Big(%struct.Big* byval align 4 %s) +// WIN32: define void @"\01?big_arg@@YAXUBig@@@Z"(%struct.Big* byval align 4 %s) +// WIN64: define void @"\01?big_arg@@YAXUBig@@@Z"(%struct.Big* %s) + +// FIXME: Add WIN64 tests. Currently, even the method manglings are wrong (sic!). +class Class { + public: + Small thiscall_method_small() { return Small(); } + // LINUX: define {{.*}} void @_ZN5Class21thiscall_method_smallEv(%struct.Small* noalias sret %agg.result, %class.Class* %this) + // WIN32: define {{.*}} x86_thiscallcc void @"\01?thiscall_method_small@Class@@QAE?AUSmall@@XZ"(%struct.Small* noalias sret %agg.result, %class.Class* %this) + + SmallWithCtor thiscall_method_small_with_ctor() { return SmallWithCtor(); } + // LINUX: define {{.*}} void @_ZN5Class31thiscall_method_small_with_ctorEv(%struct.SmallWithCtor* noalias sret %agg.result, %class.Class* %this) + // WIN32: define {{.*}} x86_thiscallcc void @"\01?thiscall_method_small_with_ctor@Class@@QAE?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result, %class.Class* %this) + + Small __cdecl cdecl_method_small() { return Small(); } + // LINUX: define {{.*}} void @_ZN5Class18cdecl_method_smallEv(%struct.Small* noalias sret %agg.result, %class.Class* %this) + // FIXME: Interesting, cdecl returns structures differently for instance + // methods and global functions. This is not supported by Clang yet... + // FIXME: Replace WIN32-NOT with WIN32 when this is fixed. + // WIN32-NOT: define {{.*}} void @"\01?cdecl_method_small@Class@@QAA?AUSmall@@XZ"(%struct.Small* noalias sret %agg.result, %class.Class* %this) + + Big __cdecl cdecl_method_big() { return Big(); } + // LINUX: define {{.*}} void @_ZN5Class16cdecl_method_bigEv(%struct.Big* noalias sret %agg.result, %class.Class* %this) + // WIN32: define {{.*}} void @"\01?cdecl_method_big@Class@@QAA?AUBig@@XZ"(%struct.Big* noalias sret %agg.result, %class.Class* %this) + + void thiscall_method_arg(Empty s) {} + // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Empty(%class.Class* %this) + // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUEmpty@@@Z"(%class.Class* %this, %struct.Empty* byval align 4 %s) + + void thiscall_method_arg(EmptyWithCtor s) {} + // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13EmptyWithCtor(%class.Class* %this) + // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUEmptyWithCtor@@@Z"(%class.Class* %this, %struct.EmptyWithCtor* byval align 4 %s) + + void thiscall_method_arg(Small s) {} + // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Small(%class.Class* %this, %struct.Small* byval align 4 %s) + // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUSmall@@@Z"(%class.Class* %this, %struct.Small* byval align 4 %s) + + void thiscall_method_arg(SmallWithCtor s) {} + // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13SmallWithCtor(%class.Class* %this, %struct.SmallWithCtor* byval align 4 %s) + // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUSmallWithCtor@@@Z"(%class.Class* %this, %struct.SmallWithCtor* byval align 4 %s) + + void thiscall_method_arg(Big s) {} + // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE3Big(%class.Class* %this, %struct.Big* byval align 4 %s) + // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUBig@@@Z"(%class.Class* %this, %struct.Big* byval align 4 %s) +}; + +void use_class() { + Class c; + c.thiscall_method_small(); + c.thiscall_method_small_with_ctor(); + + c.cdecl_method_small(); + c.cdecl_method_big(); + + c.thiscall_method_arg(Empty()); + c.thiscall_method_arg(EmptyWithCtor()); + c.thiscall_method_arg(Small()); + c.thiscall_method_arg(SmallWithCtor()); + c.thiscall_method_arg(Big()); +} diff --git a/test/CodeGenCXX/pr15753.cpp b/test/CodeGenCXX/pr15753.cpp new file mode 100644 index 0000000..fd2000b --- /dev/null +++ b/test/CodeGenCXX/pr15753.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +template <typename T> static int Foo(T t); +template <typename T> +int Foo(T t) { + return t; +} +template<> int Foo<int>(int i) { + return i; +} + +// CHECK-NOT: define diff --git a/test/CodeGenCXX/scoped-enums-debug-info.cpp b/test/CodeGenCXX/scoped-enums-debug-info.cpp new file mode 100644 index 0000000..d3ef9f7 --- /dev/null +++ b/test/CodeGenCXX/scoped-enums-debug-info.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm -g -o - %s | FileCheck %s +// Test that we are emitting debug info and base types for scoped enums. + +// CHECK: [ DW_TAG_enumeration_type ] [Color] {{.*}} [from int] +enum class Color { gray }; + +void f(Color); +void g() { + f(Color::gray); +} + +// CHECK: [ DW_TAG_enumeration_type ] [Colour] {{.*}} [from int] +enum struct Colour { grey }; + +void h(Colour); +void i() { + h(Colour::grey); +} + +// CHECK: [ DW_TAG_enumeration_type ] [Couleur] {{.*}} [from unsigned char] +enum class Couleur : unsigned char { gris }; + +void j(Couleur); +void k() { + j(Couleur::gris); +} diff --git a/test/CodeGenCXX/scoped-enums.cpp b/test/CodeGenCXX/scoped-enums.cpp index fca0509..c20faaa 100644 --- a/test/CodeGenCXX/scoped-enums.cpp +++ b/test/CodeGenCXX/scoped-enums.cpp @@ -7,3 +7,11 @@ void f(Color); void g() { f(Color::red); } + +// See that struct is handled equally. +enum struct Colour { grey }; + +void h(Colour); +void i() { + h(Colour::grey); +} diff --git a/test/CodeGenCXX/throw-expressions.cpp b/test/CodeGenCXX/throw-expressions.cpp index f04185b..ba8a868 100644 --- a/test/CodeGenCXX/throw-expressions.cpp +++ b/test/CodeGenCXX/throw-expressions.cpp @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -emit-llvm-only -verify %s -Wno-unreachable-code -// expected-no-diagnostics +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -Wno-unreachable-code -Werror -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s int val = 42; int& test1() { @@ -19,3 +18,28 @@ void test3() { int test4() { return 1 ? throw val : val; } + +// PR15923 +int test5(bool x, bool y, int z) { + return (x ? throw 1 : y) ? z : throw 2; +} +// CHECK: define i32 @_Z5test5bbi( +// CHECK: br i1 +// +// x.true: +// CHECK: call void @__cxa_throw( +// CHECK-NEXT: unreachable +// +// x.false: +// CHECK: br i1 +// +// y.true: +// CHECK: load i32* +// CHECK: br label +// +// y.false: +// CHECK: call void @__cxa_throw( +// CHECK-NEXT: unreachable +// +// end: +// CHECK: ret i32 diff --git a/test/CodeGenCXX/tls-init-funcs.cpp b/test/CodeGenCXX/tls-init-funcs.cpp new file mode 100644 index 0000000..17299dc --- /dev/null +++ b/test/CodeGenCXX/tls-init-funcs.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.8 -std=c++11 -S -emit-llvm %s -o - | FileCheck %s + +// CHECK: @a = internal thread_local global +// CHECK: @_tlv_atexit({{.*}}@_ZN1AD1Ev + +struct A { + ~A(); +}; + +thread_local A a; diff --git a/test/CodeGenCXX/vtable-debug-info.cpp b/test/CodeGenCXX/vtable-debug-info.cpp index 9294d20..8710c76 100644 --- a/test/CodeGenCXX/vtable-debug-info.cpp +++ b/test/CodeGenCXX/vtable-debug-info.cpp @@ -1,4 +1,4 @@ -// RUN: %clang -c -g %s -o /dev/null +// RUN: %clang -emit-llvm -S -g %s -o /dev/null // Radar 8730409 // XFAIL: win32 diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m index 3281b2a..c9ba2f6 100644 --- a/test/CodeGenObjC/arc-blocks.m +++ b/test/CodeGenObjC/arc-blocks.m @@ -650,5 +650,44 @@ void test18(id x) { // CHECK-UNOPT-NEXT: ret void } +// rdar://13588325 +void test19_sink(void (^)(int)); +void test19(void (^b)(void)) { +// CHECK: define void @test19( +// Prologue. +// CHECK: [[B:%.*]] = alloca void ()*, +// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], +// CHECK-NEXT: [[T0:%.*]] = bitcast void ()* {{%.*}} to i8* +// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) +// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()* +// CHECK-NEXT: store void ()* [[T2]], void ()** [[B]] + +// Block setup. We skip most of this. Note the bare retain. +// CHECK-NEXT: [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 +// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 +// CHECK-NEXT: [[T0:%.*]] = load void ()** [[B]], +// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* +// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* +// CHECK-NEXT: store void ()* [[T3]], void ()** [[SLOT]], +// Call. +// CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void (i32)* +// CHECK-NEXT: call void @test19_sink(void (i32)* [[T0]]) + + test19_sink(^(int x) { b(); }); + +// Block teardown. +// CHECK-NEXT: [[T0:%.*]] = load void ()** [[SLOTREL]] +// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* +// CHECK-NEXT: call void @objc_release(i8* [[T1]]) + +// Local cleanup. +// CHECK-NEXT: [[T0:%.*]] = load void ()** [[B]] +// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* +// CHECK-NEXT: call void @objc_release(i8* [[T1]]) + +// CHECK-NEXT: ret void +} + // CHECK: attributes [[NUW]] = { nounwind } // CHECK-UNOPT: attributes [[NUW]] = { nounwind } diff --git a/test/CodeGenObjC/arc-linetable.m b/test/CodeGenObjC/arc-linetable.m new file mode 100644 index 0000000..eac91f1 --- /dev/null +++ b/test/CodeGenObjC/arc-linetable.m @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -emit-llvm -fblocks -fobjc-arc -g -triple x86_64-apple-darwin10 %s -o - | FileCheck %s + +// Legend: EXP = Return expression, RET = ret instruction + +// CHECK: define {{.*}}testNoSideEffect +// CHECK: call void @objc_storeStrong{{.*}} +// CHECK: call void @objc_storeStrong{{.*}} !dbg ![[ARC1:[0-9]+]] +// CHECK: ret {{.*}} !dbg ![[RET1:[0-9]+]] + +// CHECK: define {{.*}}testNoCleanup +// CHECK: ret {{.*}} !dbg ![[RET2:[0-9]+]] + +// CHECK: define {{.*}}testSideEffect +// CHECK: @objc_msgSend{{.*}} !dbg ![[MSG3:[0-9]+]] +// CHECK: ret {{.*}} !dbg ![[RET3:[0-9]+]] + +// CHECK: define {{.*}}testMultiline +// CHECK: @objc_msgSend{{.*}} !dbg ![[MSG4:[0-9]+]] +// CHECK: load{{.*}} !dbg ![[EXP4:[0-9]+]] +// CHECK: ret {{.*}} !dbg ![[RET4:[0-9]+]] + +// CHECK: define {{.*}}testVoid +// CHECK: call void @objc_storeStrong{{.*}} +// CHECK: call void @objc_storeStrong{{.*}} !dbg ![[ARC5:[0-9]+]] +// CHECK: ret {{.*}} !dbg ![[RET5:[0-9]+]] + +// CHECK: define {{.*}}testVoidNoReturn +// CHECK: @objc_msgSend{{.*}} !dbg ![[MSG6:[0-9]+]] +// CHECK: ret {{.*}} !dbg ![[RET6:[0-9]+]] + +// CHECK: define {{.*}}testNoCleanupSideEffect +// CHECK: @objc_msgSend{{.*}} !dbg ![[MSG7:[0-9]+]] +// CHECK: ret {{.*}} !dbg ![[RET7:[0-9]+]] + + +@interface NSObject ++ (id)alloc; +- (id)init; +- (id)retain; +@end + +@class NSString; + +@interface AppDelegate : NSObject + +@end + +@implementation AppDelegate : NSObject + +- (int)testNoSideEffect:(NSString *)foo { + // CHECK: ![[ARC1]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + return 1; // Return expression + // CHECK: ![[RET1]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} +} // Cleanup + Ret + +- (int)testNoCleanup { + // CHECK: ![[RET2]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + return 1; +} + +- (int)testSideEffect:(NSString *)foo { + // CHECK: ![[MSG3]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + return [self testNoSideEffect :foo]; + // CHECK: ![[RET3]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} +} + +- (int)testMultiline:(NSString *)foo { + // CHECK: ![[MSG4]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + int r = [self testSideEffect :foo]; + // CHECK: ![[EXP4]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + return r; + // CHECK: ![[RET4]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} +} + +- (void)testVoid:(NSString *)foo { + // CHECK: ![[ARC5]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + return; + // CHECK: ![[RET5]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} +} + +- (void)testVoidNoReturn:(NSString *)foo { + // CHECK: ![[MSG6]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + [self testVoid :foo]; + // CHECK: ![[RET6]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} +} + +- (int)testNoCleanupSideEffect { + // CHECK: ![[MSG7]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + [self testVoid :@"foo"]; + // CHECK: ![[RET7]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + return 1; +} + + +@end + + +int main(int argc, const char** argv) { + AppDelegate *o = [[AppDelegate alloc] init]; + return [o testMultiline :@"foo"]; +} diff --git a/test/CodeGenObjC/autorelease.m b/test/CodeGenObjC/autorelease.m index 830929a..f89b81a 100644 --- a/test/CodeGenObjC/autorelease.m +++ b/test/CodeGenObjC/autorelease.m @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-runtime=macosx-10.7 -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -emit-llvm -fobjc-runtime=macosx-10.7 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-runtime=macosx-10.7 -fexceptions -fobjc-exceptions -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -emit-llvm -fobjc-runtime=macosx-10.7 -fexceptions -fobjc-exceptions -o - %s | FileCheck %s // rdar://8881826 // rdar://9412038 @@ -28,3 +28,26 @@ // CHECK: call i8* @objc_autoreleasePoolPush // CHECK: [[T:%.*]] = load i8** [[A:%.*]] // CHECK: call void @objc_autoreleasePoolPop + +// rdar://13660038 +int tryTo(int (*f)(void)) { + @try { + @autoreleasepool { + return f(); + } + } @catch (...) { + return 0; + } +} +// CHECK: define i32 @tryTo(i32 ()* +// CHECK: [[RET:%.*]] = alloca i32, +// CHECK: [[T0:%.*]] = call i8* @objc_autoreleasePoolPush() +// CHECK-NEXT: [[T1:%.*]] = load i32 ()** {{%.*}}, +// CHECK-NEXT: [[T2:%.*]] = invoke i32 [[T1]]() +// CHECK: store i32 [[T2]], i32* [[RET]] +// CHECK: invoke void @objc_autoreleasePoolPop(i8* [[T0]]) +// CHECK: landingpad { i8*, i32 } personality +// CHECK-NEXT: catch i8* null +// CHECK: call i8* @objc_begin_catch +// CHECK-NEXT: store i32 0, i32* [[RET]] +// CHECK: call void @objc_end_catch() diff --git a/test/CodeGenObjC/debug-info-block-captured-self.m b/test/CodeGenObjC/debug-info-block-captured-self.m index 0316013..183e91b 100644 --- a/test/CodeGenObjC/debug-info-block-captured-self.m +++ b/test/CodeGenObjC/debug-info-block-captured-self.m @@ -59,7 +59,6 @@ typedef enum { // CHECK: call void @llvm.dbg.declare(metadata !{i8* [[BLOCK_DESC]]}, metadata ![[BDMD:[0-9]+]]) // CHECK: %[[TMP1:.*]] = bitcast // CHECK-NEXT: store -// CHECK-NEXT: %[[TMP2:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %[[TMP1]] // CHECK: call void @llvm.dbg.declare(metadata !{<{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** {{.*}}}, metadata ![[SELF:.*]]) // make sure we are still in the same function // CHECK: define {{.*}}__copy_helper_block_ diff --git a/test/CodeGenObjC/debug-info-block-line.m b/test/CodeGenObjC/debug-info-block-line.m index c913a97..2192575 100644 --- a/test/CodeGenObjC/debug-info-block-line.m +++ b/test/CodeGenObjC/debug-info-block-line.m @@ -64,13 +64,16 @@ typedef enum : NSUInteger { // CHECK: define internal void @"__39-[TServer serverConnection:getCommand:]_block_invoke" // CHECK: call void @objc_storeStrong(i8** [[ZERO:%.*]], i8* [[ONE:%.*]]) [[NUW:#[0-9]+]] // CHECK: call void @objc_storeStrong(i8** [[TWO:%.*]], i8* [[THREE:%.*]]) [[NUW]] +// CHECK: call {{.*}}@objc_msgSend{{.*}}, !dbg ![[LINE_ABOVE:[0-9]+]] +// CHECK: getelementptr +// CHECK-NOT: !dbg, ![[LINE_ABOVE]] // CHECK: bitcast %5** [[TMP:%.*]] to i8** -// CHECK: call void @objc_storeStrong(i8** [[VAL1:%.*]], i8* null) [[NUW]], !dbg ![[MD1:.*]] -// CHECK: bitcast %4** [[TMP:%.*]] to i8** -// CHECK: call void @objc_storeStrong(i8** [[VAL2:%.*]], i8* null) [[NUW]], !dbg ![[MD1]] +// CHECK-NOT: !dbg, ![[LINE_ABOVE]] +// CHECK: call void @objc_storeStrong(i8** [[VAL1:%.*]], i8* null) [[NUW]] +// CHECK-NEXT: bitcast %4** [[TMP:%.*]] to i8** +// CHECK-NEXT: call void @objc_storeStrong(i8** [[VAL2:%.*]], i8* null) [[NUW]] // CHECK-NEXT: ret // CHECK: attributes [[NUW]] = { nounwind } -// CHECK: ![[MD1]] = metadata !{i32 87 [map dataWithCompletionBlock:^(NSData *data, NSError *error) { if (data) { NSString *encoded = [[data compressedData] encodedString:18]; diff --git a/test/CodeGenObjC/debug-info-blocks.m b/test/CodeGenObjC/debug-info-blocks.m index f50ddf0..3d91c9e 100644 --- a/test/CodeGenObjC/debug-info-blocks.m +++ b/test/CodeGenObjC/debug-info-blocks.m @@ -7,11 +7,10 @@ // CHECK: define {{.*}}_block_invoke // CHECK: %[[BLOCK:.*]] = bitcast i8* %.block_descriptor to <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>*, !dbg // CHECK-NEXT: store <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %[[BLOCK]], <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA:.*]], align -// CHECK-NEXT: getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %[[BLOCK]], i32 0, i32 5 // CHECK-NEXT: call void @llvm.dbg.declare(metadata !{<{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA]]}, metadata ![[SELF:[0-9]+]]) // CHECK-NEXT: call void @llvm.dbg.declare(metadata !{%1** %d}, metadata ![[D:[0-9]+]]) -// CHECK: ![[SELF]] = {{.*}} [ DW_TAG_auto_variable ] [self] [line 52] -// CHECK: ![[D]] = {{.*}} [d] [line 50] +// CHECK: ![[SELF]] = {{.*}} [ DW_TAG_auto_variable ] [self] [line 51] +// CHECK: ![[D]] = {{.*}} [d] [line 49] typedef unsigned int NSUInteger; diff --git a/test/CodeGenObjC/encode-test-3.m b/test/CodeGenObjC/encode-test-3.m index 4b39cd7..b76063f 100644 --- a/test/CodeGenObjC/encode-test-3.m +++ b/test/CodeGenObjC/encode-test-3.m @@ -1,12 +1,14 @@ -// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o %t %s -// RUN: grep -e "\^i" %t | count 1 -// RUN: grep -e "\[0i\]" %t | count 1 +// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o - %s | FileCheck %s int main() { int n; const char * inc = @encode(int[]); +// CHECK: ^i +// CHECK-NOT: ^i const char * vla = @encode(int[n]); +// CHECK: [0i] +// CHECK-NOT: [0i] } // PR3648 diff --git a/test/CodeGenObjC/metadata-symbols-32.m b/test/CodeGenObjC/metadata-symbols-32.m index e8d2512..fda909c 100644 --- a/test/CodeGenObjC/metadata-symbols-32.m +++ b/test/CodeGenObjC/metadata-symbols-32.m @@ -1,32 +1,32 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o %t %s - -// RUN: grep '@"\\01L_OBJC_CATEGORY_A_Cat" = internal global .*section "__OBJC,__category,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_CATEGORY_CLASS_METHODS_A_Cat" = internal global .*section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_CATEGORY_INSTANCE_METHODS_A_Cat" = internal global .*section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_CLASSEXT_A" = internal global .*section "__OBJC,__class_ext,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_CLASS_A" = internal global .*section "__OBJC,__class,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_CLASS_METHODS_A" = internal global .*section "__OBJC,__cls_meth,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_CLASS_NAME_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t -// RUN: grep '@"\\01L_OBJC_CLASS_PROTOCOLS_A" = internal global .*section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_CLASS_REFERENCES_[0-9]*" = internal global .*section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4' %t +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s + +// CHECK: .lazy_reference .objc_class_name_J0 + +// CHECK: @"\01L_OBJC_METH_VAR_NAME_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @"\01L_OBJC_METH_VAR_TYPE_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @"\01L_OBJC_CLASS_NAME_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @"\01L_OBJC_PROTOCOL_INSTANCE_METHODS_P" = internal global {{.*}}section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_PROTOCOL_CLASS_METHODS_P" = internal global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_PROTOCOL_P" = internal global {{.*}}section "__OBJC,__protocol,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CLASS_PROTOCOLS_A" = internal global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CLASS_METHODS_A" = internal global {{.*}}section "__OBJC,__cls_meth,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_METACLASS_A" = internal global {{.*}}section "__OBJC,__meta_class,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_INSTANCE_VARIABLES_A" = internal global {{.*}}section "__OBJC,__instance_vars,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_INSTANCE_METHODS_A" = internal global {{.*}}section "__OBJC,__inst_meth,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_PROP_NAME_ATTR_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @"\01l_OBJC_$_PROP_LIST_A" = internal global {{.*}}section "__OBJC,__property,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CLASSEXT_A" = internal global {{.*}}section "__OBJC,__class_ext,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CLASS_A" = internal global {{.*}}section "__OBJC,__class,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CATEGORY_INSTANCE_METHODS_A_Cat" = internal global {{.*}}section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CATEGORY_CLASS_METHODS_A_Cat" = internal global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CATEGORY_A_Cat" = internal global {{.*}}section "__OBJC,__category,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CLASS_REFERENCES_{{[0-9]*}}" = internal global {{.*}}section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_{{[0-9]*}}" = internal externally_initialized global {{.*}}section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_SYMBOLS" = internal global {{.*}}section "__OBJC,__symbols,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_MODULES" = internal global {{.*}}section "__OBJC,__module_info,regular,no_dead_strip", align 4 // Clang's Obj-C 32-bit doesn't emit ivars for the root class. -// RUNX: grep '@"\\01L_OBJC_CLASS_VARIABLES_A" = internal global .*section "__OBJC,__class_vars,regular,no_dead_strip", align 4' %t && - -// RUN: grep '@"\\01L_OBJC_INSTANCE_METHODS_A" = internal global .*section "__OBJC,__inst_meth,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_INSTANCE_VARIABLES_A" = internal global .*section "__OBJC,__instance_vars,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_METACLASS_A" = internal global .*section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_METH_VAR_NAME_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t -// RUN: grep '@"\\01L_OBJC_METH_VAR_TYPE_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t -// RUN: grep '@"\\01L_OBJC_MODULES" = internal global .*section "__OBJC,__module_info,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_PROP_NAME_ATTR_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t -// RUN: grep '@"\\01L_OBJC_PROTOCOL_CLASS_METHODS_P" = internal global .*section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_PROTOCOL_INSTANCE_METHODS_P" = internal global .*section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_PROTOCOL_P" = internal global .*section "__OBJC,__protocol,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_SELECTOR_REFERENCES_[0-9]*" = internal externally_initialized global .*section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_SYMBOLS" = internal global .*section "__OBJC,__symbols,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01l_OBJC_$_PROP_LIST_A" = internal global .*section "__OBJC,__property,regular,no_dead_strip", align 4' %t -// RUN: grep "\.lazy_reference \.objc_class_name_J0" %t +// CHECKX: @"\01L_OBJC_CLASS_VARIABLES_A" = internal global {{.*}}section "__OBJC,__class_vars,regular,no_dead_strip", align 4 /* diff --git a/test/CodeGenObjC/metadata-symbols-64.m b/test/CodeGenObjC/metadata-symbols-64.m index 27017b7..a89fec5 100644 --- a/test/CodeGenObjC/metadata-symbols-64.m +++ b/test/CodeGenObjC/metadata-symbols-64.m @@ -1,37 +1,38 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed -emit-llvm -o %t %s - -// RUN: grep '@"OBJC_CLASS_$_A" = global' %t -// RUN: grep '@"OBJC_CLASS_$_B" = external global' %t -// RUN: grep '@"OBJC_IVAR_$_A._ivar" = global .* section "__DATA, __objc_ivar", align 8' %t -// RUN: grep '@"OBJC_METACLASS_$_A" = global .* section "__DATA, __objc_data", align 8' %t -// RUN: grep '@"\\01L_OBJC_CLASSLIST_REFERENCES_$_[0-9]*" = internal global .* section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8' %t -// RUN: grep '@"\\01L_OBJC_CLASSLIST_SUP_REFS_$_[0-9]*" = internal global .* section "__DATA, __objc_superrefs, regular, no_dead_strip", align 8' %t | count 2 -// RUN: grep '@"\\01L_OBJC_CLASS_NAME_[0-9]*" = internal global .* section "__TEXT,__objc_classname,cstring_literals", align 1' %t -// RUN: grep '@"\\01L_OBJC_LABEL_CATEGORY_$" = internal global .* section "__DATA, __objc_catlist, regular, no_dead_strip", align 8' %t -// RUN: grep '@"\\01L_OBJC_LABEL_CLASS_$" = internal global .* section "__DATA, __objc_classlist, regular, no_dead_strip", align 8' %t -// RUN: grep '@"\\01L_OBJC_METH_VAR_NAME_[0-9]*" = internal global .* section "__TEXT,__objc_methname,cstring_literals", align 1' %t -// RUN: grep '@"\\01L_OBJC_METH_VAR_TYPE_[0-9]*" = internal global .* section "__TEXT,__objc_methtype,cstring_literals", align 1' %t -// RUN: grep '@"\\01L_OBJC_PROP_NAME_ATTR_[0-9]*" = internal global .* section "__TEXT,__cstring,cstring_literals", align 1' %t -// RUN: grep '@"\\01L_OBJC_SELECTOR_REFERENCES_*" = internal externally_initialized global .* section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"' %t -// RUN: grep '@"\\01l_OBJC_$_CATEGORY_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_$_CATEGORY_CLASS_METHODS_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_$_CLASS_METHODS_A" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_$_INSTANCE_METHODS_A" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_$_INSTANCE_VARIABLES_A" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_$_PROP_LIST_A" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_$_PROTOCOL_CLASS_METHODS_P" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_P" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_CLASS_PROTOCOLS_$_A" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_CLASS_RO_$_A" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_LABEL_PROTOCOL_$_P" = weak hidden global .* section "__DATA, __objc_protolist, coalesced, no_dead_strip", align 8' %t -// RUN: grep '@"\\01l_OBJC_METACLASS_RO_$_A" = internal global .* section "__DATA, __objc_const", align 8' %t -// RUN: grep '@"\\01l_OBJC_PROTOCOL_$_P" = weak hidden global .* section "__DATA,__datacoal_nt,coalesced", align 8' %t -// RUN: grep '@"\\01l_objc_msgSend_fixup_alloc" = weak hidden global .* section "__DATA, __objc_msgrefs, coalesced", align 16' %t -// RUN: grep '@_objc_empty_cache = external global' %t -// RUN: grep '@_objc_empty_vtable = external global' %t -// RUN: grep '@objc_msgSend_fixup(' %t -// RUN: grep '@objc_msgSend_fpret(' %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed -emit-llvm -o - %s | FileCheck %s + +// CHECK: @"OBJC_IVAR_$_A._ivar" = global {{.*}} section "__DATA, __objc_ivar", align 8 +// CHECK: @_objc_empty_cache = external global +// CHECK: @_objc_empty_vtable = external global +// CHECK: @"OBJC_CLASS_$_A" = global +// CHECK: @"OBJC_METACLASS_$_A" = global {{.*}} section "__DATA, __objc_data", align 8 +// CHECK: @"\01L_OBJC_CLASS_NAME_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__objc_classname,cstring_literals", align 1 +// CHECK: @"\01L_OBJC_METH_VAR_NAME_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__objc_methname,cstring_literals", align 1 +// CHECK: @"\01L_OBJC_METH_VAR_TYPE_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__objc_methtype,cstring_literals", align 1 +// CHECK: @"\01l_OBJC_$_CLASS_METHODS_A" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_P" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_P" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01l_OBJC_PROTOCOL_$_P" = weak hidden global {{.*}} section "__DATA,__datacoal_nt,coalesced", align 8 +// CHECK: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = weak hidden global {{.*}} section "__DATA, __objc_protolist, coalesced, no_dead_strip", align 8 +// CHECK: @"\01l_OBJC_CLASS_PROTOCOLS_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01l_OBJC_METACLASS_RO_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01l_OBJC_$_INSTANCE_METHODS_A" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01l_OBJC_$_INSTANCE_VARIABLES_A" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01L_OBJC_PROP_NAME_ATTR_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @"\01l_OBJC_$_PROP_LIST_A" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01l_OBJC_CLASS_RO_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_A_$_Cat" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01l_OBJC_$_CATEGORY_CLASS_METHODS_A_$_Cat" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01l_OBJC_$_CATEGORY_A_$_Cat" = internal global {{.*}} section "__DATA, __objc_const", align 8 +// CHECK: @"\01L_OBJC_CLASSLIST_SUP_REFS_$_{{[0-9]*}}" = internal global {{.*}} section "__DATA, __objc_superrefs, regular, no_dead_strip", align 8 +// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_" = internal externally_initialized global {{.*}} section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" +// CHECK: @"\01L_OBJC_CLASSLIST_SUP_REFS_$_{{[0-9]*}}" = internal global {{.*}} section "__DATA, __objc_superrefs, regular, no_dead_strip", align 8 +// CHECK: @"OBJC_CLASS_$_B" = external global +// CHECK: @"\01L_OBJC_CLASSLIST_REFERENCES_$_{{[0-9]*}}" = internal global {{.*}} section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 +// CHECK: @"\01l_objc_msgSend_fixup_alloc" = weak hidden global {{.*}} section "__DATA, __objc_msgrefs, coalesced", align 16 +// CHECK: @"\01L_OBJC_LABEL_CLASS_$" = internal global {{.*}} section "__DATA, __objc_classlist, regular, no_dead_strip", align 8 +// CHECK: @"\01L_OBJC_LABEL_CATEGORY_$" = internal global {{.*}} section "__DATA, __objc_catlist, regular, no_dead_strip", align 8 +// CHECK: @objc_msgSend_fpret( +// CHECK: @objc_msgSend_fixup( /* diff --git a/test/CodeGenObjC/metadata_symbols.m b/test/CodeGenObjC/metadata_symbols.m index 576a55b..eedcf16 100644 --- a/test/CodeGenObjC/metadata_symbols.m +++ b/test/CodeGenObjC/metadata_symbols.m @@ -1,6 +1,12 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -fobjc-exceptions -o %t %s // RUN: FileCheck -check-prefix=CHECK-X86_64 < %t %s -// RUN: grep '@"OBJC_EHTYPE_$_EH3"' %t | count 3 +// RUN: FileCheck -check-prefix=CHECK-EHTYPE < %t %s + +// We need exactly 3 of these. +// CHECK-EHTYPE: @"OBJC_EHTYPE_$_EH3" +// CHECK-EHTYPE: @"OBJC_EHTYPE_$_EH3" +// CHECK-EHTYPE: @"OBJC_EHTYPE_$_EH3" +// CHECK-EHTYPE-NOT: @"OBJC_EHTYPE_$_EH3" // CHECK-X86_64: @"OBJC_CLASS_$_A" = global {{.*}}, section "__DATA, __objc_data", align 8 // CHECK-X86_64: @"OBJC_METACLASS_$_A" = global {{.*}}, section "__DATA, __objc_data", align 8 diff --git a/test/CodeGenObjC/objc-align.m b/test/CodeGenObjC/objc-align.m index 1a9e882..1a96f34 100644 --- a/test/CodeGenObjC/objc-align.m +++ b/test/CodeGenObjC/objc-align.m @@ -1,14 +1,14 @@ // 32-bit -// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o %t %s -// RUN: grep '@"\\01L_OBJC_CATEGORY_A_Cat" = internal global .*, section "__OBJC,__category,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_CLASS_A" = internal global .*, section "__OBJC,__class,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_CLASS_C" = internal global .*, section "__OBJC,__class,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_CLASS_PROTOCOLS_C" = internal global .*, section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_METACLASS_A" = internal global .*, section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_METACLASS_C" = internal global .*, section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_MODULES" = internal global .*, section "__OBJC,__module_info,regular,no_dead_strip", align 4' %t -// RUN: grep '@"\\01L_OBJC_PROTOCOL_P" = internal global .*, section "__OBJC,__protocol,regular,no_dead_strip", align 4' %t +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s +// CHECK: @"\01L_OBJC_METACLASS_A" = internal global {{.*}}, section "__OBJC,__meta_class,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CLASS_A" = internal global {{.*}}, section "__OBJC,__class,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CATEGORY_A_Cat" = internal global {{.*}}, section "__OBJC,__category,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_PROTOCOL_P" = internal global {{.*}}, section "__OBJC,__protocol,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CLASS_PROTOCOLS_C" = internal global {{.*}}, section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_METACLASS_C" = internal global {{.*}}, section "__OBJC,__meta_class,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_CLASS_C" = internal global {{.*}}, section "__OBJC,__class,regular,no_dead_strip", align 4 +// CHECK: @"\01L_OBJC_MODULES" = internal global {{.*}}, section "__OBJC,__module_info,regular,no_dead_strip", align 4 // 64-bit diff --git a/test/CodeGenObjC/objc-fixed-enum.m b/test/CodeGenObjC/objc-fixed-enum.m new file mode 100644 index 0000000..55c2a7c --- /dev/null +++ b/test/CodeGenObjC/objc-fixed-enum.m @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -g -emit-llvm -o - %s | FileCheck %s +// The DWARF standard says the underlying data type of an enum may be +// stored in an DW_AT_type entry in the enum DIE. This is useful to have +// so the debugger knows about the signedness of the underlying type. + +typedef long NSInteger; +#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type + +// Enum with no specified underlying type +typedef enum { + Enum0One, + Enum0Two +} Enum0; + +// Enum declared with the NS_ENUM macro +typedef NS_ENUM(NSInteger, Enum1) { + Enum1One = -1, + Enum1Two +}; + +// Enum declared with a fixed underlying type +typedef enum : NSInteger { + Enum2One = -1, + Enum2Two +} Enum2; + +// Typedef and declaration separately +enum : NSInteger +{ + Enum3One = -1, + Enum3Two +}; +typedef NSInteger Enum3; + +int main() { + Enum0 e0 = Enum0One; + // CHECK: call void @llvm.dbg.declare(metadata !{{.*}}, metadata ![[ENUM0:[0-9]+]]) + Enum1 e1 = Enum1One; + // CHECK: call void @llvm.dbg.declare(metadata !{{.*}}, metadata ![[ENUM1:[0-9]+]]) + Enum2 e2 = Enum2One; + // CHECK: call void @llvm.dbg.declare(metadata !{{.*}}, metadata ![[ENUM2:[0-9]+]]) + Enum3 e3 = Enum3One; + // CHECK: call void @llvm.dbg.declare(metadata !{{.*}}, metadata ![[ENUM3:[0-9]+]]) + + // -Werror and the following line ensures that these enums are not + // -treated as C++11 strongly typed enums. + return e0 != e1 && e1 == e2 && e2 == e3; +} +// CHECK: ![[ENUMERATOR0:[0-9]+]] = {{.*}}; [ DW_TAG_enumeration_type ] [line 10 +// CHECK: ![[ENUMERATOR1:[0-9]+]] = {{.*}}; [ DW_TAG_enumeration_type ] [Enum1] [line 16{{.*}}] [from NSInteger] +// CHECK: ![[ENUMERATOR3:[0-9]+]] = {{.*}}; [ DW_TAG_typedef ] [NSInteger] [line 6{{.*}}] [from long int] +// CHECK: ![[ENUMERATOR2:[0-9]+]] = {{.*}}; [ DW_TAG_enumeration_type ] [line 22{{.*}}] [from NSInteger] + +// CHECK: ![[ENUM0]] = metadata !{{{.*}}!"e0", metadata !{{[0-9]+}}, i32 {{[0-9]+}}, metadata ![[TYPE0:[0-9]+]] +// CHECK: ![[TYPE0]] = metadata !{{{.*}}!"Enum0", {{.*}} metadata ![[ENUMERATOR0]]} ; [ DW_TAG_typedef ] [Enum0] + +// CHECK: ![[ENUM1]] = metadata !{{{.*}}!"e1", metadata !{{[0-9]+}}, i32 {{[0-9]+}}, metadata ![[TYPE1:[0-9]+]] +// CHECK: ![[TYPE1]] = metadata !{{{.*}}!"Enum1", {{.*}} metadata ![[ENUMERATOR1]]} ; [ DW_TAG_typedef ] [Enum1] + +// CHECK: ![[ENUM2]] = metadata !{{{.*}}!"e2", metadata !{{[0-9]+}}, i32 {{[0-9]+}}, metadata ![[TYPE2:[0-9]+]] +// CHECK: ![[TYPE2]] = metadata !{{{.*}}!"Enum2", {{.*}} metadata ![[ENUMERATOR2]]} ; [ DW_TAG_typedef ] [Enum2] + +// CHECK: ![[ENUM3]] = metadata !{{{.*}}!"e3", metadata !{{[0-9]+}}, i32 {{[0-9]+}}, metadata ![[TYPE3:[0-9]+]] +// CHECK: ![[TYPE3]] = metadata !{{{.*}}!"Enum3", {{.*}} metadata ![[ENUMERATOR3]]} ; [ DW_TAG_typedef ] [Enum3] diff --git a/test/CodeGenObjC/synthesize_ivar-cont-class.m b/test/CodeGenObjC/synthesize_ivar-cont-class.m index 9822702..393ec36 100644 --- a/test/CodeGenObjC/synthesize_ivar-cont-class.m +++ b/test/CodeGenObjC/synthesize_ivar-cont-class.m @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o %t %s -// RUN: grep '@"OBJC_IVAR_$_XCOrganizerDeviceNodeInfo.viewController"' %t +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s // PR13820 // REQUIRES: LP64 @@ -17,5 +16,6 @@ @implementation XCOrganizerDeviceNodeInfo @synthesize viewController; +// CHECK: @"OBJC_IVAR_$_XCOrganizerDeviceNodeInfo.viewController" @end diff --git a/test/CodeGenObjC/tentative-cfconstantstring.m b/test/CodeGenObjC/tentative-cfconstantstring.m new file mode 100644 index 0000000..b7e1c46 --- /dev/null +++ b/test/CodeGenObjC/tentative-cfconstantstring.m @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s +// rdar://13598026 + +@interface NSObject @end + +@class NSString; + +int __CFConstantStringClassReference[24]; + +@interface Bar : NSObject ++(void)format:(NSString *)format,...; +@end + +@interface Foo : NSObject +@end + + +static inline void _inlineFunction() { + [Bar format:@" "]; +} + +@implementation Foo + + ++(NSString *)someMethod { + return @""; +} + +-(void)someMethod { + _inlineFunction(); +} +@end + +// CHECK: @__CFConstantStringClassReference = common global [24 x i32] zeroinitializer, align 16 +// CHECK: @_unnamed_cfstring_{{.*}} = private constant %struct.NSConstantString { i32* getelementptr inbounds ([24 x i32]* @__CFConstantStringClassReference, i32 0, i32 0) + +// CHECK: define internal void @_inlineFunction() +// CHECK: [[ZERO:%.*]] = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_ +// CHECK-NEXT: [[ONE:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_" +// CHECK-NEXT: [[TWO:%.*]] = bitcast %struct._class_t* [[ZERO]] to i8* +// CHECK-NEXT: call void (i8*, i8*, [[T:%.*]]*, ...)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, [[T:%.*]]*, ...)*)(i8* [[TWO]], i8* [[ONE]], [[T:%.*]]* bitcast (%struct.NSConstantString* @_unnamed_cfstring_{{.*}} to [[T:%.*]]*)) +// CHECK-NEXT: ret void + diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm index 1888dbe..e3e86a0 100644 --- a/test/CodeGenObjCXX/arc.mm +++ b/test/CodeGenObjCXX/arc.mm @@ -275,3 +275,25 @@ id Test39::bar() { return 0; } // CHECK: define i8* @_ZThn8_N6Test393barEv( // CHECK: call i8* @_ZN6Test393barEv( // CHECK-NEXT: ret i8* + +// rdar://13617051 +// Just a basic sanity-check that IR-gen still works after instantiating +// a non-dependent message send that requires writeback. +@interface Test40 ++ (void) foo:(id *)errorPtr; +@end +template <class T> void test40_helper() { + id x; + [Test40 foo: &x]; +}; +template void test40_helper<int>(); +// CHECK: define weak_odr void @_Z13test40_helperIiEvv() +// CHECK: [[X:%.*]] = alloca i8* +// CHECK-NEXT: [[TEMP:%.*]] = alloca i8* +// CHECK-NEXT: store i8* null, i8** [[X]] +// CHECK: [[T0:%.*]] = load i8** [[X]] +// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP]] +// CHECK: @objc_msgSend +// CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]] +// CHECK-NEXT: call i8* @objc_retain(i8* [[T0]]) + diff --git a/test/CodeGenObjCXX/lambda-expressions.mm b/test/CodeGenObjCXX/lambda-expressions.mm index 7c1e2e4..c73e172 100644 --- a/test/CodeGenObjCXX/lambda-expressions.mm +++ b/test/CodeGenObjCXX/lambda-expressions.mm @@ -38,6 +38,28 @@ void f2() { global = []{ return 3; }; } // ARC: define internal i32 @___Z2f2v_block_invoke // ARC: call i32 @"_ZZ2f2vENK3$_1clEv +template <class T> void take_lambda(T &&lambda) { lambda(); } +void take_block(void (^block)()) { block(); } + +// rdar://13800041 +@interface A +- (void) test; +@end +@interface B : A @end +@implementation B +- (void) test { + take_block(^{ + take_lambda([=]{ + take_block(^{ + take_lambda([=] { + [super test]; + }); + }); + }); + }); +} +@end + // ARC: attributes [[NUW]] = { nounwind{{.*}} } // MRC: attributes [[NUW]] = { nounwind{{.*}} } diff --git a/test/CodeGenObjCXX/mangle.mm b/test/CodeGenObjCXX/mangle.mm index 2521c60..45a93a1 100644 --- a/test/CodeGenObjCXX/mangle.mm +++ b/test/CodeGenObjCXX/mangle.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s // CHECK: @"_ZZ11+[A shared]E1a" = internal global // CHECK: @"_ZZ11-[A(Foo) f]E1a" = internal global @@ -54,3 +54,27 @@ uiIsVisible(); } @end + +// rdar://13434937 +// +// Don't crash when mangling an enum whose semantic context +// is a class extension (which looks anonymous in the AST). +// The other tests here are just for coverage. +@interface Test2 @end +@interface Test2 () +@property (assign) enum { T2x, T2y, T2z } axis; +@end +@interface Test2 (a) +@property (assign) enum { T2i, T2j, T2k } dimension; +@end +@implementation Test2 { +@public + enum { T2a, T2b, T2c } alt_axis; +} +@end +template <class T> struct Test2Template { Test2Template() {} }; // must have a member that we'll instantiate and mangle +void test2(Test2 *t) { + Test2Template<decltype(t.axis)> t0; + Test2Template<decltype(t.dimension)> t1; + Test2Template<decltype(t->alt_axis)> t2; +} diff --git a/test/Driver/Inputs/fedora_18_tree/lib/.keep b/test/Driver/Inputs/fedora_18_tree/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/fedora_18_tree/lib/.keep diff --git a/test/Driver/Inputs/fedora_18_tree/usr/lib/crt1.o b/test/Driver/Inputs/fedora_18_tree/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/fedora_18_tree/usr/lib/crt1.o diff --git a/test/Driver/Inputs/fedora_18_tree/usr/lib/crti.o b/test/Driver/Inputs/fedora_18_tree/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/fedora_18_tree/usr/lib/crti.o diff --git a/test/Driver/Inputs/fedora_18_tree/usr/lib/crtn.o b/test/Driver/Inputs/fedora_18_tree/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/fedora_18_tree/usr/lib/crtn.o diff --git a/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtbegin.o b/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtbegin.o diff --git a/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtend.o b/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/bin/.keep b/test/Driver/Inputs/mips_cs_tree/bin/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/bin/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/64/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/64/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/64/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/el/64/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/el/64/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/el/64/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/el/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/soft-float/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/soft-float/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/el/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/soft-float/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/soft-float/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/64/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/64/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/64/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/el/64/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/el/64/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/el/64/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtbegin.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtbegin.o diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtend.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtend.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/soft-float/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/soft-float/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/soft-float/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/soft-float/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/soft-float/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/soft-float/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/soft-float/el/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/soft-float/el/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib64/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib64/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib64/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib64/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib64/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib64/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib64/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib64/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib64/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib64/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib64/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib64/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/include/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/include/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/include/.keep diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crtn.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crt1.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crt1.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crti.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crti.o diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crtn.o new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crtn.o diff --git a/test/Driver/Ofast.c b/test/Driver/Ofast.c new file mode 100644 index 0000000..1f9fc78 --- /dev/null +++ b/test/Driver/Ofast.c @@ -0,0 +1,39 @@ +// RUN: %clang -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -O2 -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -fno-fast-math -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -fno-strict-aliasing -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -fno-vectorize -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -Ofast -O2 -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-O2 %s +// RUN: %clang -Ofast -fno-fast-math -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-FAST-MATH %s +// RUN: %clang -Ofast -fno-strict-aliasing -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-STRICT-ALIASING %s +// RUN: %clang -Ofast -fno-vectorize -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-VECTORIZE %s + +// CHECK-OFAST: -cc1 +// CHECK-OFAST-NOT: -relaxed-aliasing +// CHECK-OFAST: -ffast-math +// CHECK-OFAST: -Ofast +// CHECK-OFAST: -vectorize-loops + +// CHECK-OFAST-O2: -cc1 +// CHECK-OFAST-O2-NOT: -relaxed-aliasing +// CHECK-OFAST-O2-NOT: -ffast-math +// CHECK-OFAST-O2-NOT: -Ofast +// CHECK-OFAST-O2: -vectorize-loops + +// CHECK-OFAST-NO-FAST-MATH: -cc1 +// CHECK-OFAST-NO-FAST-MATH-NOT: -relaxed-aliasing +// CHECK-OFAST-NO-FAST-MATH-NOT: -ffast-math +// CHECK-OFAST-NO-FAST-MATH: -Ofast +// CHECK-OFAST-NO-FAST-MATH: -vectorize-loops + +// CHECK-OFAST-NO-STRICT-ALIASING: -cc1 +// CHECK-OFAST-NO-STRICT-ALIASING: -relaxed-aliasing +// CHECK-OFAST-NO-STRICT-ALIASING: -ffast-math +// CHECK-OFAST-NO-STRICT-ALIASING: -Ofast +// CHECK-OFAST-NO-STRICT-ALIASING: -vectorize-loops + +// CHECK-OFAST-NO-VECTORIZE: -cc1 +// CHECK-OFAST-NO-VECTORIZE-NOT: -relaxed-aliasing +// CHECK-OFAST-NO-VECTORIZE: -ffast-math +// CHECK-OFAST-NO-VECTORIZE: -Ofast +// CHECK-OFAST-NO-VECTORIZE-NOT: -vectorize-loops diff --git a/test/Driver/autolink_integrated_as.c b/test/Driver/autolink_integrated_as.c new file mode 100644 index 0000000..f1e7102 --- /dev/null +++ b/test/Driver/autolink_integrated_as.c @@ -0,0 +1,6 @@ +// RUN: %clang -target x86_64-apple-darwin -fsyntax-only %s -no-integrated-as -### 2>&1 | FileCheck %s + +// Test that the autolinking feature is disabled with *not* using the +// integrated assembler. + +// CHECK: -fno-autolink diff --git a/test/Driver/clang_cpp.c b/test/Driver/clang_cpp.c index 79b2f55..bf31800 100644 --- a/test/Driver/clang_cpp.c +++ b/test/Driver/clang_cpp.c @@ -1,4 +1,5 @@ // Verify that -include isn't included twice with -save-temps. // RUN: %clang -S -o - %s -include %t.h -save-temps -### 2> %t.log -// RUN: grep '"-include' %t.log | count 1 - +// RUN: FileCheck %s < %t.log +// CHECK: "-include +// CHECK-NOT: "-include diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c index c1431a1..5451945 100644 --- a/test/Driver/clang_f_opts.c +++ b/test/Driver/clang_f_opts.c @@ -56,8 +56,15 @@ // RUN: %clang -### -S -fno-tree-slp-vectorize -fslp-vectorize %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE %s // RUN: %clang -### -S -fno-tree-slp-vectorize %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE %s // RUN: %clang -### -S -ftree-slp-vectorize -fno-slp-vectorize %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE %s -// CHECK-SLP-VECTORIZE: "-vectorize" -// CHECK-NO-SLP-VECTORIZE-NOT: "-vectorize" +// CHECK-SLP-VECTORIZE: "-vectorize-slp" +// CHECK-NO-SLP-VECTORIZE-NOT: "-vectorize-slp" + +// RUN: %clang -### -S -fslp-vectorize-aggressive %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE-AGG %s +// RUN: %clang -### -S -fno-slp-vectorize-aggressive -fslp-vectorize-aggressive %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE-AGG %s +// RUN: %clang -### -S -fno-slp-vectorize-aggressive %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE-AGG %s +// RUN: %clang -### -S -fslp-vectorize-aggressive -fno-slp-vectorize-aggressive %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE-AGG %s +// CHECK-SLP-VECTORIZE-AGG: "-vectorize-slp-aggressive" +// CHECK-NO-SLP-VECTORIZE-AGG-NOT: "-vectorize-slp-aggressive" // RUN: %clang -### -S -fextended-identifiers %s 2>&1 | FileCheck -check-prefix=CHECK-EXTENDED-IDENTIFIERS %s // RUN: %clang -### -S -fno-extended-identifiers %s 2>&1 | FileCheck -check-prefix=CHECK-NO-EXTENDED-IDENTIFIERS %s diff --git a/test/Driver/color-diagnostics.c b/test/Driver/color-diagnostics.c new file mode 100644 index 0000000..deff511 --- /dev/null +++ b/test/Driver/color-diagnostics.c @@ -0,0 +1,53 @@ +// RUN: %clang -fcolor-diagnostics -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CD %s +// CHECK-CD: clang{{.*}}" "-fcolor-diagnostics" + +// RUN: %clang -fno-color-diagnostics -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=NCD %s +// CHECK-NCD-NOT: clang{{.*}}" "-fcolor-diagnostics" + +// RUN: %clang -fdiagnostics-color -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=DC %s +// CHECK-DC: clang{{.*}}" "-fcolor-diagnostics" + +// RUN: %clang -fno-diagnostics-color -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=NDC %s +// CHECK-NDC-NOT: clang{{.*}}" "-fcolor-diagnostics" + +// RUN: %clang -fdiagnostics-color=always -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=DCE_A %s +// CHECK-DCE_A: clang{{.*}}" "-fcolor-diagnostics" + +// RUN: %clang -fdiagnostics-color=never -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=DCE_N %s +// CHECK-DCE_N-NOT: clang{{.*}}" "-fcolor-diagnostics" + +// The test doesn't run in a PTY, so "auto" defaults to off. +// RUN: %clang -fdiagnostics-color=auto -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=DCE_AUTO %s +// CHECK-DCE_AUTO-NOT: clang{{.*}}" "-fcolor-diagnostics" + +// RUN: %clang -fdiagnostics-color=foo -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=DCE_FOO %s +// CHECK-DCE_FOO: error: the clang compiler does not support '-fdiagnostics-color=foo' + +// Check that the last flag wins. +// RUN: %clang -fno-color-diagnostics -fdiagnostics-color -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=NCD_DC_S %s +// CHECK-NCD_DC_S: clang{{.*}}" "-fcolor-diagnostics" + +// RUN: %clang -fcolor-diagnostics -fno-diagnostics-color -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CD_NDC_S %s +// CHECK-CD_NDC_S-NOT: clang{{.*}}" "-fcolor-diagnostics" + +// RUN: %clang -fdiagnostics-color -fno-color-diagnostics -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=DC_NCD_S %s +// CHECK-DC_NCD_S-NOT: clang{{.*}}" "-fcolor-diagnostics" + +// RUN: %clang -fno-diagnostics-color -fcolor-diagnostics -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=NDC_CD_S %s +// CHECK-NDC_CD_S: clang{{.*}}" "-fcolor-diagnostics" + +// RUN: %clang -fcolor-diagnostics -fdiagnostics-color=auto -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CD_DCE_AUTO_S %s +// CHECK-CD_DCE_AUTO_S-NOT: clang{{.*}}" "-fcolor-diagnostics" diff --git a/test/Driver/debug-comp-dir.S b/test/Driver/debug-comp-dir.S index ca1ca30..daf895c 100644 --- a/test/Driver/debug-comp-dir.S +++ b/test/Driver/debug-comp-dir.S @@ -1,9 +1,6 @@ // RUN: cd %S && %clang -### -g %s -c 2>&1 | FileCheck -check-prefix=CHECK-PWD %s // CHECK-PWD: {{"-fdebug-compilation-dir" ".*Driver.*"}} -// RUN: env PWD=/foo %clang -### -g %s -c 2>&1 | FileCheck -check-prefix=CHECK-FOO %s -// CHECK-FOO: {{"-fdebug-compilation-dir" ".*foo"}} - // "PWD=/foo gcc" wouldn't necessarily work. You would need to pick a different // path to the same directory (try a symlink). diff --git a/test/Driver/debug.c b/test/Driver/debug.c index ca1ca30..daf895c 100644 --- a/test/Driver/debug.c +++ b/test/Driver/debug.c @@ -1,9 +1,6 @@ // RUN: cd %S && %clang -### -g %s -c 2>&1 | FileCheck -check-prefix=CHECK-PWD %s // CHECK-PWD: {{"-fdebug-compilation-dir" ".*Driver.*"}} -// RUN: env PWD=/foo %clang -### -g %s -c 2>&1 | FileCheck -check-prefix=CHECK-FOO %s -// CHECK-FOO: {{"-fdebug-compilation-dir" ".*foo"}} - // "PWD=/foo gcc" wouldn't necessarily work. You would need to pick a different // path to the same directory (try a symlink). diff --git a/test/Driver/dragonfly.c b/test/Driver/dragonfly.c index 8a629da..4be2aad 100644 --- a/test/Driver/dragonfly.c +++ b/test/Driver/dragonfly.c @@ -1,7 +1,7 @@ -// RUN: %clang -no-canonical-prefixes -target amd64-pc-dragonfly %s -### 2> %t.log +// RUN: %clang -no-canonical-prefixes -target x86_64-pc-dragonfly %s -### 2> %t.log // RUN: FileCheck -input-file %t.log %s -// CHECK: clang{{.*}}" "-cc1" "-triple" "amd64-pc-dragonfly" -// CHECK: ld{{.*}}" "-dynamic-linker" "{{.*}}ld-elf.{{.*}}" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-L{{.*}}/gcc{{.*}}" {{.*}} "-lc" "-lgcc" "{{.*}}crtend.o" "{{.*}}crtn.o" +// CHECK: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-dragonfly" +// CHECK: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/usr/libexec/ld-elf.so.{{.*}}" "--hash-style=both" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-L{{.*}}gcc4{{.*}}" "-rpath" "{{.*}}gcc4{{.*}}" "-lc" "-lgcc" "{{.*}}crtend.o" "{{.*}}crtn.o" diff --git a/test/Driver/flags.c b/test/Driver/flags.c index 2786231..ff60caf 100644 --- a/test/Driver/flags.c +++ b/test/Driver/flags.c @@ -1,20 +1,26 @@ -// RUN: %clang -target i386-apple-darwin9 -### -S -msoft-float %s 2> %t.log -// RUN: grep '"-no-implicit-float"' %t.log +// RUN: %clang -target i386-apple-darwin9 -### -S -msoft-float %s 2>&1 | FileCheck -check-prefix=TEST1 %s +// TEST1: "-no-implicit-float" -// RUN: %clang -target i386-apple-darwin9 -### -S -msoft-float -mno-soft-float %s 2> %t.log -// RUN: grep '"-no-implicit-float"' %t.log | count 0 +// RUN: %clang -target i386-apple-darwin9 -### -S -msoft-float -mno-soft-float %s 2>&1 | FileCheck -check-prefix=TEST2 %s +// TEST2-NOT: "-no-implicit-float" -// RUN: %clang -target i386-apple-darwin9 -### -S -mno-soft-float %s -msoft-float 2> %t.log -// RUN: grep '"-no-implicit-float"' %t.log +// RUN: %clang -target i386-apple-darwin9 -### -S -mno-soft-float %s -msoft-float 2>&1 | FileCheck -check-prefix=TEST3 %s +// TEST3: "-no-implicit-float" -// RUN: %clang -target i386-apple-darwin9 -### -S -mno-implicit-float %s 2> %t.log -// RUN: grep '"-no-implicit-float"' %t.log +// RUN: %clang -target i386-apple-darwin9 -### -S -mno-implicit-float %s 2>&1 | FileCheck -check-prefix=TEST4 %s +// TEST4: "-no-implicit-float" -// RUN: %clang -target i386-apple-darwin9 -### -S -mkernel %s 2> %t.log -// RUN: grep '"-no-implicit-float"' %t.log +// RUN: %clang -target i386-apple-darwin9 -### -S -mno-implicit-float -mimplicit-float %s 2>&1 | FileCheck -check-prefix=TEST4A %s +// TEST4A-NOT: "-no-implicit-float" -// RUN: %clang -target i386-apple-darwin9 -### -S -mkernel -mno-soft-float %s 2> %t.log -// RUN: grep '"-no-implicit-float"' %t.log | count 0 +// RUN: %clang -target i386-apple-darwin9 -### -S -mkernel %s 2>&1 | FileCheck -check-prefix=TEST5 %s +// TEST5: "-no-implicit-float" -// RUN: %clang -target armv7-apple-darwin10 -### -S -mno-implicit-float %s 2> %t.log -// RUN: grep '"-no-implicit-float"' %t.log +// RUN: %clang -target i386-apple-darwin9 -### -S -mkernel -mno-soft-float %s 2>&1 | FileCheck -check-prefix=TEST6 %s +// TEST6-NOT: "-no-implicit-float" + +// RUN: %clang -target armv7-apple-darwin10 -### -S -mno-implicit-float %s 2>&1 | FileCheck -check-prefix=TEST7 %s +// TEST7: "-no-implicit-float" + +// RUN: %clang -target armv7-apple-darwin10 -### -S -mno-implicit-float -mimplicit-float %s 2>&1 | FileCheck -check-prefix=TEST8 %s +// TEST8-NOT: "-no-implicit-float" diff --git a/test/Driver/fparse-all-comments.c b/test/Driver/fparse-all-comments.c new file mode 100644 index 0000000..5f825d0 --- /dev/null +++ b/test/Driver/fparse-all-comments.c @@ -0,0 +1,5 @@ +// Check that we pass -fparse-all-comments to frontend. +// +// RUN: %clang -c %s -fparse-all-comments -### 2>&1 | FileCheck %s --check-prefix=CHECK-ARG +// +// CHECK-ARG: -fparse-all-comments diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c index 1d606b4..0e7522b 100644 --- a/test/Driver/fsanitize.c +++ b/test/Driver/fsanitize.c @@ -95,19 +95,30 @@ // CHECK-DEPRECATED: argument '-fbounds-checking' is deprecated, use '-fsanitize=bounds' instead // RUN: %clang -target x86_64-linux-gnu -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-NO-PIE -// CHECK-TSAN-NO-PIE: invalid argument '-fsanitize=thread' only allowed with '-pie' +// CHECK-TSAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2" +// CHECK-TSAN-NO-PIE: "-pie" // RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-NO-PIE -// CHECK-MSAN-NO-PIE: invalid argument '-fsanitize=memory' only allowed with '-pie' +// CHECK-MSAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2" +// CHECK-MSAN-NO-PIE: "-pie" // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE -// CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: invalid argument '-fsanitize-address-zero-base-shadow' only allowed with '-pie' +// CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2" +// CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: "-pie" // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow -fno-sanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL -// CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: '-fsanitize-address-zero-base-shadow' only allowed with '-pie' +// CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2" +// CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: "-pie" // RUN: %clang -target arm-linux-androideabi -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-NO-PIE -// CHECK-ANDROID-ASAN-NO-PIE: AddressSanitizer on Android requires '-pie' +// CHECK-ANDROID-ASAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2" +// CHECK-ANDROID-ASAN-NO-PIE: "-pie" + +// RUN: %clang -target arm-linux-androideabi -fsanitize=address -fsanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-ZERO-BASE +// CHECK-ANDROID-ASAN-ZERO-BASE-NOT: argument unused during compilation + +// RUN: %clang -target arm-linux-androideabi -fsanitize=address -fno-sanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-NO-ZERO-BASE +// CHECK-ANDROID-ASAN-NO-ZERO-BASE: '-fno-sanitize-address-zero-base-shadow' not allowed with '-fsanitize=address' // RUN: %clang -target x86_64-linux-gnu %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER // RUN: %clang -target x86_64-linux-gnu %s -fsanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER diff --git a/test/Driver/hexagon-toolchain-elf.c b/test/Driver/hexagon-toolchain-elf.c index b3ff7b6..1a2650d 100644 --- a/test/Driver/hexagon-toolchain-elf.c +++ b/test/Driver/hexagon-toolchain-elf.c @@ -560,5 +560,5 @@ // RUN: | FileCheck -check-prefix=CHECK029 %s // CHECK029: "{{.*}}clang{{.*}}" "-cc1" // CHECK029-NEXT: "{{.*}}/bin/hexagon-as" -// CHECK029: "-gdwarf-2" "--noexecstack" "--trap" "--keep-locals" +// CHECK029: "--noexecstack" "--trap" "--keep-locals" // CHECK029-NEXT: "{{.*}}/bin/hexagon-ld" diff --git a/test/Driver/hexagon-toolchain.c b/test/Driver/hexagon-toolchain.c index bfa627c..3e66f35 100644 --- a/test/Driver/hexagon-toolchain.c +++ b/test/Driver/hexagon-toolchain.c @@ -560,5 +560,5 @@ // RUN: | FileCheck -check-prefix=CHECK029 %s // CHECK029: "{{.*}}clang{{.*}}" "-cc1" // CHECK029-NEXT: "{{.*}}/bin/hexagon-as" -// CHECK029: "-gdwarf-2" "--noexecstack" "--trap" "--keep-locals" +// CHECK029: "--noexecstack" "--trap" "--keep-locals" // CHECK029-NEXT: "{{.*}}/bin/hexagon-ld" diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c index 79282cb..ebac718 100644 --- a/test/Driver/linux-ld.c +++ b/test/Driver/linux-ld.c @@ -245,6 +245,22 @@ // CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtend.o" // CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../../arm-linux-gnueabihf/crtn.o" // +// Check fedora 18 on arm. +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target armv7-unknown-linux-gnueabihf \ +// RUN: --sysroot=%S/Inputs/fedora_18_tree \ +// RUN: | FileCheck --check-prefix=CHECK-FEDORA-18-ARM-HF %s +// CHECK-FEDORA-18-ARM-HF: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/../../../crt1.o" +// CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/../../../crti.o" +// CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtbegin.o" +// CHECK-FEDORA-18-ARM-HF: "-L[[SYSROOT]]/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2" +// CHECK-FEDORA-18-ARM-HF: "-L[[SYSROOT]]/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/../../.." +// CHECK-FEDORA-18-ARM-HF: "-L[[SYSROOT]]/lib" +// CHECK-FEDORA-18-ARM-HF: "-L[[SYSROOT]]/usr/lib" +// CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtend.o" +// CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/../../../crtn.o" +// // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-unknown-linux-gnueabi \ // RUN: --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \ diff --git a/test/Driver/mips-abi.c b/test/Driver/mips-abi.c new file mode 100644 index 0000000..fd2b46f --- /dev/null +++ b/test/Driver/mips-abi.c @@ -0,0 +1,36 @@ +// Check passing Mips ABI options to the backend. +// +// RUN: %clang -target mips-linux-gnu -### -c %s \ +// RUN: -mabi=32 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ABI-32 %s +// MIPS-ABI-32: "-target-abi" "o32" +// +// RUN: %clang -target mips-linux-gnu -### -c %s \ +// RUN: -mabi=o32 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ABI-O32 %s +// MIPS-ABI-O32: "-target-abi" "o32" +// +// RUN: %clang -target mips-linux-gnu -### -c %s \ +// RUN: -mabi=n32 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ABI-N32 %s +// MIPS-ABI-N32: "-target-abi" "n32" +// +// RUN: %clang -target mips64-linux-gnu -### -c %s \ +// RUN: -mabi=64 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ABI-64 %s +// MIPS-ABI-64: "-target-abi" "n64" +// +// RUN: %clang -target mips64-linux-gnu -### -c %s \ +// RUN: -mabi=n64 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ABI-N64 %s +// MIPS-ABI-N64: "-target-abi" "n64" +// +// RUN: %clang -target mips64-linux-gnu -### -c %s \ +// RUN: -mabi=o64 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ABI-O64 %s +// MIPS-ABI-O64: "-target-abi" "o64" +// +// RUN: %clang -target mips-linux-gnu -### -c %s \ +// RUN: -mabi=eabi 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ABI-EABI %s +// MIPS-ABI-EABI: "-target-abi" "eabi" diff --git a/test/Driver/mips-as.c b/test/Driver/mips-as.c index 146b193..216b656 100644 --- a/test/Driver/mips-as.c +++ b/test/Driver/mips-as.c @@ -1,5 +1,3 @@ -// REQUIRES: mips-registered-target -// // Check passing options to the assembler for MIPS targets. // // RUN: %clang -target mips-linux-gnu -### \ @@ -73,3 +71,47 @@ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ALIAS-64R2 %s // MIPS-ALIAS-64R2: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB" +// +// RUN: %clang -target mips-linux-gnu -mno-mips16 -mips16 -### \ +// RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-16 %s +// MIPS-16: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mips16" +// +// RUN: %clang -target mips-linux-gnu -mips16 -mno-mips16 -### \ +// RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-N16 %s +// MIPS-N16: as{{(.exe)?}}" +// MIPS-N16-NOT: "-mips16" +// +// RUN: %clang -target mips-linux-gnu -mno-micromips -mmicromips -### \ +// RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-MICRO %s +// MIPS-MICRO: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mmicromips" +// +// RUN: %clang -target mips-linux-gnu -mmicromips -mno-micromips -### \ +// RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-NMICRO %s +// MIPS-NMICRO: as{{(.exe)?}}" +// MIPS-NMICRO-NOT: "-mmicromips" +// +// RUN: %clang -target mips-linux-gnu -mno-dsp -mdsp -### \ +// RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-DSP %s +// MIPS-DSP: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mdsp" +// +// RUN: %clang -target mips-linux-gnu -mdsp -mno-dsp -### \ +// RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-NDSP %s +// MIPS-NDSP: as{{(.exe)?}}" +// MIPS-NDSP-NOT: "-mdsp" +// +// RUN: %clang -target mips-linux-gnu -mno-dspr2 -mdspr2 -### \ +// RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-DSPR2 %s +// MIPS-DSPR2: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mdspr2" +// +// RUN: %clang -target mips-linux-gnu -mdspr2 -mno-dspr2 -### \ +// RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-NDSPR2 %s +// MIPS-NDSPR2: as{{(.exe)?}}" +// MIPS-NDSPR2-NOT: "-mdspr2" diff --git a/test/Driver/mips-cs-header-search.cpp b/test/Driver/mips-cs-header-search.cpp new file mode 100644 index 0000000..e59fadc --- /dev/null +++ b/test/Driver/mips-cs-header-search.cpp @@ -0,0 +1,257 @@ +// Check frontend invocations on Mentor Graphics MIPS toolchain. +// +// = Big-endian, hard float +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-HF-32 %s +// CHECK-BE-HF-32: "-internal-isystem" +// CHECK-BE-HF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-BE-HF-32: "-internal-isystem" +// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu" +// CHECK-BE-HF-32: "-internal-isystem" +// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-BE-HF-32: "-internal-externc-isystem" +// CHECK-BE-HF-32: "[[TC]]/include" +// CHECK-BE-HF-32: "-internal-externc-isystem" +// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Big-endian, hard float, mips16 +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -mips16 \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-HF-16 %s +// CHECK-BE-HF-16: "-internal-isystem" +// CHECK-BE-HF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-BE-HF-16: "-internal-isystem" +// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16" +// CHECK-BE-HF-16: "-internal-isystem" +// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-BE-HF-16: "-internal-externc-isystem" +// CHECK-BE-HF-16: "[[TC]]/include" +// CHECK-BE-HF-16: "-internal-externc-isystem" +// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Big-endian, hard float, micromips +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -mmicromips \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-HF-MICRO %s +// CHECK-BE-HF-MICRO: "-internal-isystem" +// CHECK-BE-HF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-BE-HF-MICRO: "-internal-isystem" +// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips" +// CHECK-BE-HF-MICRO: "-internal-isystem" +// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-BE-HF-MICRO: "-internal-externc-isystem" +// CHECK-BE-HF-MICRO: "[[TC]]/include" +// CHECK-BE-HF-MICRO: "-internal-externc-isystem" +// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Big-endian, soft float +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -msoft-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-SF-32 %s +// CHECK-BE-SF-32: "-internal-isystem" +// CHECK-BE-SF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-BE-SF-32: "-internal-isystem" +// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float" +// CHECK-BE-SF-32: "-internal-isystem" +// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-BE-SF-32: "-internal-externc-isystem" +// CHECK-BE-SF-32: "[[TC]]/include" +// CHECK-BE-SF-32: "-internal-externc-isystem" +// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Big-endian, soft float, mips16 +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -msoft-float -mips16 \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-SF-16 %s +// CHECK-BE-SF-16: "-internal-isystem" +// CHECK-BE-SF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-BE-SF-16: "-internal-isystem" +// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/soft-float" +// CHECK-BE-SF-16: "-internal-isystem" +// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-BE-SF-16: "-internal-externc-isystem" +// CHECK-BE-SF-16: "[[TC]]/include" +// CHECK-BE-SF-16: "-internal-externc-isystem" +// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Big-endian, soft float, micromips +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -msoft-float -mmicromips \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-SF-MICRO %s +// CHECK-BE-SF-MICRO: "-internal-isystem" +// CHECK-BE-SF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-BE-SF-MICRO: "-internal-isystem" +// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/soft-float" +// CHECK-BE-SF-MICRO: "-internal-isystem" +// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-BE-SF-MICRO: "-internal-externc-isystem" +// CHECK-BE-SF-MICRO: "[[TC]]/include" +// CHECK-BE-SF-MICRO: "-internal-externc-isystem" +// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Big-endian, hard float, 64-bit +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mips64-linux-gnu \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-HF-64 %s +// CHECK-BE-HF-64: "-internal-isystem" +// CHECK-BE-HF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-BE-HF-64: "-internal-isystem" +// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/64" +// CHECK-BE-HF-64: "-internal-isystem" +// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-BE-HF-64: "-internal-externc-isystem" +// CHECK-BE-HF-64: "[[TC]]/include" +// CHECK-BE-HF-64: "-internal-externc-isystem" +// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Big-endian, soft float, 64-bit +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mips64-linux-gnu -msoft-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-SF-64 %s +// CHECK-BE-SF-64: "-internal-isystem" +// CHECK-BE-SF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-BE-SF-64: "-internal-isystem" +// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/64" +// CHECK-BE-SF-64: "-internal-isystem" +// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-BE-SF-64: "-internal-externc-isystem" +// CHECK-BE-SF-64: "[[TC]]/include" +// CHECK-BE-SF-64: "-internal-externc-isystem" +// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Little-endian, hard float +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mhard-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-HF-32 %s +// CHECK-EL-HF-32: "-internal-isystem" +// CHECK-EL-HF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-EL-HF-32: "-internal-isystem" +// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/el" +// CHECK-EL-HF-32: "-internal-isystem" +// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-EL-HF-32: "-internal-externc-isystem" +// CHECK-EL-HF-32: "[[TC]]/include" +// CHECK-EL-HF-32: "-internal-externc-isystem" +// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Little-endian, hard float, mips16 +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mips16 \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-HF-16 %s +// CHECK-EL-HF-16: "-internal-isystem" +// CHECK-EL-HF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-EL-HF-16: "-internal-isystem" +// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/el" +// CHECK-EL-HF-16: "-internal-isystem" +// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-EL-HF-16: "-internal-externc-isystem" +// CHECK-EL-HF-16: "[[TC]]/include" +// CHECK-EL-HF-16: "-internal-externc-isystem" +// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Little-endian, hard float, micromips +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mmicromips \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-HF-MICRO %s +// CHECK-EL-HF-MICRO: "-internal-isystem" +// CHECK-EL-HF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-EL-HF-MICRO: "-internal-isystem" +// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/el" +// CHECK-EL-HF-MICRO: "-internal-isystem" +// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-EL-HF-MICRO: "-internal-externc-isystem" +// CHECK-EL-HF-MICRO: "[[TC]]/include" +// CHECK-EL-HF-MICRO: "-internal-externc-isystem" +// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Little-endian, soft float +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mfloat-abi=soft \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-SF-32 %s +// CHECK-EL-SF-32: "-internal-isystem" +// CHECK-EL-SF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-EL-SF-32: "-internal-isystem" +// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/el" +// CHECK-EL-SF-32: "-internal-isystem" +// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-EL-SF-32: "-internal-externc-isystem" +// CHECK-EL-SF-32: "[[TC]]/include" +// CHECK-EL-SF-32: "-internal-externc-isystem" +// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Little-endian, soft float, mips16 +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mips16 -msoft-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-SF-16 %s +// CHECK-EL-SF-16: "-internal-isystem" +// CHECK-EL-SF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-EL-SF-16: "-internal-isystem" +// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/soft-float/el" +// CHECK-EL-SF-16: "-internal-isystem" +// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-EL-SF-16: "-internal-externc-isystem" +// CHECK-EL-SF-16: "[[TC]]/include" +// CHECK-EL-SF-16: "-internal-externc-isystem" +// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Little-endian, soft float, micromips +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mmicromips -msoft-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-SF-MICRO %s +// CHECK-EL-SF-MICRO: "-internal-isystem" +// CHECK-EL-SF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-EL-SF-MICRO: "-internal-isystem" +// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/soft-float/el" +// CHECK-EL-SF-MICRO: "-internal-isystem" +// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-EL-SF-MICRO: "-internal-externc-isystem" +// CHECK-EL-SF-MICRO: "[[TC]]/include" +// CHECK-EL-SF-MICRO: "-internal-externc-isystem" +// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Little-endian, hard float, 64-bit +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mips64el-linux-gnu \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-HF-64 %s +// CHECK-EL-HF-64: "-internal-isystem" +// CHECK-EL-HF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-EL-HF-64: "-internal-isystem" +// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/el/64" +// CHECK-EL-HF-64: "-internal-isystem" +// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-EL-HF-64: "-internal-externc-isystem" +// CHECK-EL-HF-64: "[[TC]]/include" +// CHECK-EL-HF-64: "-internal-externc-isystem" +// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" +// +// = Little-endian, soft float, 64-bit +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target mips64el-linux-gnu -msoft-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-SF-64 %s +// CHECK-EL-SF-64: "-internal-isystem" +// CHECK-EL-SF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3" +// CHECK-EL-SF-64: "-internal-isystem" +// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/el/64" +// CHECK-EL-SF-64: "-internal-isystem" +// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward" +// CHECK-EL-SF-64: "-internal-externc-isystem" +// CHECK-EL-SF-64: "[[TC]]/include" +// CHECK-EL-SF-64: "-internal-externc-isystem" +// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include" diff --git a/test/Driver/mips-cs-ld.c b/test/Driver/mips-cs-ld.c new file mode 100644 index 0000000..ac3adfd --- /dev/null +++ b/test/Driver/mips-cs-ld.c @@ -0,0 +1,288 @@ +// Check ld invocations on Mentor Graphics MIPS toolchain. +// +// = Big-endian, hard float +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-HF-32 %s +// CHECK-BE-HF-32: "{{.*}}ld{{(.exe)?}}" +// CHECK-BE-HF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc" +// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib/crt1.o" +// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib/crti.o" +// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/crtbegin.o" +// CHECK-BE-HF-32: "-L[[TC]]" +// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib" +// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/lib" +// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/usr/lib" +// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/crtend.o" +// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib/crtn.o" +// +// = Big-endian, hard float, mips16 +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -mips16 \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-HF-16 %s +// CHECK-BE-HF-16: "{{.*}}ld{{(.exe)?}}" +// CHECK-BE-HF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16" +// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib/crt1.o" +// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib/crti.o" +// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtbegin.o" +// CHECK-BE-HF-16: "-L[[TC]]/mips16" +// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16" +// CHECK-BE-HF-16: "-L[[TC]]" +// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/lib" +// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/usr/lib" +// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtend.o" +// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib/crtn.o" +// +// = Big-endian, hard float, mmicromips +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -mmicromips \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-HF-MICRO %s +// CHECK-BE-HF-MICRO: "{{.*}}ld{{(.exe)?}}" +// CHECK-BE-HF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips" +// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib/crt1.o" +// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib/crti.o" +// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtbegin.o" +// CHECK-BE-HF-MICRO: "-L[[TC]]/micromips" +// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips" +// CHECK-BE-HF-MICRO: "-L[[TC]]" +// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/lib" +// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/usr/lib" +// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtend.o" +// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib/crtn.o" +// +// = Big-endian, soft float +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -msoft-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-SF-32 %s +// CHECK-BE-SF-32: "{{.*}}ld{{(.exe)?}}" +// CHECK-BE-SF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float" +// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib/crt1.o" +// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib/crti.o" +// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtbegin.o" +// CHECK-BE-SF-32: "-L[[TC]]/soft-float" +// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/soft-float" +// CHECK-BE-SF-32: "-L[[TC]]" +// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/lib" +// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib" +// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtend.o" +// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib/crtn.o" +// +// = Big-endian, soft float, mips16 +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -msoft-float -mips16 \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-SF-16 %s +// CHECK-BE-SF-16: "{{.*}}ld{{(.exe)?}}" +// CHECK-BE-SF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16/soft-float" +// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib/crt1.o" +// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib/crti.o" +// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtbegin.o" +// CHECK-BE-SF-16: "-L[[TC]]/mips16/soft-float" +// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/soft-float" +// CHECK-BE-SF-16: "-L[[TC]]" +// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/lib" +// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib" +// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtend.o" +// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib/crtn.o" +// +// = Big-endian, soft float, micromips +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -msoft-float -mmicromips \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-SF-MICRO %s +// CHECK-BE-SF-MICRO: "{{.*}}ld{{(.exe)?}}" +// CHECK-BE-SF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips/soft-float" +// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib/crt1.o" +// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib/crti.o" +// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtbegin.o" +// CHECK-BE-SF-MICRO: "-L[[TC]]/micromips/soft-float" +// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/soft-float" +// CHECK-BE-SF-MICRO: "-L[[TC]]" +// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/lib" +// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib" +// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtend.o" +// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib/crtn.o" +// +// = Big-endian, hard float, 64-bit +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mips64-linux-gnu \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-HF-64 %s +// CHECK-BE-HF-64: "{{.*}}ld{{(.exe)?}}" +// CHECK-BE-HF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc" +// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib64/crt1.o" +// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib64/crti.o" +// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/64/crtbegin.o" +// CHECK-BE-HF-64: "-L[[TC]]/64" +// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64" +// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/lib/../lib64" +// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/usr/lib/../lib64" +// CHECK-BE-HF-64: "-L[[TC]]" +// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/64/crtend.o" +// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib64/crtn.o" +// +// = Big-endian, soft float, 64-bit +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mips64-linux-gnu -msoft-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-BE-SF-64 %s +// CHECK-BE-SF-64: "{{.*}}ld{{(.exe)?}}" +// CHECK-BE-SF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float" +// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64/crt1.o" +// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64/crti.o" +// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtbegin.o" +// CHECK-BE-SF-64: "-L[[TC]]/soft-float/64" +// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/soft-float" +// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/lib/../lib64" +// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64" +// CHECK-BE-SF-64: "-L[[TC]]" +// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtend.o" +// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64/crtn.o" +// +// = Little-endian, hard float +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mhard-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-HF-32 %s +// CHECK-EL-HF-32: "{{.*}}ld{{(.exe)?}}" +// CHECK-EL-HF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/el" +// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib/crt1.o" +// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib/crti.o" +// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el/crtbegin.o" +// CHECK-EL-HF-32: "-L[[TC]]/el" +// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/el" +// CHECK-EL-HF-32: "-L[[TC]]" +// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/lib" +// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib" +// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el/crtend.o" +// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib/crtn.o" +// +// = Little-endian, hard float, mips16 +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mips16 \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-HF-16 %s +// CHECK-EL-HF-16: "{{.*}}ld{{(.exe)?}}" +// CHECK-EL-HF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16/el" +// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib/crt1.o" +// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib/crti.o" +// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtbegin.o" +// CHECK-EL-HF-16: "-L[[TC]]/mips16/el" +// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/el" +// CHECK-EL-HF-16: "-L[[TC]]" +// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/el/lib" +// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/el/usr/lib" +// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtend.o" +// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib/crtn.o" +// +// = Little-endian, hard float, micromips +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mmicromips \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-HF-MICRO %s +// CHECK-EL-HF-MICRO: "{{.*}}ld{{(.exe)?}}" +// CHECK-EL-HF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips/el" +// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib/crt1.o" +// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib/crti.o" +// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtbegin.o" +// CHECK-EL-HF-MICRO: "-L[[TC]]/micromips/el" +// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/el" +// CHECK-EL-HF-MICRO: "-L[[TC]]" +// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/el/lib" +// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/el/usr/lib" +// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtend.o" +// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib/crtn.o" +// +// = Little-endian, soft float +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mfloat-abi=soft \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-SF-32 %s +// CHECK-EL-SF-32: "{{.*}}ld{{(.exe)?}}" +// CHECK-EL-SF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float/el" +// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib/crt1.o" +// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib/crti.o" +// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtbegin.o" +// CHECK-EL-SF-32: "-L[[TC]]/soft-float/el" +// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/soft-float/el" +// CHECK-EL-SF-32: "-L[[TC]]" +// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/lib" +// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib" +// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtend.o" +// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib/crtn.o" +// +// = Little-endian, soft float, mips16 +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mips16 -msoft-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-SF-16 %s +// CHECK-EL-SF-16: "{{.*}}ld{{(.exe)?}}" +// CHECK-EL-SF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el" +// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib/crt1.o" +// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib/crti.o" +// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtbegin.o" +// CHECK-EL-SF-16: "-L[[TC]]/mips16/soft-float/el" +// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/soft-float/el" +// CHECK-EL-SF-16: "-L[[TC]]" +// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el/lib" +// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib" +// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtend.o" +// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib/crtn.o" +// +// = Little-endian, soft float, micromips +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mipsel-linux-gnu -mmicromips -msoft-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-SF-MICRO %s +// CHECK-EL-SF-MICRO: "{{.*}}ld{{(.exe)?}}" +// CHECK-EL-SF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el" +// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib/crt1.o" +// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib/crti.o" +// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtbegin.o" +// CHECK-EL-SF-MICRO: "-L[[TC]]/micromips/soft-float/el" +// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/soft-float/el" +// CHECK-EL-SF-MICRO: "-L[[TC]]" +// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el/lib" +// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib" +// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtend.o" +// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib/crtn.o" +// +// = Little-endian, hard float, 64-bit +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mips64el-linux-gnu \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-HF-64 %s +// CHECK-EL-HF-64: "{{.*}}ld{{(.exe)?}}" +// CHECK-EL-HF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/el" +// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64/crt1.o" +// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64/crti.o" +// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtbegin.o" +// CHECK-EL-HF-64: "-L[[TC]]/el/64" +// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/el" +// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/lib/../lib64" +// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64" +// CHECK-EL-HF-64: "-L[[TC]]" +// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtend.o" +// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64/crtn.o" +// +// = Little-endian, soft float, 64-bit +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target mips64el-linux-gnu -msoft-float \ +// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \ +// RUN: | FileCheck --check-prefix=CHECK-EL-SF-64 %s +// CHECK-EL-SF-64: "{{.*}}ld{{(.exe)?}}" +// CHECK-EL-SF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float/el" +// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64/crt1.o" +// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64/crti.o" +// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtbegin.o" +// CHECK-EL-SF-64: "-L[[TC]]/soft-float/el/64" +// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/soft-float/el" +// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/lib/../lib64" +// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64" +// CHECK-EL-SF-64: "-L[[TC]]" +// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtend.o" +// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64/crtn.o" diff --git a/test/Driver/mips-eleb.c b/test/Driver/mips-eleb.c index 8afe44f..6ea49be 100644 --- a/test/Driver/mips-eleb.c +++ b/test/Driver/mips-eleb.c @@ -1,29 +1,27 @@ -// REQUIRES: mips-registered-target -// // Check that -EL/-EB options adjust the toolchain flags. // -// RUN: %clang -target mips-unknown-linux-gnu -### \ +// RUN: %clang -no-canonical-prefixes -target mips-unknown-linux-gnu -### \ // RUN: -EL -no-integrated-as %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS32-EL %s // MIPS32-EL: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mipsel-unknown-linux-gnu" // MIPS32-EL: "{{.*}}as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EL" // MIPS32-EL: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf32ltsmip" // -// RUN: %clang -target mips64-unknown-linux-gnu -### \ +// RUN: %clang -no-canonical-prefixes -target mips64-unknown-linux-gnu -### \ // RUN: -EL -no-integrated-as %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS64-EL %s // MIPS64-EL: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mips64el-unknown-linux-gnu" // MIPS64-EL: "{{.*}}as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EL" // MIPS64-EL: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf64ltsmip" // -// RUN: %clang -target mipsel-unknown-linux-gnu -### \ +// RUN: %clang -no-canonical-prefixes -target mipsel-unknown-linux-gnu -### \ // RUN: -EB -no-integrated-as %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS32-EB %s // MIPS32-EB: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mips-unknown-linux-gnu" // MIPS32-EB: "{{.*}}as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" // MIPS32-EB: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf32btsmip" // -// RUN: %clang -target mips64el-unknown-linux-gnu -### \ +// RUN: %clang -no-canonical-prefixes -target mips64el-unknown-linux-gnu -### \ // RUN: -EB -no-integrated-as %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS64-EB %s // MIPS64-EB: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mips64-unknown-linux-gnu" diff --git a/test/Driver/mips-features.c b/test/Driver/mips-features.c index 3bebffc..31bf193 100644 --- a/test/Driver/mips-features.c +++ b/test/Driver/mips-features.c @@ -1,5 +1,3 @@ -// REQUIRES: mips-registered-target -// // Check handling MIPS specific features options. // // -mips16 @@ -14,6 +12,18 @@ // RUN: | FileCheck --check-prefix=CHECK-NOMIPS16 %s // CHECK-NOMIPS16: "-target-feature" "-mips16" // +// -mmicromips +// RUN: %clang -target mips-linux-gnu -### -c %s \ +// RUN: -mno-micromips -mmicromips 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-MICROMIPS %s +// CHECK-MICROMIPS: "-target-feature" "+micromips" +// +// -mno-micromips +// RUN: %clang -target mips-linux-gnu -### -c %s \ +// RUN: -mmicromips -mno-micromips 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NOMICROMIPS %s +// CHECK-NOMICROMIPS: "-target-feature" "-micromips" +// // -mdsp // RUN: %clang -target mips-linux-gnu -### -c %s \ // RUN: -mno-dsp -mdsp 2>&1 \ diff --git a/test/Driver/mips-float.c b/test/Driver/mips-float.c index 5c16b9b..9e62c0a 100644 --- a/test/Driver/mips-float.c +++ b/test/Driver/mips-float.c @@ -1,4 +1,3 @@ -// REQUIRES: mips-registered-target // Check handling -mhard-float / -msoft-float / -mfloat-abi options // when build for MIPS platforms. // @@ -36,12 +35,27 @@ // CHECK-ABI-SOFT: "-mfloat-abi" "soft" // CHECK-ABI-SOFT: "-target-feature" "+soft-float" // -// -mfloat-abi=single +// -mdouble-float // RUN: %clang -c %s -### -o %t.o 2>&1 \ -// RUN: -target mips-linux-gnu -mfloat-abi=single \ +// RUN: -target mips-linux-gnu -msingle-float -mdouble-float \ +// RUN: | FileCheck --check-prefix=CHECK-ABI-DOUBLE %s +// CHECK-ABI-DOUBLE: "-mfloat-abi" "hard" +// CHECK-ABI-DOUBLE-NOT: "+single-float" +// +// -msingle-float +// RUN: %clang -c %s -### -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -mdouble-float -msingle-float \ // RUN: | FileCheck --check-prefix=CHECK-ABI-SINGLE %s +// CHECK-ABI-SINGLE: "-mfloat-abi" "hard" // CHECK-ABI-SINGLE: "-target-feature" "+single-float" // +// -msoft-float -msingle-float +// RUN: %clang -c %s -### -o %t.o 2>&1 \ +// RUN: -target mips-linux-gnu -msoft-float -msingle-float \ +// RUN: | FileCheck --check-prefix=CHECK-ABI-SOFT-SINGLE %s +// CHECK-ABI-SOFT-SINGLE: "-mfloat-abi" "soft" +// CHECK-ABI-SOFT-SINGLE: "-target-feature" "+single-float" +// // Default -mips16 // RUN: %clang -c %s -### -o %t.o 2>&1 \ // RUN: -target mips-linux-gnu -mips16 \ diff --git a/test/Driver/modules.m b/test/Driver/modules.m index 69c79fc..b93054d 100644 --- a/test/Driver/modules.m +++ b/test/Driver/modules.m @@ -4,9 +4,3 @@ // RUN: %clang -fmodules -fno-modules -fmodules -### %s 2>&1 | FileCheck -check-prefix=CHECK-HAS-MODULES %s // CHECK-HAS-MODULES: -fmodules -// RUN: %clang -target x86_64-apple-darwin10 -fmodules -fno-modules -fmodules -### %s 2>&1 | FileCheck -check-prefix=CHECK-HAS-AUTOLINK %s -// CHECK-HAS-AUTOLINK: -fmodules-autolink - -// RUN: %clang -fmodules -fno-modules -fno-modules-autolink -fmodules -### %s 2>&1 | FileCheck -check-prefix=CHECK-NO-AUTOLINK %s -// CHECK-NO-AUTOLINK-NOT: -fmodules-autolink - diff --git a/test/Driver/modules_integrated_as.c b/test/Driver/modules_integrated_as.c deleted file mode 100644 index 0abd18f..0000000 --- a/test/Driver/modules_integrated_as.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %clang -fsyntax-only modules_integrated_as.c -fmodules -no-integrated-as -### 2>&1 | FileCheck %s - -// Test that the autolinking feature is disabled with *not* using the -// integrated assembler. - -// CHECK-NOT: -fmodules-autolink diff --git a/test/Driver/objc++-cpp-output.mm b/test/Driver/objc++-cpp-output.mm index 63b15d8..a42f7b2 100644 --- a/test/Driver/objc++-cpp-output.mm +++ b/test/Driver/objc++-cpp-output.mm @@ -1,5 +1,5 @@ -// RUN: %clang -x objc++-cpp-output -c %s -o /dev/null -// RUN: %clang -x objc++-cpp-output -c %s -o /dev/null -### 2>&1 | FileCheck %s +// RUN: %clang -emit-llvm -x objc++-cpp-output -S %s -o /dev/null +// RUN: %clang -emit-llvm -x objc++-cpp-output -S %s -o /dev/null -### 2>&1 | FileCheck %s // PR13820 // REQUIRES: LP64 diff --git a/test/Driver/objc-cpp-output.m b/test/Driver/objc-cpp-output.m index 8c174f7..293bbc7 100644 --- a/test/Driver/objc-cpp-output.m +++ b/test/Driver/objc-cpp-output.m @@ -1,4 +1,4 @@ -// RUN: %clang -x objc-cpp-output -c %s -o /dev/null +// RUN: %clang -emit-llvm -x objc-cpp-output -S %s -o /dev/null // PR13820 // REQUIRES: LP64 diff --git a/test/Driver/output-file-is-dir.c b/test/Driver/output-file-is-dir.c index c1fec56..042ae3d 100644 --- a/test/Driver/output-file-is-dir.c +++ b/test/Driver/output-file-is-dir.c @@ -1,7 +1,6 @@ // RUN: rm -rf %t.dir -// RUN: mkdir -p %t.dir/a.out -// RUN: cd %t.dir && not %clang %s -// RUN: test -d %t.dir/a.out -// REQUIRES: shell +// RUN: mkdir -p %t.dir +// RUN: not %clang %s -c -emit-llvm -o %t.dir +// RUN: test -d %t.dir int main() { return 0; } diff --git a/test/Driver/pic.c b/test/Driver/pic.c index 8ba9319..3faed2d 100644 --- a/test/Driver/pic.c +++ b/test/Driver/pic.c @@ -36,6 +36,8 @@ // // CHECK-NO-PIE-NOT: "-pie" // +// CHECK-NO-UNUSED-ARG-NOT: argument unused during compilation +// // RUN: %clang -c %s -target i386-unknown-unknown -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC // RUN: %clang -c %s -target i386-unknown-unknown -fpic -### 2>&1 \ @@ -164,6 +166,8 @@ // RUN: | FileCheck %s --check-prefix=CHECK-PIC2 // RUN: %clang -c %s -target x86_64-apple-darwin -fPIE -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-PIC2 +// RUN: %clang -c %s -target x86_64-apple-darwin -fPIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-UNUSED-ARG // // Darwin gets even more special with '-mdynamic-no-pic'. This flag is only // valid on Darwin, and it's behavior is very strange but needs to remain diff --git a/test/Driver/r600-mcpu.cl b/test/Driver/r600-mcpu.cl index 70e8116..1c5e762 100644 --- a/test/Driver/r600-mcpu.cl +++ b/test/Driver/r600-mcpu.cl @@ -1,12 +1,12 @@ // Check that -mcpu works for all supported GPUs // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=r600 %s -o - 2>&1 | FileCheck --check-prefix=R600-CHECK %s -// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv610 %s -o - 2>&1 | FileCheck --check-prefix=R600-CHECK %s -// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv620 %s -o - 2>&1 | FileCheck --check-prefix=R600-CHECK %s // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv630 %s -o - 2>&1 | FileCheck --check-prefix=R600-CHECK %s // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv635 %s -o - 2>&1 | FileCheck --check-prefix=R600-CHECK %s -// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rs780 %s -o - 2>&1 | FileCheck --check-prefix=R600-CHECK %s -// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rs880 %s -o - 2>&1 | FileCheck --check-prefix=R600-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv610 %s -o - 2>&1 | FileCheck --check-prefix=RS880-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv620 %s -o - 2>&1 | FileCheck --check-prefix=RS880-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rs780 %s -o - 2>&1 | FileCheck --check-prefix=RS880-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rs880 %s -o - 2>&1 | FileCheck --check-prefix=RS880-CHECK %s // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv670 %s -o - 2>&1 | FileCheck --check-prefix=RV670-CHECK %s // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv710 %s -o - 2>&1 | FileCheck --check-prefix=RV710-CHECK %s // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv730 %s -o - 2>&1 | FileCheck --check-prefix=RV730-CHECK %s @@ -14,8 +14,8 @@ // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv770 %s -o - 2>&1 | FileCheck --check-prefix=RV770-CHECK %s // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=palm %s -o - 2>&1 | FileCheck --check-prefix=CEDAR-CHECK %s // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=cedar %s -o - 2>&1 | FileCheck --check-prefix=CEDAR-CHECK %s -// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=sumo %s -o - 2>&1 | FileCheck --check-prefix=REDWOOD-CHECK %s -// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=sumo2 %s -o - 2>&1 | FileCheck --check-prefix=REDWOOD-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=sumo %s -o - 2>&1 | FileCheck --check-prefix=SUMO-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=sumo2 %s -o - 2>&1 | FileCheck --check-prefix=SUMO-CHECK %s // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=redwood %s -o - 2>&1 | FileCheck --check-prefix=REDWOOD-CHECK %s // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=juniper %s -o - 2>&1 | FileCheck --check-prefix=JUNIPER-CHECK %s // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=juniper %s -o - 2>&1 | FileCheck --check-prefix=JUNIPER-CHECK %s @@ -32,12 +32,14 @@ // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=oland %s -o - 2>&1 | FileCheck --check-prefix=OLAND-CHECK %s // R600-CHECK: "-target-cpu" "r600" +// RS880-CHECK: "-target-cpu" "rs880" // RV670-CHECK: "-target-cpu" "rv670" // RV710-CHECK: "-target-cpu" "rv710" // RV730-CHECK: "-target-cpu" "rv730" // RV770-CHECK: "-target-cpu" "rv770" // CEDAR-CHECK: "-target-cpu" "cedar" // REDWOOD-CHECK: "-target-cpu" "redwood" +// SUMO-CHECK: "-target-cpu" "sumo" // JUNIPER-CHECK: "-target-cpu" "juniper" // CYPRESS-CHECK: "-target-cpu" "cypress" // BARTS-CHECK: "-target-cpu" "barts" diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c index fd68b57..fd7e97f 100644 --- a/test/Driver/sanitizer-ld.c +++ b/test/Driver/sanitizer-ld.c @@ -10,6 +10,7 @@ // CHECK-ASAN-LINUX-NOT: "-lc" // CHECK-ASAN-LINUX: libclang_rt.asan-i386.a" // CHECK-ASAN-LINUX: "-lpthread" +// CHECK-ASAN-LINUX: "-lrt" // CHECK-ASAN-LINUX: "-ldl" // CHECK-ASAN-LINUX-NOT: "-export-dynamic" // CHECK-ASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.asan-i386.a.syms" @@ -24,6 +25,7 @@ // CHECK-ASAN-LINUX-CXX-NOT: "-lc" // CHECK-ASAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive" // CHECK-ASAN-LINUX-CXX: "-lpthread" +// CHECK-ASAN-LINUX-CXX: "-lrt" // CHECK-ASAN-LINUX-CXX: "-ldl" // CHECK-ASAN-LINUX-CXX: "-export-dynamic" // CHECK-ASAN-LINUX-CXX-NOT: "--dynamic-list" @@ -70,6 +72,7 @@ // CHECK-TSAN-LINUX-CXX-NOT: stdc++ // CHECK-TSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.tsan-x86_64.a" "-no-whole-archive" // CHECK-TSAN-LINUX-CXX: "-lpthread" +// CHECK-TSAN-LINUX-CXX: "-lrt" // CHECK-TSAN-LINUX-CXX: "-ldl" // CHECK-TSAN-LINUX-CXX-NOT: "-export-dynamic" // CHECK-TSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.tsan-x86_64.a.syms" @@ -85,6 +88,7 @@ // CHECK-MSAN-LINUX-CXX-NOT: stdc++ // CHECK-MSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.msan-x86_64.a" "-no-whole-archive" // CHECK-MSAN-LINUX-CXX: "-lpthread" +// CHECK-MSAN-LINUX-CXX: "-lrt" // CHECK-MSAN-LINUX-CXX: "-ldl" // CHECK-MSAN-LINUX-CXX-NOT: "-export-dynamic" // CHECK-MSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.msan-x86_64.a.syms" diff --git a/test/Driver/save-temps.c b/test/Driver/save-temps.c new file mode 100644 index 0000000..a4ca3b2 --- /dev/null +++ b/test/Driver/save-temps.c @@ -0,0 +1,19 @@ +// RUN: %clang -target x86_64-apple-darwin -save-temps -arch x86_64 %s -### 2>&1 \ +// RUN: | FileCheck %s +// CHECK: "-o" "save-temps.i" +// CHECK: "-o" "save-temps.s" +// CHECK: "-o" "save-temps.o" +// CHECK: "-o" "a.out" + +// RUN: %clang -target x86_64-apple-darwin -save-temps -arch i386 -arch x86_64 %s -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=MULT-ARCH +// MULT-ARCH: "-o" "save-temps-i386.i" +// MULT-ARCH: "-o" "save-temps-i386.s" +// MULT-ARCH: "-o" "save-temps-i386.o" +// MULT-ARCH: "-o" "a.out-i386" +// MULT-ARCH: "-o" "save-temps-x86_64.i" +// MULT-ARCH: "-o" "save-temps-x86_64.s" +// MULT-ARCH: "-o" "save-temps-x86_64.o" +// MULT-ARCH: "-o" "a.out-x86_64" +// MULT-ARCH: lipo +// MULT-ARCH: "-create" "-output" "a.out" "a.out-i386" "a.out-x86_64" diff --git a/test/Driver/split-debug.s b/test/Driver/split-debug.s new file mode 100644 index 0000000..d5f077a --- /dev/null +++ b/test/Driver/split-debug.s @@ -0,0 +1,21 @@ +// Check that we split debug output properly +// +// REQUIRES: asserts +// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -c -### %s 2> %t +// RUN: FileCheck -check-prefix=CHECK-ACTIONS < %t %s +// +// CHECK-ACTIONS: objcopy{{.*}}--extract-dwo{{.*}}"split-debug.dwo" +// CHECK-ACTIONS: objcopy{{.*}}--strip-dwo{{.*}}"split-debug.o" + + +// RUN: %clang -target x86_64-macosx -gsplit-dwarf -c -### %s 2> %t +// RUN: FileCheck -check-prefix=CHECK-NO-ACTIONS < %t %s +// +// CHECK-NO-ACTIONS-NOT: -split-dwarf + + +// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -o Bad.x -### %s 2> %t +// RUN: FileCheck -check-prefix=CHECK-BAD < %t %s +// +// CHECK-BAD-NOT: "Bad.dwo" + diff --git a/test/FixIt/fixit-cxx1y-compat.cpp b/test/FixIt/fixit-cxx1y-compat.cpp new file mode 100644 index 0000000..9fd5ff2 --- /dev/null +++ b/test/FixIt/fixit-cxx1y-compat.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -verify -std=c++11 %s +// RUN: cp %s %t +// RUN: %clang_cc1 -x c++ -std=c++11 -fixit %t +// RUN: %clang_cc1 -Wall -pedantic-errors -Werror -x c++ -std=c++11 %t +// RUN: %clang_cc1 -Wall -pedantic-errors -Werror -x c++ -std=c++1y %t + +// This is a test of the code modification hints for C++1y-compatibility problems. + +struct S { + constexpr int &f(); // expected-warning {{'constexpr' non-static member function will not be implicitly 'const' in C++1y; add 'const' to avoid a change in behavior}} + int &f(); +}; diff --git a/test/Format/basic.cpp b/test/Format/basic.cpp index 375bbd2..a12866b 100644 --- a/test/Format/basic.cpp +++ b/test/Format/basic.cpp @@ -1,5 +1,5 @@ // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: clang-format -i %t.cpp +// RUN: clang-format -style=LLVM -i %t.cpp // RUN: FileCheck -strict-whitespace -input-file=%t.cpp %s // CHECK: {{^int\ \*i;}} diff --git a/test/Format/multiple-inputs-error.cpp b/test/Format/multiple-inputs-error.cpp new file mode 100644 index 0000000..71f87e0 --- /dev/null +++ b/test/Format/multiple-inputs-error.cpp @@ -0,0 +1,6 @@ +// RUN: cp %s %t-1.cpp +// RUN: cp %s %t-2.cpp +// RUN: clang-format 2>&1 >/dev/null -offset=1 -length=0 %t-1.cpp %t-2.cpp |FileCheck %s +// CHECK: error: "-offset" and "-length" can only be used for single file. + +int i ; diff --git a/test/Format/multiple-inputs-inplace.cpp b/test/Format/multiple-inputs-inplace.cpp new file mode 100644 index 0000000..74c30db --- /dev/null +++ b/test/Format/multiple-inputs-inplace.cpp @@ -0,0 +1,8 @@ +// RUN: cp %s %t-1.cpp +// RUN: cp %s %t-2.cpp +// RUN: clang-format -style=LLVM -i %t-1.cpp %t-2.cpp +// RUN: FileCheck -strict-whitespace -input-file=%t-1.cpp %s +// RUN: FileCheck -strict-whitespace -input-file=%t-2.cpp %s + +// CHECK: {{^int\ \*i;}} + int * i ; diff --git a/test/Format/multiple-inputs.cpp b/test/Format/multiple-inputs.cpp new file mode 100644 index 0000000..df26714 --- /dev/null +++ b/test/Format/multiple-inputs.cpp @@ -0,0 +1,7 @@ +// RUN: cp %s %t-1.cpp +// RUN: cp %s %t-2.cpp +// RUN: clang-format -style=LLVM %t-1.cpp %t-2.cpp|FileCheck -strict-whitespace %s + +// CHECK: {{^int\ \*i;}} +// CHECK: {{^int\ \*i;}} + int * i ; diff --git a/test/Format/ranges.cpp b/test/Format/ranges.cpp index 0244fc1..c7fdd4b 100644 --- a/test/Format/ranges.cpp +++ b/test/Format/ranges.cpp @@ -1,5 +1,5 @@ // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: clang-format -offset=2 -length=0 -offset=28 -length=0 -i %t.cpp +// RUN: clang-format -style=LLVM -offset=2 -length=0 -offset=28 -length=0 -i %t.cpp // RUN: FileCheck -strict-whitespace -input-file=%t.cpp %s // CHECK: {{^int\ \*i;$}} int*i; diff --git a/test/Frontend/Inputs/rewrite-includes8.h b/test/Frontend/Inputs/rewrite-includes8.h new file mode 100644 index 0000000..e827ad9 --- /dev/null +++ b/test/Frontend/Inputs/rewrite-includes8.h @@ -0,0 +1,5 @@ +#if __has_include_next(<rewrite-includes8.h>) +#elif __has_include(<rewrite-includes8.hfail>) +#endif +#if !__has_include("rewrite-includes8.h") +#endif diff --git a/test/Frontend/rewrite-includes-invalid-hasinclude.c b/test/Frontend/rewrite-includes-invalid-hasinclude.c new file mode 100644 index 0000000..e32d6ad --- /dev/null +++ b/test/Frontend/rewrite-includes-invalid-hasinclude.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -E -frewrite-includes -DFIRST -I %S/Inputs %s -o - | FileCheck -strict-whitespace %s + +#if __has_include bar.h +#endif + +#if __has_include(bar.h) +#endif + +#if __has_include(<bar.h) +#endif + +// CHECK: #if __has_include bar.h +// CHECK: #endif +// CHECK: #if __has_include(bar.h) +// CHECK: #endif +// CHECK: #if __has_include(<bar.h) +// CHECK: #endif diff --git a/test/Frontend/rewrite-includes-missing.c b/test/Frontend/rewrite-includes-missing.c index b79bbd9..da4e209 100644 --- a/test/Frontend/rewrite-includes-missing.c +++ b/test/Frontend/rewrite-includes-missing.c @@ -4,4 +4,4 @@ // CHECK: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}} // CHECK-NEXT: {{^}}#include "foobar.h" // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}} -// CHECK-NEXT: {{^}}# 4 "{{.*}}rewrite-includes-missing.c" 2{{$}} +// CHECK-NEXT: {{^}}# 4 "{{.*}}rewrite-includes-missing.c"{{$}} diff --git a/test/Frontend/rewrite-includes-modules.c b/test/Frontend/rewrite-includes-modules.c new file mode 100644 index 0000000..783a967 --- /dev/null +++ b/test/Frontend/rewrite-includes-modules.c @@ -0,0 +1,20 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c %s -F %S/../Modules/Inputs -E -frewrite-includes -o - | FileCheck %s + +int bar(); +#include <Module/Module.h> +int foo(); +#include <Module/Module.h> + +// CHECK: int bar();{{$}} +// CHECK-NEXT: #if 0 /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: #include <Module/Module.h>{{$}} +// CHECK-NEXT: #endif /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: @import Module; /* clang -frewrite-includes: implicit import */{{$}} +// CHECK-NEXT: # 6 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}} +// CHECK-NEXT: int foo();{{$}} +// CHECK-NEXT: #if 0 /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: #include <Module/Module.h>{{$}} +// CHECK-NEXT: #endif /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: @import Module; /* clang -frewrite-includes: implicit import */{{$}} +// CHECK-NEXT: # 8 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}} diff --git a/test/Frontend/rewrite-includes.c b/test/Frontend/rewrite-includes.c index 546a2c4..bf330a6 100644 --- a/test/Frontend/rewrite-includes.c +++ b/test/Frontend/rewrite-includes.c @@ -18,6 +18,7 @@ A(1,2) continues */ #include "rewrite-includes7.h" #include "rewrite-includes7.h" +#include "rewrite-includes8.h" // ENDCOMPARE // CHECK: {{^}}// STARTCOMPARE{{$}} // CHECK-NEXT: {{^}}#define A(a,b) a ## b{{$}} @@ -88,6 +89,16 @@ A(1,2) // CHECK-NEXT: {{^}}#include "rewrite-includes7.h"{{$}} // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}} // CHECK-NEXT: {{^}}# 21 "{{.*}}rewrite-includes.c"{{$}} +// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: {{^}}#include "rewrite-includes8.h"{{$}} +// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs[/\\]}}rewrite-includes8.h" 1{{$}} +// CHECK-NEXT: {{^}}#if (1)/*__has_include_next(<rewrite-includes8.h>)*/{{$}} +// CHECK-NEXT: {{^}}#elif (0)/*__has_include(<rewrite-includes8.hfail>)*/{{$}} +// CHECK-NEXT: {{^}}#endif{{$}} +// CHECK-NEXT: {{^}}#if !(1)/*__has_include("rewrite-includes8.h")*/{{$}} +// CHECK-NEXT: {{^}}#endif{{$}} +// CHECK-NEXT: {{^}}# 22 "{{.*}}rewrite-includes.c" 2{{$}} // CHECK-NEXT: {{^}}// ENDCOMPARE{{$}} // CHECKNL: {{^}}// STARTCOMPARE{{$}} @@ -142,4 +153,12 @@ A(1,2) // CHECKNL-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}} // CHECKNL-NEXT: {{^}}#include "rewrite-includes7.h"{{$}} // CHECKNL-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}} +// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}} +// CHECKNL-NEXT: {{^}}#include "rewrite-includes8.h"{{$}} +// CHECKNL-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}} +// CHECKNL-NEXT: {{^}}#if (1)/*__has_include_next(<rewrite-includes8.h>)*/{{$}} +// CHECKNL-NEXT: {{^}}#elif (0)/*__has_include(<rewrite-includes8.hfail>)*/{{$}} +// CHECKNL-NEXT: {{^}}#endif{{$}} +// CHECKNL-NEXT: {{^}}#if !(1)/*__has_include("rewrite-includes8.h")*/{{$}} +// CHECKNL-NEXT: {{^}}#endif{{$}} // CHECKNL-NEXT: {{^}}// ENDCOMPARE{{$}} diff --git a/test/Frontend/rewrite-macros.c b/test/Frontend/rewrite-macros.c index bc74796..eab6657 100644 --- a/test/Frontend/rewrite-macros.c +++ b/test/Frontend/rewrite-macros.c @@ -1,17 +1,21 @@ -// RUN: %clang_cc1 -verify -rewrite-macros -o %t %s +// RUN: %clang_cc1 %s -verify -rewrite-macros -o %t +// RUN: FileCheck %s < %t + +// Any CHECK line comments are included in the output, so we use some extra +// regex brackets to make sure we don't match the CHECK lines themselves. #define A(a,b) a ## b -// RUN: grep '12 */\*A\*/ /\*(1,2)\*/' %t +// CHECK: {{^}} 12 /*A*/ /*(1,2)*/{{$}} A(1,2) -// RUN: grep '/\*_Pragma("mark")\*/' %t +// CHECK: {{^}} /*_Pragma("mark")*/{{$}} _Pragma("mark") -// RUN: grep "//#warning eek" %t +// CHECK: /*#warning eek*/{{$}} /* expected-warning {{eek}} */ #warning eek -// RUN: grep "//#pragma mark mark" %t +// CHECK: {{^}}//#pragma mark mark{{$}} #pragma mark mark diff --git a/test/Frontend/verify.c b/test/Frontend/verify.c index 062e6bd..3d71e04 100644 --- a/test/Frontend/verify.c +++ b/test/Frontend/verify.c @@ -124,3 +124,19 @@ unexpected b; // expected-error@33 1-1 {{unknown type}} // CHECK7-NEXT: Line 2: 2 // CHECK7-NEXT: 2 errors generated. #endif + +#ifdef TEST8 +// RUN: %clang_cc1 -DTEST8 -verify %s 2>&1 | FileCheck -check-prefix=CHECK8 %s + +// expected-warning@nonexistant-file:1 {{ }} +// expected-error@-1 {{file 'nonexistant-file' could not be located}} + +// expected-warning@verify-directive.h: {{ }} +// expected-error@-1 {{missing or invalid line number}} + +// expected-warning@verify-directive.h:1 {{diagnostic}} + +// CHECK8: error: 'warning' diagnostics expected but not seen: +// CHECK8-NEXT: File {{.*}}verify-directive.h Line 1 (directive at {{.*}}verify.c:137): diagnostic +// CHECK8-NEXT: 1 error generated. +#endif diff --git a/test/Headers/c11.c b/test/Headers/c11.c index f65164d1..21f2e4f 100644 --- a/test/Headers/c11.c +++ b/test/Headers/c11.c @@ -1,5 +1,6 @@ // RUN: %clang -fsyntax-only -Xclang -verify -std=c11 %s // RUN: %clang -fsyntax-only -Xclang -verify -std=c11 -fmodules %s +// RUN: %clang -fsyntax-only -Xclang -verify -std=c11 -ffreestanding %s noreturn int f(); // expected-error 1+{{}} @@ -17,3 +18,15 @@ _Static_assert(__alignas_is_defined, ""); _Static_assert(__alignof_is_defined, ""); alignas(alignof(int)) char c[4]; _Static_assert(__alignof(c) == 4, ""); + +#define __STDC_WANT_LIB_EXT1__ 1 +#include <stddef.h> +rsize_t x = 0; + +// If we are freestanding, then also check RSIZE_MAX (in a hosted implementation +// we will use the host stdint.h, which may not yet have C11 support). +#ifndef __STDC_HOSTED__ +#include <stdint.h> +rsize_t x2 = RSIZE_MAX; +#endif + diff --git a/test/Headers/cxx11.cpp b/test/Headers/cxx11.cpp index 41bdc76..54fe350 100644 --- a/test/Headers/cxx11.cpp +++ b/test/Headers/cxx11.cpp @@ -13,3 +13,10 @@ static_assert(__alignas_is_defined, ""); static_assert(__alignof_is_defined, ""); + + +#include <stdint.h> + +#ifndef SIZE_MAX +#error SIZE_MAX should be defined in C++ +#endif diff --git a/test/Headers/ms-wchar.c b/test/Headers/ms-wchar.c new file mode 100644 index 0000000..f015fc7 --- /dev/null +++ b/test/Headers/ms-wchar.c @@ -0,0 +1,15 @@ +// RUN: %clang -fsyntax-only -target i386-pc-win32 %s + +#if defined(_WCHAR_T_DEFINED) +#error "_WCHAR_T_DEFINED should not be defined in C99" +#endif + +#include <stddef.h> + +#if !defined(_WCHAR_T_DEFINED) +#error "_WCHAR_T_DEFINED should have been set by stddef.h" +#endif + +#if defined(_NATIVE_WCHAR_T_DEFINED) +#error "_NATIVE_WCHAR_T_DEFINED should not be defined" +#endif diff --git a/test/Index/annotate-module.m b/test/Index/annotate-module.m index 33ca3f8..55e21d2 100644 --- a/test/Index/annotate-module.m +++ b/test/Index/annotate-module.m @@ -40,3 +40,10 @@ int glob; // CHECK-MOD-NEXT: Punctuation: "*" [2:5 - 2:6] VarDecl=Module_Sub:2:6 // CHECK-MOD-NEXT: Identifier: "Module_Sub" [2:6 - 2:16] VarDecl=Module_Sub:2:6 // CHECK-MOD-NEXT: Punctuation: ";" [2:16 - 2:17] + +// RUN: c-index-test -cursor-at=%s:3:11 %s -fmodules-cache-path=%t.cache -fmodules -F %S/../Modules/Inputs \ +// RUN: | FileCheck %s -check-prefix=CHECK-CURSOR + +// CHECK-CURSOR: 3:1 ModuleImport=DependsOnModule:3:1 (Definition) Extent=[3:1 - 3:24] Spelling=DependsOnModule ([3:9 - 3:24]) ModuleName=DependsOnModule ({{.*}}DependsOnModule.pcm) Headers(2): +// CHECK-CURSOR-NEXT: {{.*}}other.h +// CHECK-CURSOR-NEXT: {{.*}}DependsOnModule.h diff --git a/test/Index/annotate-tokens.cpp b/test/Index/annotate-tokens.cpp index 3062901..1672654 100644 --- a/test/Index/annotate-tokens.cpp +++ b/test/Index/annotate-tokens.cpp @@ -20,7 +20,15 @@ void test3(S2 s2) { X foo; } -// RUN: c-index-test -test-annotate-tokens=%s:1:1:21:1 %s | FileCheck %s +template <bool (*tfn)(X*)> +struct TS { + void foo(); +}; + +template <bool (*tfn)(X*)> +void TS<tfn>::foo() {} + +// RUN: c-index-test -test-annotate-tokens=%s:1:1:30:1 %s -fno-delayed-template-parsing | FileCheck %s // CHECK: Keyword: "struct" [1:1 - 1:7] StructDecl=bonk:1:8 (Definition) // CHECK: Identifier: "bonk" [1:8 - 1:12] StructDecl=bonk:1:8 (Definition) // CHECK: Punctuation: "{" [1:13 - 1:14] StructDecl=bonk:1:8 (Definition) @@ -120,3 +128,48 @@ void test3(S2 s2) { // CHECK: Identifier: "foo" [20:5 - 20:8] VarDecl=foo:20:5 (Definition) // CHECK: Punctuation: ";" [20:8 - 20:9] DeclStmt= // CHECK: Punctuation: "}" [21:1 - 21:2] CompoundStmt= +// CHECK: Keyword: "template" [23:1 - 23:9] ClassTemplate=TS:24:8 (Definition) +// CHECK: Punctuation: "<" [23:10 - 23:11] ClassTemplate=TS:24:8 (Definition) +// CHECK: Keyword: "bool" [23:11 - 23:15] NonTypeTemplateParameter=tfn:23:18 (Definition) +// CHECK: Punctuation: "(" [23:16 - 23:17] NonTypeTemplateParameter=tfn:23:18 (Definition) +// CHECK: Punctuation: "*" [23:17 - 23:18] NonTypeTemplateParameter=tfn:23:18 (Definition) +// CHECK: Identifier: "tfn" [23:18 - 23:21] NonTypeTemplateParameter=tfn:23:18 (Definition) +// CHECK: Punctuation: ")" [23:21 - 23:22] NonTypeTemplateParameter=tfn:23:18 (Definition) +// CHECK: Punctuation: "(" [23:22 - 23:23] NonTypeTemplateParameter=tfn:23:18 (Definition) +// CHECK: Identifier: "X" [23:23 - 23:24] TypeRef=struct X:7:8 +// CHECK: Punctuation: "*" [23:24 - 23:25] ParmDecl=:23:25 (Definition) +// CHECK: Punctuation: ")" [23:25 - 23:26] ParmDecl=:23:25 (Definition) +// CHECK: Punctuation: ">" [23:26 - 23:27] ClassTemplate=TS:24:8 (Definition) +// CHECK: Keyword: "struct" [24:1 - 24:7] ClassTemplate=TS:24:8 (Definition) +// CHECK: Identifier: "TS" [24:8 - 24:10] ClassTemplate=TS:24:8 (Definition) +// CHECK: Punctuation: "{" [24:11 - 24:12] ClassTemplate=TS:24:8 (Definition) +// CHECK: Keyword: "void" [25:3 - 25:7] CXXMethod=foo:25:8 +// CHECK: Identifier: "foo" [25:8 - 25:11] CXXMethod=foo:25:8 +// CHECK: Punctuation: "(" [25:11 - 25:12] CXXMethod=foo:25:8 +// CHECK: Punctuation: ")" [25:12 - 25:13] CXXMethod=foo:25:8 +// CHECK: Punctuation: ";" [25:13 - 25:14] ClassTemplate=TS:24:8 (Definition) +// CHECK: Punctuation: "}" [26:1 - 26:2] ClassTemplate=TS:24:8 (Definition) +// CHECK: Punctuation: ";" [26:2 - 26:3] +// CHECK: Keyword: "template" [28:1 - 28:9] CXXMethod=foo:29:15 (Definition) +// CHECK: Punctuation: "<" [28:10 - 28:11] CXXMethod=foo:29:15 (Definition) +// CHECK: Keyword: "bool" [28:11 - 28:15] NonTypeTemplateParameter=tfn:28:18 (Definition) +// CHECK: Punctuation: "(" [28:16 - 28:17] NonTypeTemplateParameter=tfn:28:18 (Definition) +// CHECK: Punctuation: "*" [28:17 - 28:18] NonTypeTemplateParameter=tfn:28:18 (Definition) +// CHECK: Identifier: "tfn" [28:18 - 28:21] NonTypeTemplateParameter=tfn:28:18 (Definition) +// CHECK: Punctuation: ")" [28:21 - 28:22] NonTypeTemplateParameter=tfn:28:18 (Definition) +// CHECK: Punctuation: "(" [28:22 - 28:23] NonTypeTemplateParameter=tfn:28:18 (Definition) +// CHECK: Identifier: "X" [28:23 - 28:24] TypeRef=struct X:7:8 +// CHECK: Punctuation: "*" [28:24 - 28:25] ParmDecl=:28:25 (Definition) +// CHECK: Punctuation: ")" [28:25 - 28:26] ParmDecl=:28:25 (Definition) +// CHECK: Punctuation: ">" [28:26 - 28:27] CXXMethod=foo:29:15 (Definition) +// CHECK: Keyword: "void" [29:1 - 29:5] CXXMethod=foo:29:15 (Definition) +// CHECK: Identifier: "TS" [29:6 - 29:8] TemplateRef=TS:24:8 +// CHECK: Punctuation: "<" [29:8 - 29:9] CXXMethod=foo:29:15 (Definition) +// CHECK: Identifier: "tfn" [29:9 - 29:12] DeclRefExpr=tfn:28:18 +// CHECK: Punctuation: ">" [29:12 - 29:13] CXXMethod=foo:29:15 (Definition) +// CHECK: Punctuation: "::" [29:13 - 29:15] CXXMethod=foo:29:15 (Definition) +// CHECK: Identifier: "foo" [29:15 - 29:18] CXXMethod=foo:29:15 (Definition) +// CHECK: Punctuation: "(" [29:18 - 29:19] CXXMethod=foo:29:15 (Definition) +// CHECK: Punctuation: ")" [29:19 - 29:20] CXXMethod=foo:29:15 (Definition) +// CHECK: Punctuation: "{" [29:21 - 29:22] CompoundStmt= +// CHECK: Punctuation: "}" [29:22 - 29:23] CompoundStmt= diff --git a/test/Index/annotate-tokens.m b/test/Index/annotate-tokens.m index 7e888e3..40c66a1 100644 --- a/test/Index/annotate-tokens.m +++ b/test/Index/annotate-tokens.m @@ -281,7 +281,7 @@ static Rdar8595462_A * Rdar8595462_staticVar; // CHECK: Punctuation: ")" [40:19 - 40:20] CallExpr=ibaction_test:36:12 // CHECK: Punctuation: ";" [40:20 - 40:21] CompoundStmt= // CHECK: Punctuation: "[" [41:5 - 41:6] ObjCMessageExpr=foo::34:9 -// CHECK: Identifier: "self" [41:6 - 41:10] DeclRefExpr=self:0:0 +// CHECK: Identifier: "self" [41:6 - 41:10] ObjCSelfExpr=self:0:0 // CHECK: Identifier: "foo" [41:11 - 41:14] ObjCMessageExpr=foo::34:9 // CHECK: Punctuation: ":" [41:14 - 41:15] ObjCMessageExpr=foo::34:9 // CHECK: Literal: "0" [41:15 - 41:16] IntegerLiteral= @@ -391,7 +391,7 @@ static Rdar8595462_A * Rdar8595462_staticVar; // CHECK: Identifier: "local" [76:9 - 76:14] VarDecl=local:76:9 (Definition) // CHECK: Punctuation: "=" [76:15 - 76:16] VarDecl=local:76:9 (Definition) // CHECK: Punctuation: "[" [76:17 - 76:18] ObjCMessageExpr=foo::66:9 -// CHECK: Identifier: "self" [76:18 - 76:22] DeclRefExpr=self:0:0 +// CHECK: Identifier: "self" [76:18 - 76:22] ObjCSelfExpr=self:0:0 // CHECK: Identifier: "foo" [76:23 - 76:26] ObjCMessageExpr=foo::66:9 // CHECK: Punctuation: ":" [76:26 - 76:27] ObjCMessageExpr=foo::66:9 // CHECK: Identifier: "VAL" [76:27 - 76:30] macro expansion=VAL:63:9 @@ -401,7 +401,7 @@ static Rdar8595462_A * Rdar8595462_staticVar; // CHECK: Identifier: "second" [77:9 - 77:15] VarDecl=second:77:9 (Definition) // CHECK: Punctuation: "=" [77:16 - 77:17] VarDecl=second:77:9 (Definition) // CHECK: Punctuation: "[" [77:18 - 77:19] ObjCMessageExpr=foo::66:9 -// CHECK: Identifier: "self" [77:19 - 77:23] DeclRefExpr=self:0:0 +// CHECK: Identifier: "self" [77:19 - 77:23] ObjCSelfExpr=self:0:0 // CHECK: Identifier: "foo" [77:24 - 77:27] ObjCMessageExpr=foo::66:9 // CHECK: Punctuation: ":" [77:27 - 77:28] ObjCMessageExpr=foo::66:9 // CHECK: Literal: "0" [77:28 - 77:29] IntegerLiteral= @@ -518,7 +518,7 @@ static Rdar8595462_A * Rdar8595462_staticVar; // CHECK-INSIDE_BLOCK: Identifier: "result" [127:9 - 127:15] VarDecl=result:127:9 (Definition) // CHECK-INSIDE_BLOCK: Punctuation: "=" [127:16 - 127:17] VarDecl=result:127:9 (Definition) // CHECK-INSIDE_BLOCK: Punctuation: "[" [127:18 - 127:19] ObjCMessageExpr=blah::124:8 -// CHECK-INSIDE_BLOCK: Identifier: "self" [127:19 - 127:23] DeclRefExpr=self:0:0 +// CHECK-INSIDE_BLOCK: Identifier: "self" [127:19 - 127:23] ObjCSelfExpr=self:0:0 // CHECK-INSIDE_BLOCK: Identifier: "blah" [127:24 - 127:28] ObjCMessageExpr=blah::124:8 // CHECK-INSIDE_BLOCK: Punctuation: ":" [127:28 - 127:29] ObjCMessageExpr=blah::124:8 // CHECK-INSIDE_BLOCK: Literal: "5" [127:29 - 127:30] IntegerLiteral= @@ -530,7 +530,7 @@ static Rdar8595462_A * Rdar8595462_staticVar; // CHECK-INSIDE_BLOCK: Punctuation: "*" [128:17 - 128:18] VarDecl=a:128:18 (Definition) // CHECK-INSIDE_BLOCK: Identifier: "a" [128:18 - 128:19] VarDecl=a:128:18 (Definition) // CHECK-INSIDE_BLOCK: Punctuation: "=" [128:20 - 128:21] VarDecl=a:128:18 (Definition) -// CHECK-INSIDE_BLOCK: Identifier: "self" [128:22 - 128:26] DeclRefExpr=self:0:0 +// CHECK-INSIDE_BLOCK: Identifier: "self" [128:22 - 128:26] ObjCSelfExpr=self:0:0 // RUN: c-index-test -test-annotate-tokens=%s:134:1:138:1 %s -DIBOutlet='__attribute__((iboutlet))' -DIBAction='void)__attribute__((ibaction)' | FileCheck -check-prefix=CHECK-PROP-AFTER-METHOD %s // CHECK-PROP-AFTER-METHOD: Punctuation: "@" [134:1 - 134:2] ObjCInterfaceDecl=Rdar8062781:134:12 diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m index b0fb71e..61d82a6 100644 --- a/test/Index/c-index-api-loadTU-test.m +++ b/test/Index/c-index-api-loadTU-test.m @@ -169,7 +169,7 @@ struct X0 {}; // CHECK: c-index-api-loadTU-test.m:71:8: StructDecl=X0:71:8 (Definition) Extent=[71:1 - 71:14] // CHECK: c-index-api-loadTU-test.m:73:12: ObjCCategoryDecl=:73:12 Extent=[73:1 - 76:5] // CHECK: c-index-api-loadTU-test.m:73:12: ObjCClassRef=TestAttributes:62:12 Extent=[73:12 - 73:26] -// CHECK: c-index-api-loadTU-test.m:75:32: ObjCPropertyDecl=anotherOutlet:75:32 Extent=[75:1 - 75:45] +// CHECK: c-index-api-loadTU-test.m:75:32: ObjCPropertyDecl=anotherOutlet:75:32 [retain,] Extent=[75:1 - 75:45] // CHECK: <invalid loc>:0:0: attribute(iboutlet)= Extent=[75:20 - 75:28] // CHECK: c-index-api-loadTU-test.m:75:29: TypeRef=id:0:0 Extent=[75:29 - 75:31] // CHECK: c-index-api-loadTU-test.m:75:32: ObjCInstanceMethodDecl=anotherOutlet:75:32 Extent=[75:32 - 75:45] diff --git a/test/Index/comment-cplus11-specific.cpp b/test/Index/comment-cplus11-specific.cpp new file mode 100644 index 0000000..fa0db91 --- /dev/null +++ b/test/Index/comment-cplus11-specific.cpp @@ -0,0 +1,27 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng std=c++11 %s > %t/out +// RUN: FileCheck %s < %t/out +// rdar://13752382 + +namespace inner { + //! This documentation should be inherited. + struct Opaque; +} +// CHECK: (CXComment_Text Text=[ This documentation should be inherited.])))] + +namespace borrow { + //! This is documentation for the typedef (which shows up). + typedef inner::Opaque Typedef; +// CHECK: (CXComment_Text Text=[ This is documentation for the typedef (which shows up).])))] + + //! This is documentation for the alias (which shows up). + using Alias = inner::Opaque; +// CHECK: (CXComment_Text Text=[ This is documentation for the alias (which shows up).])))] + + typedef inner::Opaque NoDocTypedef; +// CHECK: (CXComment_Text Text=[ This documentation should be inherited.])))] + + using NoDocAlias = inner::Opaque; +// CHECK: (CXComment_Text Text=[ This documentation should be inherited.])))] +} diff --git a/test/Index/comment-misc-tags.m b/test/Index/comment-misc-tags.m new file mode 100644 index 0000000..9eae548 --- /dev/null +++ b/test/Index/comment-misc-tags.m @@ -0,0 +1,110 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s > %t/out +// RUN: FileCheck %s < %t/out +// rdar://12379114 + +/*! + @interface IOCommandGate + @brief This is a brief + @abstract Single-threaded work-loop client request mechanism. + @discussion An IOCommandGate instance is an extremely light weight mechanism that + executes an action on the driver's work-loop... + @textblock + Many discussions about text + Many1 discussions about text + Many2 discussions about text + @/textblock + @link //un_ref/c/func/function_name link text goes here @/link + @see //un_ref/doc/uid/XX0000011 I/O Kit Fundamentals + @seealso //k_ref/doc/uid/XX30000905-CH204 Programming + */ +@interface IOCommandGate +@end + +// CHECK: (CXComment_BlockCommand CommandName=[abstract] +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ Single-threaded work-loop client request mechanism.] HasTrailingNewline) +// CHECK: (CXComment_BlockCommand CommandName=[discussion] +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ An IOCommandGate instance is an extremely light weight mechanism that] HasTrailingNewline) +// CHECK-NEXT: (CXComment_Text Text=[ executes an action on the driver's work-loop...] HasTrailingNewline) +// CHECK: (CXComment_VerbatimBlockCommand CommandName=[textblock] +// CHECK-NEXT: (CXComment_VerbatimBlockLine Text=[ Many discussions about text]) +// CHECK-NEXT: (CXComment_VerbatimBlockLine Text=[ Many1 discussions about text]) +// CHECK-NEXT: (CXComment_VerbatimBlockLine Text=[ Many2 discussions about text])) +// CHECK-NEXT: (CXComment_Paragraph IsWhitespace + +// CHECK: (CXComment_VerbatimBlockCommand CommandName=[link] +// CHECK-NEXT: (CXComment_VerbatimBlockLine Text=[ //un_ref/c/func/function_name link text goes here ])) +// CHECK-NEXT: (CXComment_Paragraph IsWhitespace +// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)) +// CHECK: (CXComment_BlockCommand CommandName=[see] +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ //un_ref/doc/uid/XX0000011 I/O Kit Fundamentals] HasTrailingNewline) +// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace))) +// CHECK: (CXComment_BlockCommand CommandName=[seealso] +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ //k_ref/doc/uid/XX30000905-CH204 Programming] HasTrailingNewline) + +// rdar://12379053 +/*! +\arg \c AlignLeft left alignment. +\li \c AlignRight right alignment. + + No other types of alignment are supported. +*/ +struct S { + int AlignLeft; + int AlignRight; +}; + +// CHECK: (CXComment_BlockCommand CommandName=[arg] +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) +// CHECK-NEXT: (CXComment_InlineCommand CommandName=[c] RenderMonospaced Arg[0]=AlignLeft) +// CHECK-NEXT: (CXComment_Text Text=[ left alignment.] HasTrailingNewline))) +// CHECK: (CXComment_BlockCommand CommandName=[li] +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) +// CHECK-NEXT: (CXComment_InlineCommand CommandName=[c] RenderMonospaced Arg[0]=AlignRight) +// CHECK-NEXT: (CXComment_Text Text=[ right alignment.]))) +// CHECK: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ No other types of alignment are supported.])) + +// rdar://12379053 +/*! \struct Test + * Normal text. + * + * \par User defined paragraph: + * Contents of the paragraph. + * + * \par + * New paragraph under the same heading. + * + * \note + * This note consists of two paragraphs. + * This is the first paragraph. + * + * \par + * And this is the second paragraph. + * + * More normal text. + */ + +struct Test {int filler;}; + +// CHECK: (CXComment_BlockCommand CommandName=[par] +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ User defined paragraph:] HasTrailingNewline) +// CHECK-NEXT: (CXComment_Text Text=[ Contents of the paragraph.]))) +// CHECK: (CXComment_BlockCommand CommandName=[par] +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ New paragraph under the same heading.]))) +// CHECK: (CXComment_BlockCommand CommandName=[note] +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ This note consists of two paragraphs.] HasTrailingNewline) +// CHECK-NEXT: (CXComment_Text Text=[ This is the first paragraph.]))) +// CHECK: (CXComment_BlockCommand CommandName=[par] +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ And this is the second paragraph.]))) diff --git a/test/Index/comment-unqualified-objc-pointer.m b/test/Index/comment-unqualified-objc-pointer.m new file mode 100644 index 0000000..546d4fa --- /dev/null +++ b/test/Index/comment-unqualified-objc-pointer.m @@ -0,0 +1,36 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng -target x86_64-apple-darwin10 -fobjc-default-synthesize-properties -fobjc-arc %s > %t/out +// RUN: FileCheck %s < %t/out +// rdar://13757500 + +@class NSString; + +@interface NSArray @end + +@interface NSMutableArray : NSArray +{ +//! This is the name. + NSString *Name; +} +//! This is WithLabel comment. +- (NSString *)WithLabel:(NSString * const)label; +// CHECK: <Declaration>- (NSString *)WithLabel:(NSString *const)label;</Declaration> + +//! This is a property to get the Name. +@property (copy) NSString *Name; +// CHECK: <Declaration>@property(readwrite, copy, atomic) NSString *Name;</Declaration> +@end + +@implementation NSMutableArray +{ +//! This is private ivar + NSString *NickName; +// CHECK: <Declaration>NSString *NickName</Declaration> +} + +- (NSString *)WithLabel:(NSString * const)label { + return 0; +} +@synthesize Name = Name; +@end diff --git a/test/Index/comment-with-preamble.c b/test/Index/comment-with-preamble.c new file mode 100644 index 0000000..72e6140 --- /dev/null +++ b/test/Index/comment-with-preamble.c @@ -0,0 +1,13 @@ +// Make sure the preable does not truncate comments. + +#ifndef BAZ +#define BAZ 3 +#endif + +//! Foo’s description. +void Foo(); + +// RUN: c-index-test -test-load-source-reparse 1 local %s | FileCheck %s +// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 1 local %s | FileCheck %s + +// CHECK: FunctionDecl=Foo:8:6 RawComment=[//! Foo’s description.] RawCommentRange=[7:1 - 7:25] BriefComment=[Foo’s description.] diff --git a/test/Index/get-cursor.cpp b/test/Index/get-cursor.cpp index 8b70216..996ecc2 100644 --- a/test/Index/get-cursor.cpp +++ b/test/Index/get-cursor.cpp @@ -47,6 +47,24 @@ void test() { }; } +template <bool (*tfn)(X*)> +struct TS { + void foo(); +}; + +template <bool (*tfn)(X*)> +void TS<tfn>::foo() {} + +template <typename T> +class TC { + void init(); +}; + +template<> void TC<char>::init(); + +#define EXTERN_TEMPLATE(...) extern template __VA_ARGS__; +EXTERN_TEMPLATE(class TC<char>) + // RUN: c-index-test -cursor-at=%s:6:4 %s | FileCheck -check-prefix=CHECK-COMPLETION-1 %s // CHECK-COMPLETION-1: CXXConstructor=X:6:3 // CHECK-COMPLETION-1-NEXT: Completion string: {TypedText X}{LeftParen (}{Placeholder int}{Comma , }{Placeholder int}{RightParen )} @@ -103,3 +121,10 @@ void test() { // RUN: c-index-test -cursor-at=%s:45:9 %s | FileCheck -check-prefix=CHECK-LOCALCLASS %s // CHECK-LOCALCLASS: 45:9 DeclRefExpr=x:44:11 Extent=[45:9 - 45:10] Spelling=x ([45:9 - 45:10]) + +// RUN: c-index-test -cursor-at=%s:50:23 -cursor-at=%s:55:23 %s | FileCheck -check-prefix=CHECK-TEMPLPARAM %s +// CHECK-TEMPLPARAM: 50:23 TypeRef=struct X:3:8 Extent=[50:23 - 50:24] Spelling=struct X ([50:23 - 50:24]) +// CHECK-TEMPLPARAM: 55:23 TypeRef=struct X:3:8 Extent=[55:23 - 55:24] Spelling=struct X ([55:23 - 55:24]) + +// RUN: c-index-test -cursor-at=%s:66:23 %s | FileCheck -check-prefix=CHECK-TEMPLSPEC %s +// CHECK-TEMPLSPEC: 66:23 ClassDecl=TC:66:23 (Definition) [Specialization of TC:59:7] Extent=[66:1 - 66:31] Spelling=TC ([66:23 - 66:25]) diff --git a/test/Index/index-refs.m b/test/Index/index-refs.m index b82345f..f25013b 100644 --- a/test/Index/index-refs.m +++ b/test/Index/index-refs.m @@ -13,6 +13,15 @@ void foo() { @encode(struct FooS); } +@interface I ++(void)clsMeth; +@end + +void foo2() { + [I clsMeth]; +} + // RUN: c-index-test -index-file %s | FileCheck %s // CHECK: [indexEntityReference]: kind: objc-protocol | name: Prot | {{.*}} | loc: 12:27 // CHECK: [indexEntityReference]: kind: struct | name: FooS | {{.*}} | loc: 13:18 +// CHECK: [indexEntityReference]: kind: objc-class | name: I | {{.*}} | loc: 21:4 diff --git a/test/Index/load-classes.cpp b/test/Index/load-classes.cpp index 5877019..db7b48f 100644 --- a/test/Index/load-classes.cpp +++ b/test/Index/load-classes.cpp @@ -3,7 +3,9 @@ struct X { X(int value); X(const X& x); +protected: ~X(); +private: operator X*(); }; @@ -11,18 +13,18 @@ X::X(int value) { } // RUN: c-index-test -test-load-source all %s | FileCheck %s -// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) Extent=[3:1 - 8:2] -// CHECK: load-classes.cpp:4:3: CXXConstructor=X:4:3 Extent=[4:3 - 4:15] +// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) Extent=[3:1 - 10:2] +// CHECK: load-classes.cpp:4:3: CXXConstructor=X:4:3 Extent=[4:3 - 4:15] [access=public] // FIXME: missing TypeRef in the constructor name // CHECK: load-classes.cpp:4:9: ParmDecl=value:4:9 (Definition) Extent=[4:5 - 4:14] -// CHECK: load-classes.cpp:5:3: CXXConstructor=X:5:3 Extent=[5:3 - 5:16] +// CHECK: load-classes.cpp:5:3: CXXConstructor=X:5:3 Extent=[5:3 - 5:16] [access=public] // FIXME: missing TypeRef in the constructor name // CHECK: load-classes.cpp:5:14: ParmDecl=x:5:14 (Definition) Extent=[5:5 - 5:15] // CHECK: load-classes.cpp:5:11: TypeRef=struct X:3:8 Extent=[5:11 - 5:12] -// CHECK: load-classes.cpp:6:3: CXXDestructor=~X:6:3 Extent=[6:3 - 6:7] +// CHECK: load-classes.cpp:7:3: CXXDestructor=~X:7:3 Extent=[7:3 - 7:7] [access=protected] // FIXME: missing TypeRef in the destructor name -// CHECK: load-classes.cpp:7:3: CXXConversion=operator struct X *:7:3 Extent=[7:3 - 7:16] -// CHECK: load-classes.cpp:7:12: TypeRef=struct X:3:8 Extent=[7:12 - 7:13] -// CHECK: load-classes.cpp:10:4: CXXConstructor=X:10:4 (Definition) Extent=[10:1 - 11:2] -// CHECK: load-classes.cpp:10:1: TypeRef=struct X:3:8 Extent=[10:1 - 10:2] -// CHECK: load-classes.cpp:10:10: ParmDecl=value:10:10 (Definition) Extent=[10:6 - 10:15] +// CHECK: load-classes.cpp:9:3: CXXConversion=operator struct X *:9:3 Extent=[9:3 - 9:16] [access=private] +// CHECK: load-classes.cpp:9:12: TypeRef=struct X:3:8 Extent=[9:12 - 9:13] +// CHECK: load-classes.cpp:12:4: CXXConstructor=X:12:4 (Definition) Extent=[12:1 - 13:2] [access=public] +// CHECK: load-classes.cpp:12:1: TypeRef=struct X:3:8 Extent=[12:1 - 12:2] +// CHECK: load-classes.cpp:12:10: ParmDecl=value:12:10 (Definition) Extent=[12:6 - 12:15] diff --git a/test/Index/parse-all-comments.c b/test/Index/parse-all-comments.c new file mode 100644 index 0000000..f8b0449 --- /dev/null +++ b/test/Index/parse-all-comments.c @@ -0,0 +1,62 @@ +// Run lines are sensitive to line numbers and come below the code. + +#ifndef HEADER +#define HEADER + +// Not a Doxygen comment. notdoxy1 NOT_DOXYGEN +void notdoxy1(void); + +/* Not a Doxygen comment. notdoxy2 NOT_DOXYGEN */ +void notdoxy2(void); + +/*/ Not a Doxygen comment. notdoxy3 NOT_DOXYGEN */ +void notdoxy3(void); + +/** Doxygen comment. isdoxy4 IS_DOXYGEN_SINGLE */ +void isdoxy4(void); + +/*! Doxygen comment. isdoxy5 IS_DOXYGEN_SINGLE */ +void isdoxy5(void); + +/// Doxygen comment. isdoxy6 IS_DOXYGEN_SINGLE +void isdoxy6(void); + +/* BLOCK_ORDINARY_COMMENT */ +// ORDINARY COMMENT +/// This is a BCPL comment. IS_DOXYGEN_START +/// It has only two lines. +/** But there are other blocks that are part of the comment, too. IS_DOXYGEN_END */ +void multi_line_comment_plus_ordinary(int); + +// MULTILINE COMMENT +// +// WITH EMPTY LINE +void multi_line_comment_empty_line(int); + +#endif + +// RUN: rm -rf %t +// RUN: mkdir %t + +// RUN: %clang_cc1 -fparse-all-comments -x c++ -std=c++11 -emit-pch -o %t/out.pch %s + +// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s -std=c++11 -fparse-all-comments > %t/out.c-index-direct +// RUN: c-index-test -test-load-tu %t/out.pch all > %t/out.c-index-pch + +// RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-direct +// RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-pch + +// Ensure that XML is not invalid +// WRONG-NOT: CommentXMLInvalid + +// RUN: FileCheck %s < %t/out.c-index-direct +// RUN: FileCheck %s < %t/out.c-index-pch + +// CHECK: parse-all-comments.c:7:6: FunctionDecl=notdoxy1:{{.*}} notdoxy1 NOT_DOXYGEN +// CHECK: parse-all-comments.c:10:6: FunctionDecl=notdoxy2:{{.*}} notdoxy2 NOT_DOXYGEN +// CHECK: parse-all-comments.c:13:6: FunctionDecl=notdoxy3:{{.*}} notdoxy3 NOT_DOXYGEN +// CHECK: parse-all-comments.c:16:6: FunctionDecl=isdoxy4:{{.*}} isdoxy4 IS_DOXYGEN_SINGLE +// CHECK: parse-all-comments.c:19:6: FunctionDecl=isdoxy5:{{.*}} isdoxy5 IS_DOXYGEN_SINGLE +// CHECK: parse-all-comments.c:22:6: FunctionDecl=isdoxy6:{{.*}} isdoxy6 IS_DOXYGEN_SINGLE +// CHECK: parse-all-comments.c:29:6: FunctionDecl=multi_line_comment_plus_ordinary:{{.*}} BLOCK_ORDINARY_COMMENT {{.*}} ORDINARY COMMENT {{.*}} IS_DOXYGEN_START {{.*}} IS_DOXYGEN_END +// CHECK: parse-all-comments.c:34:6: FunctionDecl=multi_line_comment_empty_line:{{.*}} MULTILINE COMMENT{{.*}}\n{{.*}}\n{{.*}} WITH EMPTY LINE diff --git a/test/Index/print-type-size.cpp b/test/Index/print-type-size.cpp new file mode 100644 index 0000000..698d967 --- /dev/null +++ b/test/Index/print-type-size.cpp @@ -0,0 +1,428 @@ +// from SemaCXX/class-layout.cpp +// RUN: c-index-test -test-print-type-size %s -target x86_64-pc-linux-gnu | FileCheck -check-prefix=CHECK64 %s +// RUN: c-index-test -test-print-type-size %s -target i386-apple-darwin9 | FileCheck -check-prefix=CHECK32 %s + +namespace basic { + +// CHECK64: VarDecl=v:[[@LINE+2]]:6 (Definition) [type=void] [typekind=Void] +// CHECK32: VarDecl=v:[[@LINE+1]]:6 (Definition) [type=void] [typekind=Void] +void v; + +// CHECK64: VarDecl=v1:[[@LINE+2]]:7 (Definition) [type=void *] [typekind=Pointer] [sizeof=8] [alignof=8] +// CHECK32: VarDecl=v1:[[@LINE+1]]:7 (Definition) [type=void *] [typekind=Pointer] [sizeof=4] [alignof=4] +void *v1; + +// offsetof +// CHECK64: StructDecl=simple:[[@LINE+2]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=48] [alignof=8] +// CHECK32: StructDecl=simple:[[@LINE+1]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=36] [alignof=4] +struct simple { + int a; + char b; +// CHECK64: FieldDecl=c:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=40] [BitFieldSize=3] + int c:3; + long d; + int e:5; +// CHECK64: FieldDecl=f:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=133] [BitFieldSize=4] + int f:4; +// CHECK64: FieldDecl=g:[[@LINE+2]]:13 (Definition) [type=long long] [typekind=LongLong] [sizeof=8] [alignof=8] [offsetof=192] +// CHECK32: FieldDecl=g:[[@LINE+1]]:13 (Definition) [type=long long] [typekind=LongLong] [sizeof=8] [alignof=4] [offsetof=128] + long long g; +// CHECK64: FieldDecl=h:[[@LINE+1]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=256] [BitFieldSize=3] + char h:3; + char i:3; + float j; +// CHECK64: FieldDecl=k:[[@LINE+2]]:10 (Definition) [type=char *] [typekind=Pointer] [sizeof=8] [alignof=8] [offsetof=320] +// CHECK32: FieldDecl=k:[[@LINE+1]]:10 (Definition) [type=char *] [typekind=Pointer] [sizeof=4] [alignof=4] [offsetof=256] + char * k; +}; + + +// CHECK64: UnionDecl=u:[[@LINE+2]]:7 (Definition) [type=basic::u] [typekind=Record] [sizeof=48] [alignof=8] +// CHECK32: UnionDecl=u:[[@LINE+1]]:7 (Definition) [type=basic::u] [typekind=Record] [sizeof=36] [alignof=4] +union u { + int u1; + long long u2; + struct simple s1; +}; + +// CHECK64: VarDecl=s1:[[@LINE+2]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=48] [alignof=8] +// CHECK32: VarDecl=s1:[[@LINE+1]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=36] [alignof=4] +simple s1; + +struct Test { + struct { + union { +//CHECK64: FieldDecl=foo:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0] + int foo; + }; + }; +}; + +struct Test2 { + struct { + struct { +//CHECK64: FieldDecl=foo:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0] + int foo; + }; + struct { +//CHECK64: FieldDecl=bar:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=32] + int bar; + }; + struct { + struct { +//CHECK64: FieldDecl=foobar:[[@LINE+1]]:15 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64] + int foobar; + }; + }; + struct inner { + struct { +//CHECK64: FieldDecl=mybar:[[@LINE+1]]:15 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0] + int mybar; + }; +//CHECK64: FieldDecl=mole:[[@LINE+1]]:7 (Definition) [type=struct inner] [typekind=Unexposed] [sizeof=4] [alignof=4] [offsetof=96] + } mole; + }; +}; + +} + +// these are test crash. Offsetof return values are not important. +namespace Incomplete { +// test that fields in incomplete named record do not crash +union named { + struct forward_decl f1; +//CHECK64: FieldDecl=f2:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2] + int f2; + struct x { +//CHECK64: FieldDecl=g1:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0] + int g1; +//CHECK64: FieldDecl=f3:[[@LINE+1]]:5 (Definition) [type=struct x] [typekind=Unexposed] [sizeof=4] [alignof=4] [offsetof=-2] + } f3; + struct forward_decl f4; + struct x2{ + int g2; + struct forward_decl g3; + } f5; +}; + +// test that fields in incomplete anonymous record do not crash +union f { +//CHECK64: FieldDecl=f1:[[@LINE+1]]:23 (Definition) [type=struct forward_decl] [typekind=Unexposed] [sizeof=-2] [alignof=-2] [offsetof=-2] + struct forward_decl f1; +//CHECK64: FieldDecl=f2:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2] + int f2; + struct { +//CHECK64: FieldDecl=e1:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2] + int e1; + struct { +//CHECK64: FieldDecl=g1:[[@LINE+1]]:28 (Definition) [type=struct forward_decl2] [typekind=Unexposed] [sizeof=-2] [alignof=-2] [offsetof=-2] + struct forward_decl2 g1; + }; +//CHECK64: FieldDecl=e3:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2] + int e3; + }; +}; + + +// incomplete not in root level, in named record +struct s1 { + struct { + struct forward_decl2 s1_g1; +//CHECK64: FieldDecl=s1_e1:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2] + int s1_e1; + } s1_x; // named record shows in s1->field_iterator +//CHECK64: FieldDecl=s1_e3:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2] + int s1_e3; +}; + +// incomplete not in root level, in anonymous record +struct s1b { + struct { + struct forward_decl2 s1b_g1; + }; // erroneous anonymous record does not show in s1b->field_iterator +//CHECK64: FieldDecl=s1b_e2:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0] + int s1b_e2; +}; + +struct s2 { + struct { + struct forward_decl2 s2_g1; +//CHECK64: FieldDecl=s2_e1:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-5] + int s2_e1; + }; // erroneous anonymous record does not show in s1b->field_iterator +//CHECK64: FieldDecl=s2_e3:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0] + int s2_e3; +}; + +//deep anonymous with deep level incomplete +struct s3 { + struct { + int s3_e1; + struct { + struct { + struct { + struct { + struct forward_decl2 s3_g1; + }; + }; + }; + }; +//CHECK64: FieldDecl=s3_e3:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64] + int s3_e3; + }; +}; + +//deep anonymous with first level incomplete +struct s4a { + struct forward_decl2 g1; + struct { + struct forward_decl2 g2; + struct { + struct { + struct { + struct { +//CHECK64: FieldDecl=s4_e1:[[@LINE+1]]:17 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2] + int s4_e1; + }; + }; + }; + }; +//CHECK64: FieldDecl=s4_e3:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2] + int s4_e3; + }; +}; + +//deep anonymous with sub-first-level incomplete +struct s4b { + struct { + struct forward_decl2 g1; + struct { + struct { + struct { + struct { +//CHECK64: FieldDecl=s4b_e1:[[@LINE+1]]:17 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-5] + int s4b_e1; + }; + }; + }; + }; +//CHECK64: FieldDecl=s4b_e3:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-5] + int s4b_e3; + }; +}; + +// CHECK64: StructDecl=As:[[@LINE+1]]:8 [type=Incomplete::As] [typekind=Record] +struct As; + +// undefined class. Should not crash +// CHECK64: ClassDecl=A:[[@LINE+1]]:7 [type=Incomplete::A] [typekind=Record] +class A; +// CHECK64: ClassDecl=B:[[@LINE+1]]:7 (Definition) [type=Incomplete::B] [typekind=Record] [sizeof=16] [alignof=8] +class B { +// CHECK64: FieldDecl=a1:[[@LINE+2]]:6 (Definition) [type=Incomplete::A *] [typekind=Pointer] [sizeof=8] [alignof=8] [offsetof=0] +// CHECK32: FieldDecl=a1:[[@LINE+1]]:6 (Definition) [type=Incomplete::A *] [typekind=Pointer] [sizeof=4] [alignof=4] [offsetof=0] + A* a1; +// CHECK64: FieldDecl=a2:[[@LINE+2]]:6 (Definition) [type=Incomplete::A &] [typekind=LValueReference] [sizeof=-2] [alignof=-2] [offsetof=64] +// CHECK32: FieldDecl=a2:[[@LINE+1]]:6 (Definition) [type=Incomplete::A &] [typekind=LValueReference] [sizeof=-2] [alignof=-2] [offsetof=32] + A& a2; +}; + +} + +namespace Sizes { + +// CHECK64: StructDecl=A:[[@LINE+2]]:8 (Definition) [type=Sizes::A] [typekind=Record] [sizeof=8] [alignof=4] +// CHECK32: StructDecl=A:[[@LINE+1]]:8 (Definition) [type=Sizes::A] [typekind=Record] [sizeof=8] [alignof=4] +struct A { + int a; + char b; +}; + +// CHECK64: StructDecl=B:[[@LINE+2]]:8 (Definition) [type=Sizes::B] [typekind=Record] [sizeof=12] [alignof=4] +// CHECK32: StructDecl=B:[[@LINE+1]]:8 (Definition) [type=Sizes::B] [typekind=Record] [sizeof=12] [alignof=4] +struct B : A { + char c; +}; + +// CHECK64: StructDecl=C:[[@LINE+2]]:8 (Definition) [type=Sizes::C] [typekind=Record] [sizeof=8] [alignof=4] +// CHECK32: StructDecl=C:[[@LINE+1]]:8 (Definition) [type=Sizes::C] [typekind=Record] [sizeof=8] [alignof=4] +struct C { +// Make fields private so C won't be a POD type. +private: + int a; + char b; +}; + +// CHECK64: StructDecl=D:[[@LINE+2]]:8 (Definition) [type=Sizes::D] [typekind=Record] [sizeof=8] [alignof=4] +// CHECK32: StructDecl=D:[[@LINE+1]]:8 (Definition) [type=Sizes::D] [typekind=Record] [sizeof=8] [alignof=4] +struct D : C { + char c; +}; + +// CHECK64: StructDecl=E:[[@LINE+2]]:32 (Definition) [type=Sizes::E] [typekind=Record] [sizeof=5] [alignof=1] +// CHECK32: StructDecl=E:[[@LINE+1]]:32 (Definition) [type=Sizes::E] [typekind=Record] [sizeof=5] [alignof=1] +struct __attribute__((packed)) E { + char b; + int a; +}; + +// CHECK64: StructDecl=F:[[@LINE+2]]:32 (Definition) [type=Sizes::F] [typekind=Record] [sizeof=6] [alignof=1] +// CHECK32: StructDecl=F:[[@LINE+1]]:32 (Definition) [type=Sizes::F] [typekind=Record] [sizeof=6] [alignof=1] +struct __attribute__((packed)) F : E { + char d; +}; + +struct G { G(); }; +// CHECK64: StructDecl=H:[[@LINE+2]]:8 (Definition) [type=Sizes::H] [typekind=Record] [sizeof=1] [alignof=1] +// CHECK32: StructDecl=H:[[@LINE+1]]:8 (Definition) [type=Sizes::H] [typekind=Record] [sizeof=1] [alignof=1] +struct H : G { }; + +// CHECK64: StructDecl=I:[[@LINE+2]]:8 (Definition) [type=Sizes::I] [typekind=Record] [sizeof=5] [alignof=1] +// CHECK32: StructDecl=I:[[@LINE+1]]:8 (Definition) [type=Sizes::I] [typekind=Record] [sizeof=5] [alignof=1] +struct I { + char b; + int a; +} __attribute__((packed)); + +} + +namespace Test1 { + +// Test complex class hierarchy +struct A { }; +struct B : A { virtual void b(); }; +class C : virtual A { int c; }; +struct D : virtual B { }; +struct E : C, virtual D { }; +class F : virtual E { }; +// CHECK64: StructDecl=G:[[@LINE+2]]:8 (Definition) [type=Test1::G] [typekind=Record] [sizeof=24] [alignof=8] +// CHECK32: StructDecl=G:[[@LINE+1]]:8 (Definition) [type=Test1::G] [typekind=Record] [sizeof=16] [alignof=4] +struct G : virtual E, F { }; + +} + +namespace Test2 { + +// Test that this somewhat complex class structure is laid out correctly. +struct A { }; +struct B : A { virtual void b(); }; +struct C : virtual B { }; +struct D : virtual A { }; +struct E : virtual B, D { }; +struct F : E, virtual C { }; +struct G : virtual F, A { }; +// CHECK64: StructDecl=H:[[@LINE+2]]:8 (Definition) [type=Test2::H] [typekind=Record] [sizeof=24] [alignof=8] +// CHECK32: StructDecl=H:[[@LINE+1]]:8 (Definition) [type=Test2::H] [typekind=Record] [sizeof=12] [alignof=4] +struct H { G g; }; + +} + +namespace Test3 { +// CHECK64: ClassDecl=B:[[@LINE+2]]:7 (Definition) [type=Test3::B] [typekind=Record] [sizeof=16] [alignof=8] +// CHECK32: ClassDecl=B:[[@LINE+1]]:7 (Definition) [type=Test3::B] [typekind=Record] [sizeof=8] [alignof=4] +class B { +public: + virtual void b(){} +// CHECK64: FieldDecl=b_field:[[@LINE+2]]:8 (Definition) [type=long] [typekind=Long] [sizeof=8] [alignof=8] [offsetof=64] +// CHECK32: FieldDecl=b_field:[[@LINE+1]]:8 (Definition) [type=long] [typekind=Long] [sizeof=4] [alignof=4] [offsetof=32] + long b_field; +protected: +private: +}; + +// CHECK32: ClassDecl=A:[[@LINE+1]]:7 (Definition) [type=Test3::A] [typekind=Record] [sizeof=16] [alignof=4] +class A : public B { +public: +// CHECK64: FieldDecl=a_field:[[@LINE+2]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=128] +// CHECK32: FieldDecl=a_field:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64] + int a_field; + virtual void a(){} +// CHECK64: FieldDecl=one:[[@LINE+2]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=160] +// CHECK32: FieldDecl=one:[[@LINE+1]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=96] + char one; +protected: +private: +}; + +// CHECK64: ClassDecl=D:[[@LINE+2]]:7 (Definition) [type=Test3::D] [typekind=Record] [sizeof=16] [alignof=8] +// CHECK32: ClassDecl=D:[[@LINE+1]]:7 (Definition) [type=Test3::D] [typekind=Record] [sizeof=12] [alignof=4] +class D { +public: + virtual void b(){} +// CHECK64: FieldDecl=a:[[@LINE+2]]:10 (Definition) [type=double] [typekind=Double] [sizeof=8] [alignof=8] [offsetof=64] +// CHECK32: FieldDecl=a:[[@LINE+1]]:10 (Definition) [type=double] [typekind=Double] [sizeof=8] [alignof=4] [offsetof=32] + double a; +}; + +// CHECK64: ClassDecl=C:[[@LINE+2]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=88] [alignof=8] +// CHECK32: ClassDecl=C:[[@LINE+1]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=60] [alignof=4] +class C : public virtual A, + public D, public B { +public: + double c1_field; + int c2_field; + double c3_field; + int c4_field; + virtual void foo(){} + virtual void bar(){} +protected: +private: +}; + +struct BaseStruct +{ + BaseStruct(){} + double v0; + float v1; +// CHECK64: FieldDecl=fg:[[@LINE+2]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=88] [alignof=8] [offsetof=128] +// CHECK32: FieldDecl=fg:[[@LINE+1]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=60] [alignof=4] [offsetof=96] + C fg; +// CHECK64: FieldDecl=rg:[[@LINE+2]]:8 (Definition) [type=Test3::C &] [typekind=LValueReference] [sizeof=88] [alignof=8] [offsetof=832] +// CHECK32: FieldDecl=rg:[[@LINE+1]]:8 (Definition) [type=Test3::C &] [typekind=LValueReference] [sizeof=60] [alignof=4] [offsetof=576] + C &rg; + int x; +}; + +} + +namespace NotConstantSize { + +void f(int i) { +// CHECK32: VarDecl=v2:[[@LINE+1]]:8 (Definition) [type=int [i]] [typekind=Unexposed] [sizeof=-4] [alignof=4] + int v2[i]; + { + struct CS1 { +// FIXME: should libclang return [offsetof=0] ? +//CHECK32: FieldDecl=f1:[[@LINE+1]]:9 (Definition) [type=int [i]] [typekind=Unexposed] [sizeof=-4] [alignof=4] [offsetof=0] + int f1[i]; +//CHECK32: FieldDecl=f2:[[@LINE+1]]:11 (Definition) [type=float] [typekind=Float] [sizeof=4] [alignof=4] [offsetof=0] + float f2; + }; + } +} + +} + +namespace CrashTest { +// test crash scenarios on dependent types. +template<typename T> +struct Foo { +//CHECK32: FieldDecl=t:[[@LINE+1]]:5 (Definition) [type=T] [typekind=Unexposed] [sizeof=-3] [alignof=-3] [offsetof=-1] + T t; +//CHECK32: FieldDecl=a:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-1] + int a; +}; + +Foo<Sizes::A> t1; +Foo<Sizes::I> t2; + +void c; + +plopplop; + +// CHECK64: StructDecl=lastValid:[[@LINE+2]]:8 (Definition) [type=CrashTest::lastValid] [typekind=Record] [sizeof=1] [alignof=1] +// CHECK32: StructDecl=lastValid:[[@LINE+1]]:8 (Definition) [type=CrashTest::lastValid] [typekind=Record] [sizeof=1] [alignof=1] +struct lastValid { +}; + +} diff --git a/test/Index/print-type.c b/test/Index/print-type.c index 8594994..4805f59 100644 --- a/test/Index/print-type.c +++ b/test/Index/print-type.c @@ -11,12 +11,12 @@ int __attribute__((vector_size(16))) x; typedef int __attribute__((vector_size(16))) int4_t; // RUN: c-index-test -test-print-type %s | FileCheck %s -// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int *] [Pointer] [void (*)(int)] [Pointer]] [isPOD=0] +// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int [5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0] // CHECK: ParmDecl=p:3:13 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] // CHECK: ParmDecl=x:3:22 (Definition) [type=char *] [typekind=Pointer] [isPOD=1] // CHECK: ParmDecl=z:3:33 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] // CHECK: TypeRef=FooType:1:13 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] -// CHECK: ParmDecl=arr:3:40 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] +// CHECK: ParmDecl=arr:3:40 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1] // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1] // CHECK: ParmDecl=fn:3:55 (Definition) [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] // CHECK: ParmDecl=:3:62 (Definition) [type=int] [typekind=Int] [isPOD=1] diff --git a/test/Index/print-type.cpp b/test/Index/print-type.cpp index b99d1cb..49a05fb 100644 --- a/test/Index/print-type.cpp +++ b/test/Index/print-type.cpp @@ -26,6 +26,9 @@ struct Bar { template <typename T> T tbar(int); +template <typename T> +T tbar(int[5]); + // RUN: c-index-test -test-print-type %s | FileCheck %s // CHECK: Namespace=outer:1:11 (Definition) [type=] [typekind=Invalid] [isPOD=0] // CHECK: ClassTemplate=Foo:4:8 (Definition) [type=] [typekind=Invalid] [isPOD=0] @@ -59,3 +62,5 @@ T tbar(int); // CHECK: TypedefDecl=ArrayType:20:15 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1] // CHECK: FunctionTemplate=tbar:27:3 [type=T (int)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0] // CHECK: TemplateTypeParameter=T:26:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0] +// CHECK: FunctionTemplate=tbar:30:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0] +// CHECK: ParmDecl=:30:11 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1] diff --git a/test/Index/print-type.m b/test/Index/print-type.m index 9325c3f..6f146f8 100644 --- a/test/Index/print-type.m +++ b/test/Index/print-type.m @@ -2,9 +2,14 @@ @property (readonly) id x; -(int) mymethod; -(const id) mymethod2:(id)x blah:(Class)y boo:(SEL)z; +-(bycopy)methodIn:(in int)i andOut:(out short *)j , ...; @end // RUN: c-index-test -test-print-type %s | FileCheck %s -// CHECK: ObjCPropertyDecl=x:2:25 [type=id] [typekind=ObjCId] [canonicaltype=id] [canonicaltypekind=ObjCObjectPointer] [isPOD=1] +// CHECK: ObjCPropertyDecl=x:2:25 [readonly,] [type=id] [typekind=ObjCId] [canonicaltype=id] [canonicaltypekind=ObjCObjectPointer] [isPOD=1] // CHECK: ObjCInstanceMethodDecl=mymethod:3:8 [type=] [typekind=Invalid] [resulttype=int] [resulttypekind=Int] [isPOD=0] // CHECK: ObjCInstanceMethodDecl=mymethod2:blah:boo::4:13 [type=] [typekind=Invalid] [resulttype=const id] [resulttypekind=ObjCId] [args= [id] [ObjCId] [Class] [ObjCClass] [SEL] [ObjCSel]] [isPOD=0] +// CHECK: ParmDecl=z:4:52 (Definition) [type=SEL] [typekind=ObjCSel] [canonicaltype=SEL *] [canonicaltypekind=Pointer] [isPOD=1] +// CHECK: ObjCInstanceMethodDecl=methodIn:andOut::5:10 (variadic) [Bycopy,] [type=] [typekind=Invalid] [resulttype=id] [resulttypekind=ObjCId] [args= [int] [Int] [short *] [Pointer]] [isPOD=0] +// CHECK: ParmDecl=i:5:27 (Definition) [In,] [type=int] [typekind=Int] [isPOD=1] +// CHECK: ParmDecl=j:5:49 (Definition) [Out,] [type=short *] [typekind=Pointer] [isPOD=1] diff --git a/test/Index/properties-class-extensions.m b/test/Index/properties-class-extensions.m index aa99207..0fa0ecb 100644 --- a/test/Index/properties-class-extensions.m +++ b/test/Index/properties-class-extensions.m @@ -60,12 +60,12 @@ // CHECK: properties-class-extensions.m:9:15: ParmDecl=b:9:15 (Definition) Extent=[9:15 - 9:16] // CHECK: properties-class-extensions.m:10:10: ObjCInstanceMethodDecl=bar:10:10 Extent=[10:1 - 10:14] // CHECK: properties-class-extensions.m:15:12: ObjCInterfaceDecl=Bar:15:12 Extent=[15:1 - 17:5] -// CHECK: properties-class-extensions.m:16:25: ObjCPropertyDecl=bar:16:25 Extent=[16:1 - 16:28] +// CHECK: properties-class-extensions.m:16:25: ObjCPropertyDecl=bar:16:25 [readonly,] Extent=[16:1 - 16:28] // CHECK: properties-class-extensions.m:16:22: TypeRef=id:0:0 Extent=[16:22 - 16:24] // CHECK: properties-class-extensions.m:16:25: ObjCInstanceMethodDecl=bar:16:25 Extent=[16:25 - 16:28] // CHECK: properties-class-extensions.m:18:12: ObjCCategoryDecl=:18:12 Extent=[18:1 - 20:5] // CHECK: properties-class-extensions.m:18:12: ObjCClassRef=Bar:15:12 Extent=[18:12 - 18:15] -// CHECK: properties-class-extensions.m:19:26: ObjCPropertyDecl=bar:19:26 Extent=[19:1 - 19:29] +// CHECK: properties-class-extensions.m:19:26: ObjCPropertyDecl=bar:19:26 [readwrite,] Extent=[19:1 - 19:29] // CHECK: properties-class-extensions.m:19:23: TypeRef=id:0:0 Extent=[19:23 - 19:25] // CHECK-NOT: properties-class-extensions.m:16:25: ObjCInstanceMethodDecl=bar:16:25 Extent=[16:25 - 16:28] // CHECK: properties-class-extensions.m:19:26: ObjCInstanceMethodDecl=setBar::19:26 Extent=[19:26 - 19:29] @@ -73,7 +73,7 @@ // CHECK: properties-class-extensions.m:24:8: ObjCInterfaceDecl=Rdar8467189_Bar:24:8 Extent=[24:1 - 24:23] // CHECK: properties-class-extensions.m:24:8: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[24:8 - 24:23] // CHECK: properties-class-extensions.m:25:11: ObjCProtocolDecl=Rdar8467189_FooProtocol:25:11 (Definition) Extent=[25:1 - 27:5] -// CHECK: properties-class-extensions.m:26:39: ObjCPropertyDecl=Rdar8467189_Bar:26:39 Extent=[26:1 - 26:54] +// CHECK: properties-class-extensions.m:26:39: ObjCPropertyDecl=Rdar8467189_Bar:26:39 [readonly,] Extent=[26:1 - 26:54] // CHECK: properties-class-extensions.m:26:22: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[26:22 - 26:37] // CHECK: properties-class-extensions.m:26:39: ObjCInstanceMethodDecl=Rdar8467189_Bar:26:39 Extent=[26:39 - 26:54] // CHECK: properties-class-extensions.m:28:12: ObjCInterfaceDecl=Rdar8467189_Foo:28:12 Extent=[28:1 - 29:5] @@ -82,7 +82,7 @@ // CHECK-NOT: properties-class-extensions.m:31:23: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[31:23 - 31:38] // CHECK: properties-class-extensions.m:30:12: ObjCCategoryDecl=:30:12 Extent=[30:1 - 32:5] // CHECK: properties-class-extensions.m:30:12: ObjCClassRef=Rdar8467189_Foo:28:12 Extent=[30:12 - 30:27] -// CHECK: properties-class-extensions.m:31:40: ObjCPropertyDecl=Rdar8467189_Bar:31:40 Extent=[31:1 - 31:55] +// CHECK: properties-class-extensions.m:31:40: ObjCPropertyDecl=Rdar8467189_Bar:31:40 [readwrite,] Extent=[31:1 - 31:55] // CHECK: properties-class-extensions.m:31:23: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[31:23 - 31:38] // CHECK: properties-class-extensions.m:31:40: ObjCInstanceMethodDecl=Rdar8467189_Bar:31:40 [Overrides @26:39] Extent=[31:40 - 31:55] // CHECK: properties-class-extensions.m:31:40: ObjCInstanceMethodDecl=setRdar8467189_Bar::31:40 Extent=[31:40 - 31:55] @@ -90,7 +90,7 @@ // CHECK: properties-class-extensions.m:35:12: ObjCInterfaceDecl=Qux:35:12 Extent=[35:1 - 36:5] // CHECK: properties-class-extensions.m:37:12: ObjCCategoryDecl=:37:12 Extent=[37:1 - 39:5] // CHECK: properties-class-extensions.m:37:12: ObjCClassRef=Qux:35:12 Extent=[37:12 - 37:15] -// CHECK: properties-class-extensions.m:38:34: ObjCPropertyDecl=qux:38:34 Extent=[38:1 - 38:37] +// CHECK: properties-class-extensions.m:38:34: ObjCPropertyDecl=qux:38:34 [assign,readwrite,] Extent=[38:1 - 38:37] // CHECK: properties-class-extensions.m:38:31: TypeRef=id:0:0 Extent=[38:31 - 38:33] // CHECK: properties-class-extensions.m:38:34: ObjCInstanceMethodDecl=qux:38:34 Extent=[38:34 - 38:37] // CHECK: properties-class-extensions.m:38:34: ObjCInstanceMethodDecl=setQux::38:34 Extent=[38:34 - 38:37] diff --git a/test/Index/subclass-comment.mm b/test/Index/subclass-comment.mm new file mode 100644 index 0000000..9682a9f --- /dev/null +++ b/test/Index/subclass-comment.mm @@ -0,0 +1,107 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s > %t/out +// RUN: FileCheck %s < %t/out +// rdar://13647476 + +//! NSObject is root of all. +@interface NSObject +@end +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ NSObject is root of all.])))] + +//! An umbrella class for super classes. +@interface SuperClass +@end +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ An umbrella class for super classes.])))] + +@interface SubClass : SuperClass +@end +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ An umbrella class for super classes.])))] + +@interface SubSubClass : SubClass +@end +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ An umbrella class for super classes.])))] + +@interface SubSubClass (Private) +@end +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ An umbrella class for super classes.])))] + +//! Something valuable to the organization. +class Asset { +}; +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ Something valuable to the organization.])))] + +//! An individual human or human individual. +class Person : public Asset { +}; +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ An individual human or human individual.])))] + +class Student : public Person { +}; +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ An individual human or human individual.])))] + +//! Every thing is a part +class Parts { +}; +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ Every thing is a part])))] + +class Window : public virtual Parts { +}; +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ Every thing is a part])))] + +class Door : public virtual Parts { +}; +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ Every thing is a part])))] + +class House : public Window, Door { +}; +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ Every thing is a part])))] + +//! Any Material +class Material : virtual Parts { +}; + +class Building : Window, public Material { +}; +// CHECK: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ Any Material])))] + + diff --git a/test/Index/targeted-annotation.c b/test/Index/targeted-annotation.c index cfa1046..022a139 100644 --- a/test/Index/targeted-annotation.c +++ b/test/Index/targeted-annotation.c @@ -82,10 +82,10 @@ int LocalVar2; // TOP: Identifier: "TARGETED_TOP_H" [2:9 - 2:23] preprocessing directive= // TOP: Punctuation: "#" [3:1 - 3:2] preprocessing directive= // TOP: Identifier: "define" [3:2 - 3:8] preprocessing directive= -// TOP: Identifier: "TARGETED_TOP_H" [3:9 - 3:23] preprocessing directive= -// TOP: Punctuation: "#" [5:1 - 5:2] preprocessing directive= -// TOP: Identifier: "include" [5:2 - 5:9] preprocessing directive= -// TOP: Literal: ""targeted-nested1.h"" [5:10 - 5:30] preprocessing directive= +// TOP: Identifier: "TARGETED_TOP_H" [3:9 - 3:23] macro definition=TARGETED_TOP_H +// TOP: Punctuation: "#" [5:1 - 5:2] inclusion directive=targeted-nested1.h +// TOP: Identifier: "include" [5:2 - 5:9] inclusion directive=targeted-nested1.h +// TOP: Literal: ""targeted-nested1.h"" [5:10 - 5:30] inclusion directive=targeted-nested1.h // TOP: Keyword: "enum" [7:1 - 7:5] EnumDecl=:7:1 (Definition) // TOP: Punctuation: "{" [7:6 - 7:7] EnumDecl=:7:1 (Definition) // TOP: Identifier: "VALUE" [8:3 - 8:8] EnumConstantDecl=VALUE:8:3 (Definition) diff --git a/test/Index/usrs.m b/test/Index/usrs.m index be0e323..dccfb75 100644 --- a/test/Index/usrs.m +++ b/test/Index/usrs.m @@ -86,6 +86,7 @@ int test_multi_declaration(void) { id var_ext; } @property (assign) id pro_ext; +-(int)methodWithFn:(void (*)(int *p))fn; @end // RUN: c-index-test -test-load-source-usrs all -target x86_64-apple-macosx10.7 %s | FileCheck %s @@ -146,7 +147,7 @@ int test_multi_declaration(void) { // CHECK: usrs.m c:objc(pl)P1 Extent=[79:1 - 81:5] // CHECK: usrs.m c:objc(pl)P1(im)method Extent=[80:1 - 80:16] // CHECK: usrs.m c:objc(cs)CWithExt2 Extent=[83:1 - 84:5] -// CHECK: usrs.m c:objc(ext)CWithExt2@usrs.m@1111 Extent=[85:1 - 89:5] +// CHECK: usrs.m c:objc(ext)CWithExt2@usrs.m@1111 Extent=[85:1 - 90:5] // CHECK: usrs.m c:objc(cs)CWithExt2@var_ext Extent=[86:3 - 86:13] // CHECK: usrs.m c:objc(cs)CWithExt2(py)pro_ext Extent=[88:1 - 88:30] // CHECK: usrs.m c:objc(cs)CWithExt2(im)pro_ext Extent=[88:23 - 88:30] @@ -279,4 +280,6 @@ int test_multi_declaration(void) { // CHECK-source: usrs.m:76:10: IntegerLiteral= Extent=[76:10 - 76:11] // CHECK-source: usrs.m:79:11: ObjCProtocolDecl=P1:79:11 (Definition) Extent=[79:1 - 81:5] // CHECK-source: usrs.m:80:9: ObjCInstanceMethodDecl=method:80:9 Extent=[80:1 - 80:16] - +// CHECK-source: usrs.m:89:7: ObjCInstanceMethodDecl=methodWithFn::89:7 Extent=[89:1 - 89:41] +// CHECK-source: usrs.m:89:38: ParmDecl=fn:89:38 (Definition) Extent=[89:21 - 89:40] +// CHECK-source: usrs.m:89:35: ParmDecl=p:89:35 (Definition) Extent=[89:30 - 89:36] diff --git a/test/Lexer/cxx1y_binary_literal.cpp b/test/Lexer/cxx1y_binary_literal.cpp new file mode 100644 index 0000000..96dce3d --- /dev/null +++ b/test/Lexer/cxx1y_binary_literal.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=c++1y %s -verify + +static_assert(0b1001 == 9, ""); + +using I = int; +using I = decltype(0b101001); +using ULL = unsigned long long; +using ULL = decltype(0b10101001ULL); + +constexpr unsigned long long operator""_foo(unsigned long long n) { + return n * 2; +} +static_assert(0b10001111_foo == 286, ""); + +int k1 = 0b1234; // expected-error {{invalid digit '2' in binary constant}} +// FIXME: If we ever need to support a standard suffix starting with [a-f], +// we'll need to rework our binary literal parsing rules. +int k2 = 0b10010f; // expected-error {{invalid digit 'f' in binary constant}} +int k3 = 0b10010g; // expected-error {{invalid suffix 'g' on integer constant}} diff --git a/test/Lexer/has_extension_cxx.cpp b/test/Lexer/has_extension_cxx.cpp index 6ffeebd..68b542f 100644 --- a/test/Lexer/has_extension_cxx.cpp +++ b/test/Lexer/has_extension_cxx.cpp @@ -47,3 +47,9 @@ int no_local_type_template_args(); #endif // CHECK: has_local_type_template_args + +#if __has_extension(cxx_binary_literals) +int has_binary_literals(); +#endif + +// CHECK: has_binary_literals diff --git a/test/Lexer/has_feature_c1x.c b/test/Lexer/has_feature_c1x.c index c9a5f56..e26e309 100644 --- a/test/Lexer/has_feature_c1x.c +++ b/test/Lexer/has_feature_c1x.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -E -std=c1x %s -o - | FileCheck --check-prefix=CHECK-1X %s +// RUN: %clang_cc1 -E -triple x86_64-linux-gnu -std=c1x %s -o - | FileCheck --check-prefix=CHECK-1X %s // RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-1X %s #if __has_feature(c_atomic) @@ -37,6 +37,15 @@ int no_alignas(); // CHECK-1X: has_alignas // CHECK-NO-1X: no_alignas +#if __has_feature(c_thread_local) +int has_thread_local(); +#else +int no_thread_local(); +#endif + +// CHECK-1X: has_thread_local +// CHECK-NO-1X: no_thread_local + #if __STDC_VERSION__ > 199901L int is_c1x(); #else diff --git a/test/Lexer/has_feature_cxx0x.cpp b/test/Lexer/has_feature_cxx0x.cpp index 8e0222d..62a965c 100644 --- a/test/Lexer/has_feature_cxx0x.cpp +++ b/test/Lexer/has_feature_cxx0x.cpp @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -E -std=c++11 %s -o - | FileCheck --check-prefix=CHECK-0X %s -// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-0X %s +// RUN: %clang_cc1 -E -triple x86_64-linux-gnu -std=c++11 %s -o - | FileCheck --check-prefix=CHECK-11 %s +// RUN: %clang_cc1 -E -triple armv7-apple-darwin -std=c++11 %s -o - | FileCheck --check-prefix=CHECK-NO-TLS %s +// RUN: %clang_cc1 -E -triple x86_64-linux-gnu %s -o - | FileCheck --check-prefix=CHECK-NO-11 %s +// RUN: %clang_cc1 -E -triple x86_64-linux-gnu -std=c++1y %s -o - | FileCheck --check-prefix=CHECK-1Y %s #if __has_feature(cxx_atomic) int has_atomic(); @@ -7,8 +9,9 @@ int has_atomic(); int no_atomic(); #endif -// CHECK-0X: has_atomic -// CHECK-NO-0X: no_atomic +// CHECK-1Y: has_atomic +// CHECK-11: has_atomic +// CHECK-NO-11: no_atomic #if __has_feature(cxx_lambdas) int has_lambdas(); @@ -16,8 +19,9 @@ int has_lambdas(); int no_lambdas(); #endif -// CHECK-0X: has_lambdas -// CHECK-NO-0X: no_lambdas +// CHECK-1Y: has_lambdas +// CHECK-11: has_lambdas +// CHECK-NO-11: no_lambdas #if __has_feature(cxx_nullptr) @@ -26,8 +30,9 @@ int has_nullptr(); int no_nullptr(); #endif -// CHECK-0X: has_nullptr -// CHECK-NO-0X: no_nullptr +// CHECK-1Y: has_nullptr +// CHECK-11: has_nullptr +// CHECK-NO-11: no_nullptr #if __has_feature(cxx_decltype) @@ -36,8 +41,9 @@ int has_decltype(); int no_decltype(); #endif -// CHECK-0X: has_decltype -// CHECK-NO-0X: no_decltype +// CHECK-1Y: has_decltype +// CHECK-11: has_decltype +// CHECK-NO-11: no_decltype #if __has_feature(cxx_decltype_incomplete_return_types) @@ -46,8 +52,9 @@ int has_decltype_incomplete_return_types(); int no_decltype_incomplete_return_types(); #endif -// CHECK-0X: has_decltype_incomplete_return_types -// CHECK-NO-0X: no_decltype_incomplete_return_types +// CHECK-1Y: has_decltype_incomplete_return_types +// CHECK-11: has_decltype_incomplete_return_types +// CHECK-NO-11: no_decltype_incomplete_return_types #if __has_feature(cxx_auto_type) @@ -56,8 +63,9 @@ int has_auto_type(); int no_auto_type(); #endif -// CHECK-0X: has_auto_type -// CHECK-NO-0X: no_auto_type +// CHECK-1Y: has_auto_type +// CHECK-11: has_auto_type +// CHECK-NO-11: no_auto_type #if __has_feature(cxx_trailing_return) @@ -66,8 +74,9 @@ int has_trailing_return(); int no_trailing_return(); #endif -// CHECK-0X: has_trailing_return -// CHECK-NO-0X: no_trailing_return +// CHECK-1Y: has_trailing_return +// CHECK-11: has_trailing_return +// CHECK-NO-11: no_trailing_return #if __has_feature(cxx_attributes) @@ -76,8 +85,9 @@ int has_attributes(); int no_attributes(); #endif -// CHECK-0X: has_attributes -// CHECK-NO-0X: no_attributes +// CHECK-1Y: has_attributes +// CHECK-11: has_attributes +// CHECK-NO-11: no_attributes #if __has_feature(cxx_static_assert) @@ -86,8 +96,9 @@ int has_static_assert(); int no_static_assert(); #endif -// CHECK-0X: has_static_assert -// CHECK-NO-0X: no_static_assert +// CHECK-1Y: has_static_assert +// CHECK-11: has_static_assert +// CHECK-NO-11: no_static_assert #if __has_feature(cxx_deleted_functions) int has_deleted_functions(); @@ -95,8 +106,9 @@ int has_deleted_functions(); int no_deleted_functions(); #endif -// CHECK-0X: has_deleted_functions -// CHECK-NO-0X: no_deleted_functions +// CHECK-1Y: has_deleted_functions +// CHECK-11: has_deleted_functions +// CHECK-NO-11: no_deleted_functions #if __has_feature(cxx_defaulted_functions) int has_defaulted_functions(); @@ -104,8 +116,9 @@ int has_defaulted_functions(); int no_defaulted_functions(); #endif -// CHECK-0X: has_defaulted_functions -// CHECK-NO-0X: no_defaulted_functions +// CHECK-1Y: has_defaulted_functions +// CHECK-11: has_defaulted_functions +// CHECK-NO-11: no_defaulted_functions #if __has_feature(cxx_rvalue_references) int has_rvalue_references(); @@ -113,8 +126,9 @@ int has_rvalue_references(); int no_rvalue_references(); #endif -// CHECK-0X: has_rvalue_references -// CHECK-NO-0X: no_rvalue_references +// CHECK-1Y: has_rvalue_references +// CHECK-11: has_rvalue_references +// CHECK-NO-11: no_rvalue_references #if __has_feature(cxx_variadic_templates) @@ -123,8 +137,9 @@ int has_variadic_templates(); int no_variadic_templates(); #endif -// CHECK-0X: has_variadic_templates -// CHECK-NO-0X: no_variadic_templates +// CHECK-1Y: has_variadic_templates +// CHECK-11: has_variadic_templates +// CHECK-NO-11: no_variadic_templates #if __has_feature(cxx_inline_namespaces) @@ -133,8 +148,9 @@ int has_inline_namespaces(); int no_inline_namespaces(); #endif -// CHECK-0X: has_inline_namespaces -// CHECK-NO-0X: no_inline_namespaces +// CHECK-1Y: has_inline_namespaces +// CHECK-11: has_inline_namespaces +// CHECK-NO-11: no_inline_namespaces #if __has_feature(cxx_range_for) @@ -143,8 +159,9 @@ int has_range_for(); int no_range_for(); #endif -// CHECK-0X: has_range_for -// CHECK-NO-0X: no_range_for +// CHECK-1Y: has_range_for +// CHECK-11: has_range_for +// CHECK-NO-11: no_range_for #if __has_feature(cxx_reference_qualified_functions) @@ -153,8 +170,9 @@ int has_reference_qualified_functions(); int no_reference_qualified_functions(); #endif -// CHECK-0X: has_reference_qualified_functions -// CHECK-NO-0X: no_reference_qualified_functions +// CHECK-1Y: has_reference_qualified_functions +// CHECK-11: has_reference_qualified_functions +// CHECK-NO-11: no_reference_qualified_functions #if __has_feature(cxx_default_function_template_args) int has_default_function_template_args(); @@ -162,8 +180,9 @@ int has_default_function_template_args(); int no_default_function_template_args(); #endif -// CHECK-0X: has_default_function_template_args -// CHECK-NO-0X: no_default_function_template_args +// CHECK-1Y: has_default_function_template_args +// CHECK-11: has_default_function_template_args +// CHECK-NO-11: no_default_function_template_args #if __has_feature(cxx_noexcept) int has_noexcept(); @@ -171,8 +190,9 @@ int has_noexcept(); int no_noexcept(); #endif -// CHECK-0X: has_noexcept -// CHECK-NO-0X: no_noexcept +// CHECK-1Y: has_noexcept +// CHECK-11: has_noexcept +// CHECK-NO-11: no_noexcept #if __has_feature(cxx_override_control) int has_override_control(); @@ -180,8 +200,9 @@ int has_override_control(); int no_override_control(); #endif -// CHECK-0X: has_override_control -// CHECK-NO-0X: no_override_control +// CHECK-1Y: has_override_control +// CHECK-11: has_override_control +// CHECK-NO-11: no_override_control #if __has_feature(cxx_alias_templates) int has_alias_templates(); @@ -189,8 +210,9 @@ int has_alias_templates(); int no_alias_templates(); #endif -// CHECK-0X: has_alias_templates -// CHECK-NO-0X: no_alias_templates +// CHECK-1Y: has_alias_templates +// CHECK-11: has_alias_templates +// CHECK-NO-11: no_alias_templates #if __has_feature(cxx_implicit_moves) int has_implicit_moves(); @@ -198,8 +220,9 @@ int has_implicit_moves(); int no_implicit_moves(); #endif -// CHECK-0X: has_implicit_moves -// CHECK-NO-0X: no_implicit_moves +// CHECK-1Y: has_implicit_moves +// CHECK-11: has_implicit_moves +// CHECK-NO-11: no_implicit_moves #if __has_feature(cxx_alignas) int has_alignas(); @@ -207,8 +230,9 @@ int has_alignas(); int no_alignas(); #endif -// CHECK-0X: has_alignas -// CHECK-NO-0X: no_alignas +// CHECK-1Y: has_alignas +// CHECK-11: has_alignas +// CHECK-NO-11: no_alignas #if __has_feature(cxx_raw_string_literals) int has_raw_string_literals(); @@ -216,8 +240,9 @@ int has_raw_string_literals(); int no_raw_string_literals(); #endif -// CHECK-0X: has_raw_string_literals -// CHECK-NO-0X: no_raw_string_literals +// CHECK-1Y: has_raw_string_literals +// CHECK-11: has_raw_string_literals +// CHECK-NO-11: no_raw_string_literals #if __has_feature(cxx_unicode_literals) int has_unicode_literals(); @@ -225,8 +250,9 @@ int has_unicode_literals(); int no_unicode_literals(); #endif -// CHECK-0X: has_unicode_literals -// CHECK-NO-0X: no_unicode_literals +// CHECK-1Y: has_unicode_literals +// CHECK-11: has_unicode_literals +// CHECK-NO-11: no_unicode_literals #if __has_feature(cxx_constexpr) int has_constexpr(); @@ -234,8 +260,9 @@ int has_constexpr(); int no_constexpr(); #endif -// CHECK-0X: has_constexpr -// CHECK-NO-0X: no_constexpr +// CHECK-1Y: has_constexpr +// CHECK-11: has_constexpr +// CHECK-NO-11: no_constexpr #if __has_feature(cxx_generalized_initializers) int has_generalized_initializers(); @@ -243,8 +270,9 @@ int has_generalized_initializers(); int no_generalized_initializers(); #endif -// CHECK-0X: has_generalized_initializers -// CHECK-NO-0X: no_generalized_initializers +// CHECK-1Y: has_generalized_initializers +// CHECK-11: has_generalized_initializers +// CHECK-NO-11: no_generalized_initializers #if __has_feature(cxx_unrestricted_unions) int has_unrestricted_unions(); @@ -252,8 +280,9 @@ int has_unrestricted_unions(); int no_unrestricted_unions(); #endif -// CHECK-0X: has_unrestricted_unions -// CHECK-NO-0X: no_unrestricted_unions +// CHECK-1Y: has_unrestricted_unions +// CHECK-11: has_unrestricted_unions +// CHECK-NO-11: no_unrestricted_unions #if __has_feature(cxx_user_literals) int has_user_literals(); @@ -261,8 +290,9 @@ int has_user_literals(); int no_user_literals(); #endif -// CHECK-0X: has_user_literals -// CHECK-NO-0X: no_user_literals +// CHECK-1Y: has_user_literals +// CHECK-11: has_user_literals +// CHECK-NO-11: no_user_literals #if __has_feature(cxx_local_type_template_args) int has_local_type_template_args(); @@ -270,5 +300,49 @@ int has_local_type_template_args(); int no_local_type_template_args(); #endif -// CHECK-0X: has_local_type_template_args -// CHECK-NO-0X: no_local_type_template_args +// CHECK-1Y: has_local_type_template_args +// CHECK-11: has_local_type_template_args +// CHECK-NO-11: no_local_type_template_args + +#if __has_feature(cxx_inheriting_constructors) +int has_inheriting_constructors(); +#else +int no_inheriting_constructors(); +#endif + +// CHECK-1Y: has_inheriting_constructors +// CHECK-11: has_inheriting_constructors +// CHECK-NO-11: no_inheriting_constructors + +#if __has_feature(cxx_thread_local) +int has_thread_local(); +#else +int no_thread_local(); +#endif + +// CHECK-1Y: has_thread_local +// CHECK-11: has_thread_local +// CHECK-NO-11: no_thread_local +// CHECK-NO-TLS: no_thread_local + +// === C++1y features === + +#if __has_feature(cxx_binary_literals) +int has_binary_literals(); +#else +int no_binary_literals(); +#endif + +// CHECK-1Y: has_binary_literals +// CHECK-11: no_binary_literals +// CHECK-NO-11: no_binary_literals + +#if __has_feature(cxx_aggregate_nsdmi) +int has_aggregate_nsdmi(); +#else +int no_aggregate_nsdmi(); +#endif + +// CHECK-1Y: has_aggregate_nsdmi +// CHECK-11: no_aggregate_nsdmi +// CHECK-NO-11: no_aggregate_nsdmi diff --git a/test/Lexer/pragma-message.c b/test/Lexer/pragma-message.c index b67886f..d0bbe9e 100644 --- a/test/Lexer/pragma-message.c +++ b/test/Lexer/pragma-message.c @@ -14,3 +14,19 @@ #pragma message ":O gcc accepts this! " STRING(__LINE__) // expected-warning {{:O gcc accepts this! 14}} #pragma message(invalid) // expected-error {{expected string literal in pragma message}} + +// GCC supports a similar pragma, #pragma GCC warning (which generates a warning +// message) and #pragma GCC error (which generates an error message). + +#pragma GCC warning(":O I'm a message! " STRING(__LINE__)) // expected-warning {{:O I'm a message! 21}} +#pragma GCC warning ":O gcc accepts this! " STRING(__LINE__) // expected-warning {{:O gcc accepts this! 22}} + +#pragma GCC error(":O I'm a message! " STRING(__LINE__)) // expected-error {{:O I'm a message! 24}} +#pragma GCC error ":O gcc accepts this! " STRING(__LINE__) // expected-error {{:O gcc accepts this! 25}} + +#define COMPILE_ERROR(x) _Pragma(STRING2(GCC error(x))) +COMPILE_ERROR("Compile error at line " STRING(__LINE__) "!"); // expected-error {{Compile error at line 28!}} + +#pragma message // expected-error {{pragma message requires parenthesized string}} +#pragma GCC warning("" // expected-error {{pragma warning requires parenthesized string}} +#pragma GCC error(1) // expected-error {{expected string literal in pragma error}} diff --git a/test/Lexer/pragma-message2.c b/test/Lexer/pragma-message2.c new file mode 100644 index 0000000..224ccfb --- /dev/null +++ b/test/Lexer/pragma-message2.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -E -Werror -verify %s 2>&1 | FileCheck %s + +#pragma message "\\test" // expected-warning {{\test}} +// CHECK: #pragma message("\134test") + +#pragma message("\\test") // expected-warning {{\test}} +// CHECK: #pragma message("\134test") + +#pragma GCC warning "\"" "te" "st" "\"" // expected-warning {{"test"}} +// CHECK: #pragma GCC warning "\042test\042" + +#pragma GCC warning("\"" "te" "st" "\"") // expected-warning {{"test"}} +// CHECK: #pragma GCC warning "\042test\042" + +#pragma GCC error "" "[ ]" "" // expected-error {{[ ]}} +// CHECK: #pragma GCC error "[\011]" + +#pragma GCC error("" "[ ]" "") // expected-error {{[ ]}} +// CHECK: #pragma GCC error "[\011]" diff --git a/test/Misc/ast-dump-decl.c b/test/Misc/ast-dump-decl.c index c74da29..94335b8 100644 --- a/test/Misc/ast-dump-decl.c +++ b/test/Misc/ast-dump-decl.c @@ -139,7 +139,7 @@ extern int TestVarDeclSC; // CHECK: VarDecl{{.*}} TestVarDeclSC 'int' extern __thread int TestVarDeclThread; -// CHECK: VarDecl{{.*}} TestVarDeclThread 'int' __thread +// CHECK: VarDecl{{.*}} TestVarDeclThread 'int' tls{{$}} __module_private__ int TestVarDeclPrivate; // CHECK: VarDecl{{.*}} TestVarDeclPrivate 'int' __module_private__ diff --git a/test/Misc/ast-dump-decl.cpp b/test/Misc/ast-dump-decl.cpp index c8f7d2f..31715cd 100644 --- a/test/Misc/ast-dump-decl.cpp +++ b/test/Misc/ast-dump-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s +// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s class testEnumDecl { enum class TestEnumDeclScoped; @@ -92,6 +92,9 @@ class TestCXXRecordDeclPack : public T... { // CHECK-NEXT: public 'T'... // CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack +thread_local int TestThreadLocalInt; +// CHECK: TestThreadLocalInt {{.*}} tls_dynamic + __module_private__ class TestCXXRecordDeclPrivate; // CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPrivate __module_private__ diff --git a/test/Misc/warn-in-system-header.c b/test/Misc/warn-in-system-header.c index 6e0237d..132f083 100644 --- a/test/Misc/warn-in-system-header.c +++ b/test/Misc/warn-in-system-header.c @@ -1,4 +1,4 @@ // RUN: %clang_cc1 -isystem %S %s -fsyntax-only -verify #include <warn-in-system-header.h> -// expected-warning {{the cake is a lie}} +// expected-warning@warn-in-system-header.h:4 {{the cake is a lie}} diff --git a/test/Modules/Inputs/ModuleDiags/has_errors.h b/test/Modules/Inputs/ModuleDiags/has_errors.h new file mode 100644 index 0000000..2c0929a --- /dev/null +++ b/test/Modules/Inputs/ModuleDiags/has_errors.h @@ -0,0 +1,2 @@ +static void foo(void) { } +static void foo(void) { } diff --git a/test/Modules/Inputs/ModuleDiags/has_warnings.h b/test/Modules/Inputs/ModuleDiags/has_warnings.h new file mode 100644 index 0000000..87112be --- /dev/null +++ b/test/Modules/Inputs/ModuleDiags/has_warnings.h @@ -0,0 +1,3 @@ + +int int_val; +float *float_ptr = &int_val; diff --git a/test/Modules/Inputs/ModuleDiags/module.map b/test/Modules/Inputs/ModuleDiags/module.map new file mode 100644 index 0000000..09b2508 --- /dev/null +++ b/test/Modules/Inputs/ModuleDiags/module.map @@ -0,0 +1,7 @@ +module HasWarnings { + header "has_warnings.h" +} + +module HasErrors { + header "has_errors.h" +} diff --git a/test/Modules/Inputs/System/usr/include/dbl_max.h b/test/Modules/Inputs/System/usr/include/dbl_max.h new file mode 100644 index 0000000..9a020d1 --- /dev/null +++ b/test/Modules/Inputs/System/usr/include/dbl_max.h @@ -0,0 +1 @@ +#define DBL_MAX __DBL_MAX__ diff --git a/test/Modules/Inputs/System/usr/include/module.map b/test/Modules/Inputs/System/usr/include/module.map index 884b59c..9b2f3af 100644 --- a/test/Modules/Inputs/System/usr/include/module.map +++ b/test/Modules/Inputs/System/usr/include/module.map @@ -19,3 +19,14 @@ module cstd [system] { header "stdint.h" } } + +module other_constants { + explicit module dbl_max { + header "dbl_max.h" + } +} + +module uses_other_constants { + header "uses_other_constants.h" + export * +} diff --git a/test/Modules/Inputs/System/usr/include/uses_other_constants.h b/test/Modules/Inputs/System/usr/include/uses_other_constants.h new file mode 100644 index 0000000..f6d4cca --- /dev/null +++ b/test/Modules/Inputs/System/usr/include/uses_other_constants.h @@ -0,0 +1,3 @@ +@import other_constants; +#include <float.h> + diff --git a/test/Modules/auto-module-import.m b/test/Modules/auto-module-import.m index 4bd3c52..7351828 100644 --- a/test/Modules/auto-module-import.m +++ b/test/Modules/auto-module-import.m @@ -1,10 +1,10 @@ -// other file: expected-note{{'no_umbrella_A_private' declared here}} - // RUN: rm -rf %t // RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -F %S/Inputs %s -verify #include <DependsOnModule/DependsOnModule.h> // expected-warning{{treating #include as an import of module 'DependsOnModule'}} +// expected-note@Inputs/NoUmbrella.framework/PrivateHeaders/A_Private.h:1{{'no_umbrella_A_private' declared here}} + #ifdef MODULE_H_MACRO # error MODULE_H_MACRO should have been hidden #endif diff --git a/test/Modules/autolink.m b/test/Modules/autolink.m index 7f75473..4bf9d59 100644 --- a/test/Modules/autolink.m +++ b/test/Modules/autolink.m @@ -1,5 +1,6 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -fmodules -fmodules-autolink -F %S/Inputs -I %S/Inputs %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -fno-autolink -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs %s | FileCheck --check-prefix=CHECK-AUTOLINK-DISABLED %s @import autolink.sub2; @@ -38,3 +39,6 @@ int use_no_umbrella() { // CHECK: ![[DEPENDSONMODULE]] = metadata !{metadata !"-framework", metadata !"DependsOnModule"} // CHECK: ![[MODULE]] = metadata !{metadata !"-framework", metadata !"Module"} // CHECK: ![[NOUMBRELLA]] = metadata !{metadata !"-framework", metadata !"NoUmbrella"} + +// CHECK-AUTOLINK-DISABLED: !llvm.module.flags +// CHECK-AUTOLINK-DISABLED-NOT: "Linker Options" diff --git a/test/Modules/compiler_builtins.m b/test/Modules/compiler_builtins.m index 5ea7d79..4b8cb5b 100644 --- a/test/Modules/compiler_builtins.m +++ b/test/Modules/compiler_builtins.m @@ -2,7 +2,6 @@ // RUN: %clang -fsyntax-only -fmodules -fmodules-cache-path=%t -D__need_wint_t %s -Xclang -verify // RUN: %clang -fsyntax-only -std=c99 -fmodules -fmodules-cache-path=%t -D__need_wint_t %s -Xclang -verify // expected-no-diagnostics -// XFAIL: win32 #ifdef __SSE__ @import _Builtin_intrinsics.intel.sse; diff --git a/test/Modules/cstd.m b/test/Modules/cstd.m index 6d896a9..3d1dcf3 100644 --- a/test/Modules/cstd.m +++ b/test/Modules/cstd.m @@ -1,6 +1,9 @@ // RUN: rm -rf %t // RUN: %clang -fsyntax-only -isystem %S/Inputs/System/usr/include -fmodules -fmodules-cache-path=%t -D__need_wint_t -Werror=implicit-function-declaration %s +@import uses_other_constants; +const double other_value = DBL_MAX; + // Supplied by compiler, but referenced from the "/usr/include" module map. @import cstd.float_constants; @@ -16,7 +19,7 @@ void test_fprintf(FILE *file) { // Supplied by compiler, which forwards to the "/usr/include" version. @import cstd.stdint; -my_awesome_nonstandard_integer_type value; +my_awesome_nonstandard_integer_type value2; // Supplied by the compiler; that version wins. @import cstd.stdbool; @@ -25,5 +28,3 @@ my_awesome_nonstandard_integer_type value; # error "bool was not defined!" #endif - - diff --git a/test/Modules/cycles.c b/test/Modules/cycles.c index 4326e76..5f83092 100644 --- a/test/Modules/cycles.c +++ b/test/Modules/cycles.c @@ -6,8 +6,8 @@ // CHECK: While building module 'MutuallyRecursive1' imported from // CHECK: While building module 'MutuallyRecursive2' imported from // CHECK: MutuallyRecursive2.h:3:9: fatal error: cyclic dependency in module 'MutuallyRecursive1': MutuallyRecursive1 -> MutuallyRecursive2 -> MutuallyRecursive1 -// CHECK: While building module 'MutuallyRecursive1' imported from // CHECK: MutuallyRecursive1.h:2:9: fatal error: could not build module 'MutuallyRecursive2' // CHECK: cycles.c:4:9: fatal error: could not build module 'MutuallyRecursive1' -// CHECK-NOT: error: +// CHECK: 3 errors generated + diff --git a/test/Modules/decldef.m b/test/Modules/decldef.m index 7fb8a61..7ed82b5 100644 --- a/test/Modules/decldef.m +++ b/test/Modules/decldef.m @@ -1,8 +1,7 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify - -// In other file: expected-note {{previous definition is here}} +// expected-note@Inputs/def.h:5 {{previous definition is here}} @class Def; Def *def; diff --git a/test/Modules/decldef.mm b/test/Modules/decldef.mm index 732c2a2..593f53b 100644 --- a/test/Modules/decldef.mm +++ b/test/Modules/decldef.mm @@ -1,8 +1,7 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify - -// In other file: expected-note {{previous definition is here}} +// expected-note@Inputs/def.h:5 {{previous definition is here}} @class Def; Def *def; diff --git a/test/Modules/diamond-pch.c b/test/Modules/diamond-pch.c index 079f6af..e7ad02d 100644 --- a/test/Modules/diamond-pch.c +++ b/test/Modules/diamond-pch.c @@ -1,14 +1,20 @@ - - - -// in diamond-bottom.h: expected-note{{passing argument to parameter 'x' here}} +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -x objective-c -emit-pch -fmodules-cache-path=%t -o %t.pch %S/Inputs/diamond.h +// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -include-pch %t.pch %s -verify +// FIXME: When we have a syntax for modules in C, use that. void test_diamond(int i, float f, double d, char c) { top(&i); left(&f); right(&d); bottom(&c); - bottom(&d); // expected-warning{{incompatible pointer types passing 'double *' to parameter of type 'char *'}} + bottom(&d); + // expected-warning@-1{{incompatible pointer types passing 'double *' to parameter of type 'char *'}} + // expected-note@Inputs/diamond_bottom.h:4{{passing argument to parameter 'x' here}} // Names in multiple places in the diamond. top_left(&c); @@ -17,12 +23,3 @@ void test_diamond(int i, float f, double d, char c) { struct left_and_right lr; lr.left = 17; } - -// RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c -emit-pch -fmodules-cache-path=%t -o %t.pch %S/Inputs/diamond.h -// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -include-pch %t.pch %s -verify -// FIXME: When we have a syntax for modules in C, use that. diff --git a/test/Modules/diamond.c b/test/Modules/diamond.c index 0bac1b7..89d5bc0 100644 --- a/test/Modules/diamond.c +++ b/test/Modules/diamond.c @@ -1,7 +1,10 @@ - - - -// in diamond-bottom.h: expected-note{{passing argument to parameter 'x' here}} +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t %s -verify +// FIXME: When we have a syntax for modules in C, use that. @import diamond_bottom; @@ -10,7 +13,9 @@ void test_diamond(int i, float f, double d, char c) { left(&f); right(&d); bottom(&c); - bottom(&d); // expected-warning{{incompatible pointer types passing 'double *' to parameter of type 'char *'}} + bottom(&d); + // expected-warning@-1{{incompatible pointer types passing 'double *' to parameter of type 'char *'}} + // expected-note@Inputs/diamond_bottom.h:4{{passing argument to parameter 'x' here}} // Names in multiple places in the diamond. top_left(&c); @@ -20,10 +25,3 @@ void test_diamond(int i, float f, double d, char c) { lr.left = 17; } -// RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t %s -verify -// FIXME: When we have a syntax for modules in C, use that. diff --git a/test/Modules/linkage-merge.cpp b/test/Modules/linkage-merge.cpp index 4e2ecef..9cc9ae6 100644 --- a/test/Modules/linkage-merge.cpp +++ b/test/Modules/linkage-merge.cpp @@ -1,13 +1,12 @@ -// FIXME: we should be able to put these in the .h file :-( -// expected-note {{target of using declaration}} -// expected-note {{using declaration}} +// RUN: rm -rf %t +// RUN: %clang_cc1 -verify -fmodules -fmodules-cache-path=%t -I %S/Inputs %s #include "linkage-merge-bar.h" static int f(int); int f(int); -static void g(int); // expected-error {{declaration conflicts with target of using declaration already in scope}} - -// RUN: rm -rf %t -// RUN: %clang_cc1 -verify -fmodules -fmodules-cache-path=%t -I %S/Inputs %s +static void g(int); +// expected-error@-1 {{declaration conflicts with target of using declaration already in scope}} +// expected-note@Inputs/linkage-merge-foo.h:2 {{target of using declaration}} +// expected-note@Inputs/linkage-merge-bar.h:3 {{using declaration}} diff --git a/test/Modules/linkage-merge.m b/test/Modules/linkage-merge.m index 16e2205..e838ca1 100644 --- a/test/Modules/linkage-merge.m +++ b/test/Modules/linkage-merge.m @@ -1,27 +1,26 @@ -// In module: expected-note{{previous declaration}} - - - - -// In module: expected-note{{previous definition is here}} +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=linkage_merge_left %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -w %s -verify // Test redeclarations of functions where the original declaration is // still hidden. @import linkage_merge_left; // excludes "sub" -extern int f0(float); // expected-error{{conflicting types for 'f0'}} +extern int f0(float); +// expected-error@-1{{conflicting types for 'f0'}} +// expected-note@Inputs/linkage-merge-sub.h:1{{previous declaration}} + static int f1(float); // okay: considered distinct static int f2(float); // okay: considered distinct extern int f3(float); // okay: considered distinct -extern float v0; // expected-error{{redefinition of 'v0' with a different type: 'float' vs 'int'}} +extern float v0; +// expected-error@-1{{redefinition of 'v0' with a different type: 'float' vs 'int'}} +// expected-note@Inputs/linkage-merge-sub.h:6{{previous definition is here}} + static float v1; static float v2; extern float v3; typedef float T0; - -// RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=linkage_merge_left %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -w %s -verify diff --git a/test/Modules/lookup.cpp b/test/Modules/lookup.cpp index 002b6d1..efd88f4 100644 --- a/test/Modules/lookup.cpp +++ b/test/Modules/lookup.cpp @@ -5,7 +5,7 @@ import lookup_left_cxx; #define IMPORT(X) @import X IMPORT(lookup_right_cxx); -// in lookup_left.hpp: expected-warning@3 {{weak identifier 'weak_identifier' never declared}} +// expected-warning@Inputs/lookup_left.hpp:3 {{weak identifier 'weak_identifier' never declared}} void test(int i, float f) { // unqualified lookup diff --git a/test/Modules/lookup.m b/test/Modules/lookup.m index abe9542..54c7491 100644 --- a/test/Modules/lookup.m +++ b/test/Modules/lookup.m @@ -1,19 +1,19 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_left_objc %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_right_objc %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -verify %s +// RUN: %clang_cc1 -fmodules -ast-print -x objective-c -fmodules-cache-path=%t %s | FileCheck -check-prefix=CHECK-PRINT %s -// lookup_left.h: expected-note{{using}} -// lookup_right.h: expected-note{{also found}} @import lookup_left_objc; @import lookup_right_objc; void test(id x) { - [x method]; // expected-warning{{multiple methods named 'method' found}} + [x method]; +// expected-warning@-1{{multiple methods named 'method' found}} +// expected-note@Inputs/lookup_left.h:2{{using}} +// expected-note@Inputs/lookup_right.h:3{{also found}} } -// RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_left_objc %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_right_objc %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -verify %s -// RUN: %clang_cc1 -fmodules -ast-print -x objective-c -fmodules-cache-path=%t %s | FileCheck -check-prefix=CHECK-PRINT %s - // CHECK-PRINT: - (int) method; // CHECK-PRINT: - (double) method // CHECK-PRINT: void test(id x) diff --git a/test/Modules/macros.c b/test/Modules/macros.c index fc448d9..433e033 100644 --- a/test/Modules/macros.c +++ b/test/Modules/macros.c @@ -8,13 +8,13 @@ // FIXME: When we have a syntax for modules in C, use that. // These notes come from headers in modules, and are bogus. -// FIXME: expected-note{{previous definition is here}} -// FIXME: expected-note{{previous definition is here}} expected-note{{expanding this definition of 'LEFT_RIGHT_DIFFERENT'}} -// expected-note{{other definition of 'TOP_RIGHT_REDEF'}} expected-note{{expanding this definition of 'LEFT_RIGHT_DIFFERENT2'}} -// expected-note{{other definition of 'LEFT_RIGHT_DIFFERENT'}} - - -// expected-note{{expanding this definition of 'TOP_RIGHT_REDEF'}} +// FIXME: expected-note@Inputs/macros_left.h:11{{previous definition is here}} +// FIXME: expected-note@Inputs/macros_right.h:12{{previous definition is here}} +// expected-note@Inputs/macros_right.h:12{{expanding this definition of 'LEFT_RIGHT_DIFFERENT'}} +// expected-note@Inputs/macros_top.h:13{{other definition of 'TOP_RIGHT_REDEF'}} +// expected-note@Inputs/macros_right.h:13{{expanding this definition of 'LEFT_RIGHT_DIFFERENT2'}} +// expected-note@Inputs/macros_left.h:14{{other definition of 'LEFT_RIGHT_DIFFERENT'}} +// expected-note@Inputs/macros_right.h:17{{expanding this definition of 'TOP_RIGHT_REDEF'}} @import macros; diff --git a/test/Modules/method_pool.m b/test/Modules/method_pool.m index 9a8897b..6fd74b0 100644 --- a/test/Modules/method_pool.m +++ b/test/Modules/method_pool.m @@ -8,8 +8,8 @@ - (void)method5:(D*)obj; @end -// in other file: // expected-note@7{{using}} -// in other file: expected-note@12{{also found}} +// expected-note@Inputs/MethodPoolA.h:7{{using}} +// expected-note@Inputs/MethodPoolB.h:12{{also found}} void testMethod1(id object) { [object method1]; @@ -51,8 +51,8 @@ void testMethod3Again(id object) { void testMethod3AgainAgain(id object) { [object method3]; // expected-warning{{multiple methods named 'method3' found}} - // expected-note@2{{using}} - // expected-note@2{{also found}} + // expected-note@Inputs/MethodPoolBSub.h:2{{using}} + // expected-note@Inputs/MethodPoolASub.h:2{{also found}} } void testMethod4Again(id object) { diff --git a/test/Modules/module-private.cpp b/test/Modules/module-private.cpp index d4e73b5..438dcab 100644 --- a/test/Modules/module-private.cpp +++ b/test/Modules/module-private.cpp @@ -15,7 +15,7 @@ int test_broken() { HiddenStruct hidden; // \ // expected-error{{must use 'struct' tag to refer to type 'HiddenStruct' in this scope}} \ // expected-error{{definition of 'struct HiddenStruct' must be imported}} - // expected-note@3 {{previous definition is here}} + // expected-note@Inputs/module_private_left.h:3 {{previous definition is here}} Integer i; // expected-error{{unknown type name 'Integer'}} diff --git a/test/Modules/namespaces.cpp b/test/Modules/namespaces.cpp index 0e9dbff..426e002 100644 --- a/test/Modules/namespaces.cpp +++ b/test/Modules/namespaces.cpp @@ -73,5 +73,5 @@ void testAnonymousNotMerged() { N12::consumeFoo(N12::getFoo()); // expected-error{{cannot initialize a parameter of type 'N12::<anonymous>::Foo *' with an rvalue of type 'N12::<anonymous>::Foo *'}} } -// namespaces-right.h: expected-note@60 {{passing argument to parameter here}} -// namespaces-right.h: expected-note@67 {{passing argument to parameter here}} +// expected-note@Inputs/namespaces-right.h:60 {{passing argument to parameter here}} +// expected-note@Inputs/namespaces-right.h:67 {{passing argument to parameter here}} diff --git a/test/Modules/normal-module-map.cpp b/test/Modules/normal-module-map.cpp index 423e808..8155318 100644 --- a/test/Modules/normal-module-map.cpp +++ b/test/Modules/normal-module-map.cpp @@ -1,5 +1,3 @@ -// Note: inside the module. expected-note{{'nested_umbrella_a' declared here}} - // RUN: rm -rf %t // RUN: %clang_cc1 -x objective-c -fmodules-cache-path=%t -fmodules -I %S/Inputs/normal-module-map %s -verify #include "Umbrella/umbrella_sub.h" @@ -25,7 +23,9 @@ int testNestedUmbrellaA() { } int testNestedUmbrellaBFail() { - return nested_umbrella_b; // expected-error{{use of undeclared identifier 'nested_umbrella_b'; did you mean 'nested_umbrella_a'?}} + return nested_umbrella_b; + // expected-error@-1{{use of undeclared identifier 'nested_umbrella_b'; did you mean 'nested_umbrella_a'?}} + // expected-note@Inputs/normal-module-map/nested_umbrella/a.h:1{{'nested_umbrella_a' declared here}} } @import nested_umbrella.b; diff --git a/test/Modules/objc-categories.m b/test/Modules/objc-categories.m index d3ebcb7..81fb28b 100644 --- a/test/Modules/objc-categories.m +++ b/test/Modules/objc-categories.m @@ -8,11 +8,8 @@ @import category_bottom; - - - -// in category_left.h: expected-note {{previous definition}} -// in category_right.h: expected-warning@11 {{duplicate definition of category}} +// expected-note@Inputs/category_left.h:14 {{previous definition}} +// expected-warning@Inputs/category_right.h:11 {{duplicate definition of category}} @interface Foo(Source) -(void)source; @@ -75,7 +72,7 @@ void test_hidden_right_errors(Foo *foo) { [p4 p4_method]; // expected-warning{{instance method '-p4_method' not found (return type defaults to 'id')}} id p4p = p4.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'id<P4>'}} p4p = foo.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'Foo *'; did you mean 'p3_prop'?}} - // expected-note@7{{'p3_prop' declared here}} + // expected-note@Inputs/category_left_sub.h:7{{'p3_prop' declared here}} } @import category_right.sub; diff --git a/test/Modules/on-demand-build.m b/test/Modules/on-demand-build.m index 31742f7..e958759 100644 --- a/test/Modules/on-demand-build.m +++ b/test/Modules/on-demand-build.m @@ -7,7 +7,7 @@ @interface OtherClass @end -// in module: expected-note@17{{class method 'alloc' is assumed to return an instance of its receiver type ('Module *')}} +// expected-note@Inputs/Module.framework/Headers/Module.h:17{{class method 'alloc' is assumed to return an instance of its receiver type ('Module *')}} void test_getModuleVersion() { const char *version = getModuleVersion(); const char *version2 = [Module version]; diff --git a/test/Modules/redecl-merge.m b/test/Modules/redecl-merge.m index e373667..37e5967 100644 --- a/test/Modules/redecl-merge.m +++ b/test/Modules/redecl-merge.m @@ -27,8 +27,8 @@ int *call_eventually_noreturn_again(void) { int *call_eventually_noreturn2_again(void) { // noreturn and non-noreturn functions have different types eventually_noreturn2(); // expected-error{{call to 'eventually_noreturn2' is ambiguous}} - // expected-note@93{{candidate function}} - // expected-note@90{{candidate function}} + // expected-note@Inputs/redecl-merge-left.h:93{{candidate function}} + // expected-note@Inputs/redecl-merge-right.h:90{{candidate function}} } @implementation A @@ -79,24 +79,26 @@ void testTypedefMerge(int i, double d) { T1 *ip = &i; // FIXME: Typedefs aren't actually merged in the sense of other merges, because // we should only merge them when the types are identical. - // in other file: expected-note@60{{candidate found by name lookup is 'T2'}} - // in other file: expected-note@63{{candidate found by name lookup is 'T2'}} + // expected-note@Inputs/redecl-merge-left.h:60{{candidate found by name lookup is 'T2'}} + // expected-note@Inputs/redecl-merge-right.h:63{{candidate found by name lookup is 'T2'}} T2 *dp = &d; // expected-error{{reference to 'T2' is ambiguous}} } void testFuncMerge(int i) { func0(i); func1(i); - // in other file: expected-note@64{{candidate function}} - // in other file: expected-note@70{{candidate function}} + // expected-note@Inputs/redecl-merge-left.h:64{{candidate function}} + // expected-note@Inputs/redecl-merge-right.h:70{{candidate function}} func2(i); // expected-error{{call to 'func2' is ambiguous}} } void testVarMerge(int i) { var1 = i; - // in other files: expected-note@77 2{{candidate found by name lookup is 'var2'}} + // expected-note@Inputs/redecl-merge-left.h:77{{candidate found by name lookup is 'var2'}} + // expected-note@Inputs/redecl-merge-right.h:77{{candidate found by name lookup is 'var2'}} var2 = i; // expected-error{{reference to 'var2' is ambiguous}} - // in other files: expected-note@79 2{{candidate found by name lookup is 'var3'}} + // expected-note@Inputs/redecl-merge-left.h:79{{candidate found by name lookup is 'var3'}} + // expected-note@Inputs/redecl-merge-right.h:79{{candidate found by name lookup is 'var3'}} var3 = i; // expected-error{{reference to 'var3' is ambiguous}} } diff --git a/test/Modules/redecls/a.h b/test/Modules/redecls/a.h new file mode 100644 index 0000000..1647f86 --- /dev/null +++ b/test/Modules/redecls/a.h @@ -0,0 +1,3 @@ +@interface AA +@end +@class AA; diff --git a/test/Modules/redecls/b.h b/test/Modules/redecls/b.h new file mode 100644 index 0000000..d41573d --- /dev/null +++ b/test/Modules/redecls/b.h @@ -0,0 +1 @@ +@class AA; diff --git a/test/Modules/redecls/main.m b/test/Modules/redecls/main.m new file mode 100644 index 0000000..9ec02b0 --- /dev/null +++ b/test/Modules/redecls/main.m @@ -0,0 +1,27 @@ +// RUN: rm -rf %t.mcp +// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodule-name=a %S/module.map -fmodules-cache-path=%t.mcp +// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodule-name=b %S/module.map -fmodules-cache-path=%t.mcp +// RUN: %clang_cc1 -fmodules %s -emit-pch -o %t1.pch -fmodules-cache-path=%t.mcp +// RUN: %clang_cc1 -fmodules %s -emit-pch -o %t2.pch -include-pch %t1.pch -fmodules-cache-path=%t.mcp +// RUN: %clang_cc1 -fmodules %s -fsyntax-only -include-pch %t2.pch -fmodules-cache-path=%t.mcp -verify + +#ifndef HEADER1 +#define HEADER1 + +@import a; + +#elif !defined(HEADER2) +#define HEADER2 + +@class AA; +@import b; + +#else + +// rdar://13712705 +@interface SS : AA +@end + +#warning parsed this +#endif +// expected-warning@-2{{parsed this}} diff --git a/test/Modules/redecls/module.map b/test/Modules/redecls/module.map new file mode 100644 index 0000000..a365682 --- /dev/null +++ b/test/Modules/redecls/module.map @@ -0,0 +1,2 @@ +module a { header "a.h" } +module b { header "b.h" } diff --git a/test/Modules/serialized-diags.m b/test/Modules/serialized-diags.m new file mode 100644 index 0000000..18bce06 --- /dev/null +++ b/test/Modules/serialized-diags.m @@ -0,0 +1,32 @@ +@import HasWarnings; + +#ifdef WITH_ERRORS +@import HasErrors; +#endif + +float float_val; +double *double_ptr = &float_val; + +// RUN: rm -rf %t %t.diag %t.out +// RUN: %clang -fmodules -fmodules-cache-path=%t/ModuleCache -I %S/Inputs/ModuleDiags -fsyntax-only %s --serialize-diagnostics %t.diag > /dev/null 2>&1 +// RUN: c-index-test -read-diagnostics %t.diag > %t.out 2>&1 +// RUN: FileCheck --input-file=%t.out %s + +// CHECK: has_warnings.h:3:8: warning: incompatible pointer types initializing 'float *' +// CHECK: serialized-diags.m:1:9: note: while building module 'HasWarnings' imported from +// CHECK: serialized-diags.m:8:9: warning: incompatible pointer types initializing 'double *' +// CHECK: Number of diagnostics: 2 + +// RUN: rm -rf %t %t.diag_errors %t.out_errors +// RUN: not %clang -fmodules -fmodules-cache-path=%t/ModuleCache -I %S/Inputs/ModuleDiags -fsyntax-only -DWITH_ERRORS %s --serialize-diagnostics %t.diag_errors > /dev/null 2>&1 +// RUN: c-index-test -read-diagnostics %t.diag_errors > %t.out_errors 2>&1 +// RUN: FileCheck -check-prefix=CHECK-WITH-ERRORS --input-file=%t.out_errors %s + +// CHECK-WITH-ERRORS: has_warnings.h:3:8: warning: incompatible pointer types initializing 'float *' +// CHECK-WITH-ERRORS: serialized-diags.m:1:9: note: while building module 'HasWarnings' +// CHECK-WITH-ERRORS: has_errors.h:2:13: error: redefinition of 'foo' +// CHECK-WITH-ERRORS: serialized-diags.m:4:9: note: while building module 'HasErrors' +// CHECK-WITH-ERRORS: has_errors.h:1:13: note: previous definition is here +// CHECK-WITH-ERRORS: serialized-diags.m:4:9: fatal: could not build module 'HasErrors' +// CHECK-WITH-ERRORS: Number of diagnostics: 3 + diff --git a/test/Modules/subframeworks.m b/test/Modules/subframeworks.m index 22dfcca..ad70cc2 100644 --- a/test/Modules/subframeworks.m +++ b/test/Modules/subframeworks.m @@ -23,7 +23,7 @@ CXXOnly cxxonly; @import HasSubModules; -// expected-warning@1{{treating #include as an import of module 'HasSubModules.Sub.Types'}} +// expected-warning@Inputs/HasSubModules.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h:1{{treating #include as an import of module 'HasSubModules.Sub.Types'}} #import <HasSubModules/HasSubModulesPriv.h> struct FrameworkSubStruct ss; diff --git a/test/Modules/system_version.m b/test/Modules/system_version.m new file mode 100644 index 0000000..85b3263 --- /dev/null +++ b/test/Modules/system_version.m @@ -0,0 +1,32 @@ +// Test checking that we're hashing a system version file in the +// module hash. +// REQUIRES: shell + +// First, build a system root. +// RUN: rm -rf %t +// RUN: mkdir -p %t/usr/include +// RUN: cp %S/Inputs/Modified/A.h %t/usr/include +// RUN: cp %S/Inputs/Modified/B.h %t/usr/include +// RUN: cp %S/Inputs/Modified/module.map %t/usr/include + +// Run once with no system version file. We should end up with one module. +// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify +// RUN: ls -R %t | grep -c ModA.pcm| grep 1 + +// Add a system version file and run again. We should now have two +// module variants. +// RUN: mkdir -p %t/System/Library/CoreServices +// RUN: echo "hello" > %t/System/Library/CoreServices/SystemVersion.plist +// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify +// RUN: ls -R %t | grep -c ModA.pcm| grep 2 + +// Change the system version file and run again. We should now have three +// module variants. +// RUN: mkdir -p %t/System/Library/CoreServices +// RUN: echo "modules" > %t/System/Library/CoreServices/SystemVersion.plist +// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify +// RUN: ls -R %t | grep -c ModA.pcm| grep 3 + +// expected-no-diagnostics +@import ModA; + diff --git a/test/PCH/captured-stmt.cpp b/test/PCH/captured-stmt.cpp new file mode 100644 index 0000000..6f5ca38 --- /dev/null +++ b/test/PCH/captured-stmt.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -x c++-header -emit-pch %s -o %t +// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s + +// expected-no-diagnostics + +#ifndef HEADER_INCLUDED +#define HEADER_INCLUDED + +static inline void foo(int &x, int y) { + // Capturing x and y + #pragma clang __debug captured + { + x += y; + } +} + +struct C { + int val; + + explicit C(int v) : val(v) { } + + void bar(int &x) { + // Capturing x and this + #pragma clang __debug captured + { + x += val; + } + } +}; + +#else + +void test_foo(int &x) { + foo(x, 10); +} + +void test_bar(int &x) { + C Obj(10); + Obj.bar(x); +} + +#endif diff --git a/test/PCH/cxx-typeid.cpp b/test/PCH/cxx-typeid.cpp index d1e0f9d..534863a 100644 --- a/test/PCH/cxx-typeid.cpp +++ b/test/PCH/cxx-typeid.cpp @@ -1,8 +1,8 @@ // Test this without pch. -// RUN: %clang -include %S/cxx-typeid.h -fsyntax-only -Xclang -verify %s +// RUN: %clang_cc1 -include %S/cxx-typeid.h -fsyntax-only -verify %s -// RUN: %clang -ccc-pch-is-pch -x c++-header -o %t.gch %S/cxx-typeid.h -// RUN: %clang -ccc-pch-is-pch -include %t -fsyntax-only -Xclang -verify %s +// RUN: %clang_cc1 -x c++-header -emit-pch -o %t.pch %S/cxx-typeid.h +// RUN: %clang_cc1 -include-pch %t.pch -fsyntax-only -verify %s // expected-no-diagnostics diff --git a/test/PCH/cxx-typeid.h b/test/PCH/cxx-typeid.h index aa3b16a..f10f4de 100644 --- a/test/PCH/cxx-typeid.h +++ b/test/PCH/cxx-typeid.h @@ -1,3 +1,44 @@ // Header for PCH test cxx-typeid.cpp -#include <typeinfo> +#ifndef CXX_TYPEID_H +#define CXX_TYPEID_H + +namespace std { + +class type_info +{ +public: + virtual ~type_info(); + + bool operator==(const type_info& rhs) const; + bool operator!=(const type_info& rhs) const; + + bool before(const type_info& rhs) const; + unsigned long hash_code() const; + const char* name() const; + + type_info(const type_info& rhs); + type_info& operator=(const type_info& rhs); +}; + +class bad_cast +{ +public: + bad_cast(); + bad_cast(const bad_cast&); + bad_cast& operator=(const bad_cast&); + virtual const char* what() const; +}; + +class bad_typeid +{ +public: + bad_typeid(); + bad_typeid(const bad_typeid&); + bad_typeid& operator=(const bad_typeid&); + virtual const char* what() const; +}; + +} // std + +#endif diff --git a/test/PCH/cxx-using.cpp b/test/PCH/cxx-using.cpp index 2ca7dad..2cab1f0 100644 --- a/test/PCH/cxx-using.cpp +++ b/test/PCH/cxx-using.cpp @@ -6,10 +6,9 @@ // RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s void m() { - D s; // expected-note {{candidate function}} + D s; s.f(); // expected-error {{no matching member}} } - - -// expected-note {{candidate function}} +// expected-note@cxx-using.h:9 {{candidate function}} +// expected-note@cxx-using.h:15 {{candidate function}} diff --git a/test/PCH/cxx11-statement-attributes.cpp b/test/PCH/cxx11-statement-attributes.cpp index 3bb7b40..722ca6e 100644 --- a/test/PCH/cxx11-statement-attributes.cpp +++ b/test/PCH/cxx11-statement-attributes.cpp @@ -4,8 +4,7 @@ // RUN: %clang_cc1 -x c++-header -emit-pch -std=c++11 -o %t %S/Inputs/cxx11-statement-attributes.h // RUN: %clang_cc1 -include-pch %t -std=c++11 -Wimplicit-fallthrough -fsyntax-only %s -o - -verify -// Warning from Inputs/cxx11-statement-attributes.h: -// expected-warning@10 {{fallthrough annotation does not directly precede switch label}} +// expected-warning@Inputs/cxx11-statement-attributes.h:10 {{fallthrough annotation does not directly precede switch label}} void g(int n) { f<1>(n); // expected-note {{in instantiation of function template specialization 'f<1>' requested here}} diff --git a/test/PCH/cxx1y-decltype-auto.cpp b/test/PCH/cxx1y-decltype-auto.cpp new file mode 100644 index 0000000..a1c9339 --- /dev/null +++ b/test/PCH/cxx1y-decltype-auto.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch %s -o %t +// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t -verify %s + +#ifndef HEADER_INCLUDED + +#define HEADER_INCLUDED + +template<typename T> void f(T t) { + auto a = t.x; + decltype(auto) b = t.x; + auto c = (t.x); + decltype(auto) d = (t.x); +} + +#else + +struct Z { + int x : 5; // expected-note {{bit-field}} +}; + +// expected-error@12 {{non-const reference cannot bind to bit-field 'x'}} +template void f(Z); // expected-note {{in instantiation of}} + +#endif diff --git a/test/PCH/cxx1y-default-initializer.cpp b/test/PCH/cxx1y-default-initializer.cpp new file mode 100644 index 0000000..5a68f27 --- /dev/null +++ b/test/PCH/cxx1y-default-initializer.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch %s -o %t +// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t -verify %s + +#ifndef HEADER_INCLUDED + +#define HEADER_INCLUDED + +struct A { + int x; + int y = 3; + int z = x + y; +}; +template<typename T> constexpr A make() { return A {}; } +template<typename T> constexpr A make(T t) { return A { t }; } + +struct B { + int z1, z2 = z1; + constexpr B(int k) : z1(k) {} +}; + +#else + +static_assert(A{}.z == 3, ""); +static_assert(A{1}.z == 4, ""); +static_assert(A{.y = 5}.z == 5, ""); // expected-warning {{C99}} +static_assert(A{3, .y = 1}.z == 4, ""); // expected-warning {{C99}} +static_assert(make<int>().z == 3, ""); +static_assert(make<int>(12).z == 15, ""); + +#endif diff --git a/test/PCH/functions.c b/test/PCH/functions.c index 35e3921..fa2ba8d 100644 --- a/test/PCH/functions.c +++ b/test/PCH/functions.c @@ -4,18 +4,20 @@ // Test with pch. // RUN: %clang_cc1 -emit-pch -o %t %S/functions.h // RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s -// expected-note{{'f1' declared here}} + int f0(int x0, int y0, ...) { return x0 + y0; } -// expected-note{{passing argument to parameter here}} + float *test_f1(int val, double x, double y) { if (val > 5) return f1(x, y); else return f1(x); // expected-error{{too few arguments to function call}} + // expected-note@functions.h:7{{'f1' declared here}} } void test_g0(int *x, float * y) { g0(y); // expected-warning{{incompatible pointer types passing 'float *' to parameter of type 'int *'}} + // expected-note@functions.h:9{{passing argument to parameter here}} g0(x); } diff --git a/test/PCH/headersearch.cpp b/test/PCH/headersearch.cpp index 8ca0c36..4b24ac6 100644 --- a/test/PCH/headersearch.cpp +++ b/test/PCH/headersearch.cpp @@ -20,15 +20,15 @@ // RUN: cp -pR %t_orig %t_moved // Check diagnostic with location in original source: -// RUN: %clang_cc1 -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -Wpadded -emit-obj -o %t.o %s 2> %t.stderr +// RUN: %clang_cc1 -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -Wpadded -emit-llvm-only %s 2> %t.stderr // RUN: grep 'struct orig_sub' %t.stderr // Check diagnostic with 2nd location in original source: -// RUN: not %clang_cc1 -DREDECL -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -emit-obj -o %t.o %s 2> %t.stderr +// RUN: not %clang_cc1 -DREDECL -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -emit-llvm-only %s 2> %t.stderr // RUN: grep 'void foo' %t.stderr // Check diagnostic with instantiation location in original source: -// RUN: not %clang_cc1 -DINSTANTIATION -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -emit-obj -o %t.o %s 2> %t.stderr +// RUN: not %clang_cc1 -DINSTANTIATION -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -emit-llvm-only %s 2> %t.stderr // RUN: grep 'orig_sub2_1' %t.stderr void qq(orig_sub*) {all();} diff --git a/test/PCH/method_pool.m b/test/PCH/method_pool.m index 20010fb..139f8ba 100644 --- a/test/PCH/method_pool.m +++ b/test/PCH/method_pool.m @@ -9,13 +9,5 @@ int message_id(id x) { return [x instMethod:17]; // expected-warning{{multiple methods}} } - - - - -/* Whitespace below is significant */ -/* expected-note{{using}} */ - - - -/* expected-note{{also}} */ +/* expected-note@method_pool.h:17{{using}} */ +/* expected-note@method_pool.h:21{{also}} */ diff --git a/test/PCH/nonvisible-external-defs.c b/test/PCH/nonvisible-external-defs.c index 49392ca..092e2c9 100644 --- a/test/PCH/nonvisible-external-defs.c +++ b/test/PCH/nonvisible-external-defs.c @@ -7,4 +7,4 @@ int g(int, float); // expected-error{{conflicting types}} -// expected-note{{previous declaration}} +// expected-note@nonvisible-external-defs.h:10{{previous declaration}} diff --git a/test/PCH/reloc.c b/test/PCH/reloc.c index 4c426e4..8dabb8b 100644 --- a/test/PCH/reloc.c +++ b/test/PCH/reloc.c @@ -10,5 +10,5 @@ int x = 2; // expected-error{{redefinition}} int y = 5; // expected-error{{redefinition}} -// expected-note{{previous definition}} -// expected-note{{previous definition}} +// expected-note@libroot/usr/include/reloc.h:13{{previous definition}} +// expected-note@libroot/usr/include/reloc2.h:14{{previous definition}} diff --git a/test/PCH/tentative-defs.c b/test/PCH/tentative-defs.c index 0072818..4288230 100644 --- a/test/PCH/tentative-defs.c +++ b/test/PCH/tentative-defs.c @@ -5,5 +5,4 @@ // RUN: grep "@variable = common global i32 0" %t | count 1 // RUN: grep "@incomplete_array = common global .*1 x i32" %t | count 1 - -// FIXME: tentative-defs.h expected-warning{{tentative}} +// FIXME: expected-warning@tentative-defs.h:9{{tentative}} diff --git a/test/PCH/thread-local.cpp b/test/PCH/thread-local.cpp new file mode 100644 index 0000000..f65c12a --- /dev/null +++ b/test/PCH/thread-local.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -triple x86_64-linux-gnu -emit-pch %s -o %t +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -triple x86_64-linux-gnu -include-pch %t -verify %s + +#ifndef HEADER_INCLUDED + +#define HEADER_INCLUDED +extern thread_local int a; +extern _Thread_local int b; +extern int c; + +#else + +_Thread_local int a; // expected-error {{thread-local declaration of 'a' with static initialization follows declaration with dynamic initialization}} +// expected-note@7 {{previous declaration is here}} +thread_local int b; // expected-error {{thread-local declaration of 'b' with dynamic initialization follows declaration with static initialization}} +// expected-note@8 {{previous declaration is here}} +thread_local int c; // expected-error {{thread-local declaration of 'c' follows non-thread-local declaration}} +// expected-note@9 {{previous declaration is here}} + +#endif diff --git a/test/PCH/typo.cpp b/test/PCH/typo.cpp index f8161d1..6ab66c2 100644 --- a/test/PCH/typo.cpp +++ b/test/PCH/typo.cpp @@ -1,17 +1,14 @@ - -// In header: expected-note{{'boost::function' declared here}} - - -// In header: expected-note{{'boost::graph::adjacency_list' declared here}} - - - -adjacent_list<int, int> g; // expected-error{{no template named 'adjacent_list'; did you mean 'boost::graph::adjacency_list'?}} -Function<int(int)> f; // expected-error{{no template named 'Function'; did you mean 'boost::function'?}} - // Without PCH // RUN: %clang_cc1 -include %S/Inputs/typo.hpp -verify %s // With PCH // RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/Inputs/typo.hpp // RUN: %clang_cc1 -include-pch %t -verify %s + +adjacent_list<int, int> g; +// expected-error@-1{{no template named 'adjacent_list'; did you mean 'boost::graph::adjacency_list'?}} +// expected-note@Inputs/typo.hpp:5{{'boost::graph::adjacency_list' declared here}} + +Function<int(int)> f; +// expected-error@-1{{no template named 'Function'; did you mean 'boost::function'?}} +// expected-note@Inputs/typo.hpp:2{{'boost::function' declared here}} diff --git a/test/PCH/typo.m b/test/PCH/typo.m index c6f0275..876b943 100644 --- a/test/PCH/typo.m +++ b/test/PCH/typo.m @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -x objective-c-header -emit-pch -o %t %S/Inputs/typo.h // RUN: %clang_cc1 -include-pch %t -verify %s -// In header: expected-note{{declared here}} + void f() { [NSstring alloc]; // expected-error{{unknown receiver 'NSstring'; did you mean 'NSString'?}} + // expected-note@Inputs/typo.h:3{{declared here}} } diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c index 4c6f4f8..35c63d4 100644 --- a/test/Parser/MicrosoftExtensions.c +++ b/test/Parser/MicrosoftExtensions.c @@ -6,7 +6,7 @@ void (*__fastcall fastpfunc)(); struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {}; /* expected-warning{{__declspec attribute 'novtable' is not supported}} */ extern __declspec(dllimport) void __stdcall VarR4FromDec(); __declspec(deprecated) __declspec(deprecated) char * __cdecl ltoa( long _Val, char * _DstBuf, int _Radix); -__declspec(noalias) __declspec(restrict) void * __cdecl xxx( void * _Memory ); /* expected-warning{{__declspec attribute 'noalias' is not supported}} expected-warning{{__declspec attribute 'restrict' is not supported}} */ +__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx( void * _Memory ); /* expected-warning{{__declspec attribute 'safebuffers' is not supported}} expected-warning{{__declspec attribute 'noalias' is not supported}} expected-warning{{__declspec attribute 'restrict' is not supported}} */ typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR; void * __ptr64 PtrToPtr64(const void *p) diff --git a/test/Parser/MicrosoftExtensions.cpp b/test/Parser/MicrosoftExtensions.cpp index fd38dca..d8a597a 100644 --- a/test/Parser/MicrosoftExtensions.cpp +++ b/test/Parser/MicrosoftExtensions.cpp @@ -331,3 +331,32 @@ namespace Inheritance { class __multiple_inheritance B; class __virtual_inheritance C; } + +struct StructWithProperty { + __declspec(property) int V0; // expected-error {{expected '(' after 'property'}} + __declspec(property()) int V1; // expected-error {{property does not specify a getter or a putter}} + __declspec(property(set)) int V2; // expected-error {{putter for property must be specified as 'put', not 'set'}} expected-error {{expected '=' after 'set'}} + __declspec(property(ptu)) int V3; // expected-error {{missing 'get=' or 'put='}} + __declspec(property(ptu=PutV)) int V4; // expected-error {{expected 'get' or 'put' in property declaration}} + __declspec(property(get)) int V5; // expected-error {{expected '=' after 'get'}} + __declspec(property(get&)) int V6; // expected-error {{expected '=' after 'get'}} + __declspec(property(get=)) int V7; // expected-error {{expected name of accessor method}} + __declspec(property(get=GetV)) int V8; // no-warning + __declspec(property(get=GetV=)) int V9; // expected-error {{expected ',' or ')' at end of property accessor list}} + __declspec(property(get=GetV,)) int V10; // expected-error {{expected 'get' or 'put' in property declaration}} + __declspec(property(get=GetV,put=SetV)) int V11; // no-warning + __declspec(property(get=GetV,put=SetV,get=GetV)) int V12; // expected-error {{property declaration specifies 'get' accessor twice}} + + int GetV() { return 123; } + void SetV(int v) {} +}; +void TestProperty() { + StructWithProperty sp; + sp.V8; + sp.V8 = 0; // expected-error {{no setter defined for property 'V8'}} + int i = sp.V11; + sp.V11 = i++; + sp.V11 += 8; + sp.V11++; + ++sp.V11; +} diff --git a/test/Parser/captured-statements.c b/test/Parser/captured-statements.c new file mode 100644 index 0000000..30dddb5 --- /dev/null +++ b/test/Parser/captured-statements.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -verify %s + +void test1() +{ + #pragma clang __debug captured x // expected-warning {{extra tokens at end of #pragma clang __debug captured directive}} + { + } +} + +void test2() +{ + #pragma clang __debug captured + int x; // expected-error {{expected '{'}} +} diff --git a/test/Parser/cxx0x-ambig.cpp b/test/Parser/cxx0x-ambig.cpp index 3b864f9..4c22ed3 100644 --- a/test/Parser/cxx0x-ambig.cpp +++ b/test/Parser/cxx0x-ambig.cpp @@ -38,8 +38,8 @@ namespace bitfield { constexpr T() {} constexpr T(int) {} constexpr T(T, T, T, T) {} - constexpr T operator=(T) { return *this; } - constexpr operator int() { return 4; } + constexpr T operator=(T) const { return *this; } + constexpr operator int() const { return 4; } }; constexpr T a, b, c, d; @@ -68,7 +68,7 @@ namespace bitfield { }; struct U { - constexpr operator T() { return T(); } // expected-note 2{{candidate}} + constexpr operator T() const { return T(); } // expected-note 2{{candidate}} }; // This could be a bit-field. struct S7 { diff --git a/test/Parser/cxx0x-decl.cpp b/test/Parser/cxx0x-decl.cpp index b9441fd..e6cba72 100644 --- a/test/Parser/cxx0x-decl.cpp +++ b/test/Parser/cxx0x-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -pedantic-errors %s +// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -pedantic-errors -triple x86_64-linux-gnu %s // Make sure we know these are legitimate commas and not typos for ';'. namespace Commas { @@ -46,16 +46,15 @@ using PR14855 = int S::; // expected-error {{expected ';' after alias declaratio // a constexpr function. struct ConstexprTrailingReturn { int n; - constexpr auto f() -> decltype((n)); + constexpr auto f() const -> decltype((n)); }; constexpr const int &ConstexprTrailingReturn::f() const { return n; } namespace TestIsValidAfterTypeSpecifier { struct s {} v; -// FIXME: We should accept this once we support thread_local. struct s -thread_local tl; // expected-error {{expected unqualified-id}} +thread_local tl; struct s &r0 = v; diff --git a/test/Parser/objc-boxing.m b/test/Parser/objc-boxing.m index a16a137..a6bb024 100644 --- a/test/Parser/objc-boxing.m +++ b/test/Parser/objc-boxing.m @@ -24,3 +24,11 @@ id missing_parentheses() { return @(5; // expected-error {{expected ')'}} \ // expected-note {{to match this '('}} } + +// rdar://10679157 +void bar(id p); +void foo(id p) { + bar(@{p, p}); // expected-error {{expected ':'}} + bar(0); + bar(0); +} diff --git a/test/Parser/objc-error-qualified-implementation.m b/test/Parser/objc-error-qualified-implementation.m new file mode 100644 index 0000000..444fb5d --- /dev/null +++ b/test/Parser/objc-error-qualified-implementation.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s +// rdar://12233858 + +@protocol P +@end + +@interface I @end + +@implementation I<P> @end // expected-error {{@implementation declaration can not be protocol qualified}} + +@interface J < P,P > +@end + + +@implementation J < P,P > // expected-error {{@implementation declaration can not be protocol qualified}} +@end + +@interface K @end + +@implementation K <P // expected-error {{@implementation declaration can not be protocol qualified}} +@end // expected-error {{expected '>'}} diff --git a/test/Parser/objcxx11-initialized-temps.mm b/test/Parser/objcxx11-initialized-temps.mm new file mode 100644 index 0000000..96f19fe --- /dev/null +++ b/test/Parser/objcxx11-initialized-temps.mm @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// expected-no-diagnostics +// rdar://12788429 + +struct CGPoint { + double x; + double y; +}; +typedef struct CGPoint CGPoint; + +struct CGSize { + double width; + double height; +}; +typedef struct CGSize CGSize; + +struct CGRect { + CGPoint origin; + CGSize size; +}; +typedef struct CGRect CGRect; + +typedef CGRect NSRect; + +void HappySetFrame(NSRect frame) {} + +__attribute__((objc_root_class)) +@interface NSObject @end + +@implementation NSObject +- (void) sadSetFrame: (NSRect)frame {} + +- (void) nothing +{ + HappySetFrame({{0,0}, {13,14}}); + [self sadSetFrame: {{0,0}, {13,14}}]; +} +@end diff --git a/test/Parser/pragma-options.c b/test/Parser/pragma-options.c index 7844e71..d168a27 100644 --- a/test/Parser/pragma-options.c +++ b/test/Parser/pragma-options.c @@ -20,3 +20,15 @@ #pragma align=reset #pragma align=mac68k #pragma align=power + +// PR13580 +struct S +{ + char a[3]; +#pragma align=packed + struct T + { + char b; + int c; + } d; +}; diff --git a/test/Parser/pragma-pack.c b/test/Parser/pragma-pack.c index 84778cd..172a332 100644 --- a/test/Parser/pragma-pack.c +++ b/test/Parser/pragma-pack.c @@ -30,3 +30,17 @@ _Pragma("pack(push)") /* expected-warning {{expected integer or identifier in '#pragma pack'}}*/ _Pragma("pack(push,)") + +// PR13580 +struct S +{ + char a[3]; +#pragma pack(1) + struct T + { + char b; + int c; + } d; +#pragma pack() + int e; +}; diff --git a/test/Preprocessor/aarch64-target-features.c b/test/Preprocessor/aarch64-target-features.c index 65104e3..8bb8427 100644 --- a/test/Preprocessor/aarch64-target-features.c +++ b/test/Preprocessor/aarch64-target-features.c @@ -1,30 +1,32 @@ // RUN: %clang -target aarch64-none-linux-gnu -x c -E -dM %s -o - | FileCheck %s -// CHECK: __AARCH 8 // CHECK: __AARCH64EL__ -// CHECK: __AARCH_ACLE 101 // CHECK-NOT: __AARCH_ADVSIMD_FP // CHECK-NOT: __AARCH_FEATURE_ADVSIMD -// CHECK-NOT: __AARCH_FEATURE_BIG_ENDIAN -// CHECK: __AARCH_FEATURE_CLZ 1 -// CHECK: __AARCH_FEATURE_FMA 1 -// CHECK: __AARCH_FEATURE_LDREX 0xf -// CHECK: __AARCH_FEATURE_UNALIGNED 1 -// CHECK: __AARCH_FP 0xe -// CHECK-NOT: __AARCH_FP_FAST -// CHECK: __AARCH_FP16_FORMAT_IEEE 1 -// CHECK: __AARCH_FP_FENV_ROUNDING 1 -// CHECK: __AARCH_PROFILE 'A' -// CHECK: __AARCH_SIZEOF_MINIMAL_ENUM 4 -// CHECK: __AARCH_SIZEOF_WCHAR_T 4 +// CHECK: __ARM_ACLE 101 +// CHECK: __ARM_ARCH 8 +// CHECK: __ARM_ARCH_PROFILE 'A' +// CHECK-NOT: __ARM_FEATURE_BIG_ENDIAN +// CHECK: __ARM_FEATURE_CLZ 1 +// CHECK: __ARM_FEATURE_FMA 1 +// CHECK: __ARM_FEATURE_LDREX 0xf +// CHECK: __ARM_FEATURE_UNALIGNED 1 +// CHECK: __ARM_FP 0xe +// CHECK-NOT: __ARM_FP_FAST +// CHECK: __ARM_FP16_FORMAT_IEEE 1 +// CHECK: __ARM_FP_FENV_ROUNDING 1 +// CHECK-NOT: __ARM_NEON_FP +// CHECK-NOT: __ARM_NEON +// CHECK: __ARM_SIZEOF_MINIMAL_ENUM 4 +// CHECK: __ARM_SIZEOF_WCHAR_T 4 // CHECK: __aarch64__ // RUN: %clang -target aarch64-none-linux-gnu -ffast-math -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FASTMATH %s -// CHECK-FASTMATH: __AARCH_FP_FAST +// CHECK-FASTMATH: __ARM_FP_FAST // RUN: %clang -target aarch64-none-linux-gnu -fshort-wchar -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SHORTWCHAR %s -// CHECK-SHORTWCHAR: __AARCH_SIZEOF_WCHAR_T 2 +// CHECK-SHORTWCHAR: __ARM_SIZEOF_WCHAR_T 2 // RUN: %clang -target aarch64-none-linux-gnu -fshort-enums -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SHORTENUMS %s -// CHECK-SHORTENUMS: __AARCH_SIZEOF_MINIMAL_ENUM 1 +// CHECK-SHORTENUMS: __ARM_SIZEOF_MINIMAL_ENUM 1 diff --git a/test/Preprocessor/cxx_oper_spelling.cpp b/test/Preprocessor/cxx_oper_spelling.cpp index 0ae9afd..5152977 100644 --- a/test/Preprocessor/cxx_oper_spelling.cpp +++ b/test/Preprocessor/cxx_oper_spelling.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -E %s | grep 'a: "and"' +// RUN: %clang_cc1 -E %s | FileCheck %s #define X(A) #A @@ -8,4 +8,5 @@ // // This should be spelled as 'and', not '&&' a: X(and) +// CHECK: a: "and" diff --git a/test/Preprocessor/dependencies-and-pp.c b/test/Preprocessor/dependencies-and-pp.c index 7877df3..fb49638 100644 --- a/test/Preprocessor/dependencies-and-pp.c +++ b/test/Preprocessor/dependencies-and-pp.c @@ -3,29 +3,34 @@ // RUN: %clang -E -o %t.1 %s // RUN: %clang -E -MD -MF %t.d -MT foo -o %t.2 %s // RUN: diff %t.1 %t.2 -// RUN: grep "foo:" %t.d -// RUN: grep "dependencies-and-pp.c" %t.d +// RUN: FileCheck -check-prefix=TEST1 %s < %t.d +// TEST1: foo: +// TEST1: dependencies-and-pp.c // Test -MQ flag without quoting // RUN: %clang -E -MD -MF %t.d -MQ foo -o %t %s -// RUN: grep "foo:" %t.d +// RUN: FileCheck -check-prefix=TEST2 %s < %t.d +// TEST2: foo: // Test -MQ flag with quoting // RUN: %clang -E -MD -MF %t.d -MQ '$fo\ooo ooo\ ooo\\ ooo#oo' -o %t %s -// RUN: fgrep '$$fo\ooo\ ooo\\\ ooo\\\\\ ooo\#oo:' %t.d +// RUN: FileCheck -check-prefix=TEST3 %s < %t.d +// TEST3: $$fo\ooo\ ooo\\\ ooo\\\\\ ooo\#oo: // Test consecutive -MT flags // RUN: %clang -E -MD -MF %t.d -MT foo -MT bar -MT baz -o %t %s // RUN: diff %t.1 %t -// RUN: fgrep "foo bar baz:" %t.d +// RUN: FileCheck -check-prefix=TEST4 %s < %t.d +// TEST4: foo bar baz: // Test consecutive -MT and -MQ flags // RUN: %clang -E -MD -MF %t.d -MT foo -MQ '$(bar)' -MT 'b az' -MQ 'qu ux' -MQ ' space' -o %t %s -// RUN: fgrep 'foo $$(bar) b az qu\ ux \ space:' %t.d +// RUN: FileCheck -check-prefix=TEST5 %s < %t.d +// TEST5: foo $$(bar) b az qu\ ux \ space: // TODO: Test default target without quoting // TODO: Test default target with quoting diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c index 90b8466..9671f7e 100644 --- a/test/Preprocessor/init.c +++ b/test/Preprocessor/init.c @@ -8,7 +8,17 @@ // BLOCKS:#define __BLOCKS__ 1 // BLOCKS:#define __block __attribute__((__blocks__(byref))) // -// +// +// RUN: %clang_cc1 -x c++ -std=c++1y -E -dM < /dev/null | FileCheck -check-prefix CXX1Y %s +// +// CXX1Y:#define __GNUG__ +// CXX1Y:#define __GXX_EXPERIMENTAL_CXX0X__ 1 +// CXX1Y:#define __GXX_RTTI 1 +// CXX1Y:#define __GXX_WEAK__ 1 +// CXX1Y:#define __cplusplus 201305L +// CXX1Y:#define __private_extern__ extern +// +// // RUN: %clang_cc1 -x c++ -std=c++11 -E -dM < /dev/null | FileCheck -check-prefix CXX11 %s // // CXX11:#define __GNUG__ @@ -67,6 +77,14 @@ // FREESTANDING:#define __STDC_HOSTED__ 0 // // +// RUN: %clang_cc1 -x c++ -std=gnu++1y -E -dM < /dev/null | FileCheck -check-prefix GXX1Y %s +// +// GXX1Y:#define __GNUG__ +// GXX1Y:#define __GXX_WEAK__ 1 +// GXX1Y:#define __cplusplus 201305L +// GXX1Y:#define __private_extern__ extern +// +// // RUN: %clang_cc1 -x c++ -std=gnu++11 -E -dM < /dev/null | FileCheck -check-prefix GXX11 %s // // GXX11:#define __GNUG__ @@ -88,10 +106,24 @@ // C94:#define __STDC_VERSION__ 199409L // // -// RUN: %clang_cc1 -fms-extensions -triple i686-pc-win32 -fobjc-runtime=gcc -E -dM < /dev/null | FileCheck -check-prefix MSEXT %s +// RUN: %clang_cc1 -fms-extensions -triple i686-pc-win32 -E -dM < /dev/null | FileCheck -check-prefix MSEXT %s // // MSEXT-NOT:#define __STDC__ // MSEXT:#define _INTEGRAL_MAX_BITS 64 +// MSEXT-NOT:#define _NATIVE_WCHAR_T_DEFINED 1 +// MSEXT-NOT:#define _WCHAR_T_DEFINED 1 +// +// +// RUN: %clang_cc1 -x c++ -fms-extensions -triple i686-pc-win32 -E -dM < /dev/null | FileCheck -check-prefix MSEXT-CXX %s +// +// MSEXT-CXX:#define _NATIVE_WCHAR_T_DEFINED 1 +// MSEXT-CXX:#define _WCHAR_T_DEFINED 1 +// +// +// RUN: %clang_cc1 -x c++ -fno-wchar -fms-extensions -triple i686-pc-win32 -E -dM < /dev/null | FileCheck -check-prefix MSEXT-CXX-NOWCHAR %s +// +// MSEXT-CXX-NOWCHAR-NOT:#define _NATIVE_WCHAR_T_DEFINED 1 +// MSEXT-CXX-NOWCHAR-NOT:#define _WCHAR_T_DEFINED 1 // // // RUN: %clang_cc1 -x objective-c -E -dM < /dev/null | FileCheck -check-prefix OBJC %s @@ -1150,6 +1182,12 @@ // MIPS-FABI-SINGLE:#define __mips_hard_float 1 // MIPS-FABI-SINGLE:#define __mips_single_float 1 // +// RUN: %clang_cc1 -target-feature +soft-float -target-feature +single-float \ +// RUN: -E -dM -ffreestanding -triple=mips-none-none < /dev/null \ +// RUN: | FileCheck -check-prefix MIPS-FABI-SINGLE-SOFT %s +// MIPS-FABI-SINGLE-SOFT:#define __mips_single_float 1 +// MIPS-FABI-SINGLE-SOFT:#define __mips_soft_float 1 +// // Check MIPS features macros // // RUN: %clang_cc1 -target-feature +mips16 \ @@ -1162,6 +1200,16 @@ // RUN: | FileCheck -check-prefix NOMIPS16 %s // NOMIPS16-NOT:#define __mips16 1 // +// RUN: %clang_cc1 -target-feature +micromips \ +// RUN: -E -dM -triple=mips-none-none < /dev/null \ +// RUN: | FileCheck -check-prefix MICROMIPS %s +// MICROMIPS:#define __mips_micromips 1 +// +// RUN: %clang_cc1 -target-feature -micromips \ +// RUN: -E -dM -triple=mips-none-none < /dev/null \ +// RUN: | FileCheck -check-prefix NOMICROMIPS %s +// NOMICROMIPS-NOT:#define __mips_micromips 1 +// // RUN: %clang_cc1 -target-feature +dsp \ // RUN: -E -dM -triple=mips-none-none < /dev/null \ // RUN: | FileCheck -check-prefix MIPS-DSP %s @@ -2147,6 +2195,98 @@ // PPC-LINUX:#define __powerpc__ 1 // PPC-LINUX:#define __ppc__ 1 // +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=s390x-none-none -fno-signed-char < /dev/null | FileCheck -check-prefix S390X %s +// +// S390X:#define __CHAR16_TYPE__ unsigned short +// S390X:#define __CHAR32_TYPE__ unsigned int +// S390X:#define __CHAR_BIT__ 8 +// S390X:#define __CHAR_UNSIGNED__ 1 +// S390X:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 +// S390X:#define __DBL_DIG__ 15 +// S390X:#define __DBL_EPSILON__ 2.2204460492503131e-16 +// S390X:#define __DBL_HAS_DENORM__ 1 +// S390X:#define __DBL_HAS_INFINITY__ 1 +// S390X:#define __DBL_HAS_QUIET_NAN__ 1 +// S390X:#define __DBL_MANT_DIG__ 53 +// S390X:#define __DBL_MAX_10_EXP__ 308 +// S390X:#define __DBL_MAX_EXP__ 1024 +// S390X:#define __DBL_MAX__ 1.7976931348623157e+308 +// S390X:#define __DBL_MIN_10_EXP__ (-307) +// S390X:#define __DBL_MIN_EXP__ (-1021) +// S390X:#define __DBL_MIN__ 2.2250738585072014e-308 +// S390X:#define __DECIMAL_DIG__ 36 +// S390X:#define __FLT_DENORM_MIN__ 1.40129846e-45F +// S390X:#define __FLT_DIG__ 6 +// S390X:#define __FLT_EPSILON__ 1.19209290e-7F +// S390X:#define __FLT_EVAL_METHOD__ 0 +// S390X:#define __FLT_HAS_DENORM__ 1 +// S390X:#define __FLT_HAS_INFINITY__ 1 +// S390X:#define __FLT_HAS_QUIET_NAN__ 1 +// S390X:#define __FLT_MANT_DIG__ 24 +// S390X:#define __FLT_MAX_10_EXP__ 38 +// S390X:#define __FLT_MAX_EXP__ 128 +// S390X:#define __FLT_MAX__ 3.40282347e+38F +// S390X:#define __FLT_MIN_10_EXP__ (-37) +// S390X:#define __FLT_MIN_EXP__ (-125) +// S390X:#define __FLT_MIN__ 1.17549435e-38F +// S390X:#define __FLT_RADIX__ 2 +// S390X:#define __INT16_TYPE__ short +// S390X:#define __INT32_TYPE__ int +// S390X:#define __INT64_C_SUFFIX__ L +// S390X:#define __INT64_TYPE__ long long int +// S390X:#define __INT8_TYPE__ char +// S390X:#define __INTMAX_MAX__ 9223372036854775807LL +// S390X:#define __INTMAX_TYPE__ long long int +// S390X:#define __INTMAX_WIDTH__ 64 +// S390X:#define __INTPTR_TYPE__ long int +// S390X:#define __INTPTR_WIDTH__ 64 +// S390X:#define __INT_MAX__ 2147483647 +// S390X:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L +// S390X:#define __LDBL_DIG__ 33 +// S390X:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L +// S390X:#define __LDBL_HAS_DENORM__ 1 +// S390X:#define __LDBL_HAS_INFINITY__ 1 +// S390X:#define __LDBL_HAS_QUIET_NAN__ 1 +// S390X:#define __LDBL_MANT_DIG__ 113 +// S390X:#define __LDBL_MAX_10_EXP__ 4932 +// S390X:#define __LDBL_MAX_EXP__ 16384 +// S390X:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L +// S390X:#define __LDBL_MIN_10_EXP__ (-4931) +// S390X:#define __LDBL_MIN_EXP__ (-16381) +// S390X:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L +// S390X:#define __LONG_LONG_MAX__ 9223372036854775807LL +// S390X:#define __LONG_MAX__ 9223372036854775807L +// S390X:#define __NO_INLINE__ 1 +// S390X:#define __POINTER_WIDTH__ 64 +// S390X:#define __PTRDIFF_TYPE__ long int +// S390X:#define __PTRDIFF_WIDTH__ 64 +// S390X:#define __SCHAR_MAX__ 127 +// S390X:#define __SHRT_MAX__ 32767 +// S390X:#define __SIG_ATOMIC_WIDTH__ 32 +// S390X:#define __SIZEOF_DOUBLE__ 8 +// S390X:#define __SIZEOF_FLOAT__ 4 +// S390X:#define __SIZEOF_INT__ 4 +// S390X:#define __SIZEOF_LONG_DOUBLE__ 16 +// S390X:#define __SIZEOF_LONG_LONG__ 8 +// S390X:#define __SIZEOF_LONG__ 8 +// S390X:#define __SIZEOF_POINTER__ 8 +// S390X:#define __SIZEOF_PTRDIFF_T__ 8 +// S390X:#define __SIZEOF_SHORT__ 2 +// S390X:#define __SIZEOF_SIZE_T__ 8 +// S390X:#define __SIZEOF_WCHAR_T__ 4 +// S390X:#define __SIZEOF_WINT_T__ 4 +// S390X:#define __SIZE_TYPE__ long unsigned int +// S390X:#define __SIZE_WIDTH__ 64 +// S390X:#define __UINTMAX_TYPE__ long long unsigned int +// S390X:#define __USER_LABEL_PREFIX__ _ +// S390X:#define __WCHAR_MAX__ 2147483647 +// S390X:#define __WCHAR_TYPE__ int +// S390X:#define __WCHAR_WIDTH__ 32 +// S390X:#define __WINT_TYPE__ int +// S390X:#define __WINT_WIDTH__ 32 +// S390X:#define __s390__ 1 +// S390X:#define __s390x__ 1 +// // RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc-none-none < /dev/null | FileCheck -check-prefix SPARC %s // // SPARC-NOT:#define _LP64 diff --git a/test/Preprocessor/line-directive.c b/test/Preprocessor/line-directive.c index ffa7c5a..ea0a36f 100644 --- a/test/Preprocessor/line-directive.c +++ b/test/Preprocessor/line-directive.c @@ -29,7 +29,7 @@ # 42 "foo" 3 1 // expected-error {{invalid flag line marker directive}} # 42 "foo" 42 // expected-error {{invalid flag line marker directive}} # 42 "foo" 1 2 // expected-error {{invalid flag line marker directive}} - +# 42a33 // expected-error {{GNU line marker directive requires a simple digit sequence}} // These are checked by the RUN line. #line 92 "blonk.c" @@ -85,12 +85,20 @@ typedef int q; // original definition in system header, should not diagnose. #line 010 // expected-warning {{#line directive interprets number as decimal, not octal}} extern int array[__LINE__ == 10 ? 1:-1]; +# 020 // expected-warning {{GNU line marker directive interprets number as decimal, not octal}} +extern int array_gnuline[__LINE__ == 20 ? 1:-1]; + /* PR3917 */ #line 41 extern char array2[\ _\ _LINE__ == 42 ? 1: -1]; /* line marker is location of first _ */ +# 51 +extern char array2_gnuline[\ +_\ +_LINE__ == 52 ? 1: -1]; /* line marker is location of first _ */ + // rdar://11550996 #line 0 "line-directive.c" // expected-warning {{#line directive with zero argument is a GNU extension}} undefined t; // expected-error {{unknown type name 'undefined'}} diff --git a/test/Preprocessor/pp-modules.c b/test/Preprocessor/pp-modules.c new file mode 100644 index 0000000..213a5fd --- /dev/null +++ b/test/Preprocessor/pp-modules.c @@ -0,0 +1,15 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c %s -F %S/../Modules/Inputs -E -o - | FileCheck %s + +// CHECK: int bar(); +int bar(); +// CHECK: @import Module; /* clang -E: implicit import for "{{.*Headers[/\\]Module.h}}" */ +#include <Module/Module.h> +// CHECK: int foo(); +int foo(); +// CHECK: @import Module; /* clang -E: implicit import for "{{.*Headers[/\\]Module.h}}" */ +#include <Module/Module.h> + +#include "pp-modules.h" // CHECK: # 1 "{{.*}}pp-modules.h" 1 +// CHECK: @import Module; /* clang -E: implicit import for "{{.*}}Module.h" */{{$}} +// CHECK: # 14 "{{.*}}pp-modules.c" 2 diff --git a/test/Preprocessor/pp-modules.h b/test/Preprocessor/pp-modules.h new file mode 100644 index 0000000..e4ccacf --- /dev/null +++ b/test/Preprocessor/pp-modules.h @@ -0,0 +1 @@ +#include <Module/Module.h> diff --git a/test/Preprocessor/pragma-captured.c b/test/Preprocessor/pragma-captured.c new file mode 100644 index 0000000..be2a62b --- /dev/null +++ b/test/Preprocessor/pragma-captured.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -E %s | FileCheck %s + +// Test pragma clang __debug captured, for Captured Statements + +void test1() +{ + #pragma clang __debug captured + { + } +// CHECK: void test1() +// CHECK: { +// CHECK: #pragma clang __debug captured +} diff --git a/test/Preprocessor/pragma_sysheader.c b/test/Preprocessor/pragma_sysheader.c index 075c980..3c94363 100644 --- a/test/Preprocessor/pragma_sysheader.c +++ b/test/Preprocessor/pragma_sysheader.c @@ -7,7 +7,7 @@ // PR9861: Verify that line markers are not messed up in -E mode. // CHECK: # 1 "{{.*}}pragma_sysheader.h" 1 -// CHECK-NEXT: # 1 "{{.*}}pragma_sysheader.h" 3 +// CHECK-NEXT: # 2 "{{.*}}pragma_sysheader.h" 3 // CHECK-NEXT: typedef int x; // CHECK-NEXT: typedef int x; // CHECK-NEXT: # 6 "{{.*}}pragma_sysheader.c" 2 diff --git a/test/Preprocessor/predefined-arch-macros.c b/test/Preprocessor/predefined-arch-macros.c index 680f39a..d0125cd 100644 --- a/test/Preprocessor/predefined-arch-macros.c +++ b/test/Preprocessor/predefined-arch-macros.c @@ -1094,6 +1094,52 @@ // CHECK_BTVER1_M64: #define __tune_btver1__ 1 // CHECK_BTVER1_M64: #define __x86_64 1 // CHECK_BTVER1_M64: #define __x86_64__ 1 +// RUN: %clang -march=btver2 -m32 -E -dM %s -o - 2>&1 \ +// RUN: -target i386-unknown-linux \ +// RUN: | FileCheck %s -check-prefix=CHECK_BTVER2_M32 +// CHECK_BTVER2_M32-NOT: #define __3dNOW_A__ 1 +// CHECK_BTVER2_M32-NOT: #define __3dNOW__ 1 +// CHECK_BTVER2_M32: #define __AES__ 1 +// CHECK_BTVER2_M32: #define __AVX__ 1 +// CHECK_BTVER2_M32: #define __LZCNT__ 1 +// CHECK_BTVER2_M32: #define __MMX__ 1 +// CHECK_BTVER2_M32: #define __POPCNT__ 1 +// CHECK_BTVER2_M32: #define __SSE2_MATH__ 1 +// CHECK_BTVER2_M32: #define __SSE2__ 1 +// CHECK_BTVER2_M32: #define __SSE3__ 1 +// CHECK_BTVER2_M32: #define __SSE4A__ 1 +// CHECK_BTVER2_M32: #define __SSE_MATH__ 1 +// CHECK_BTVER2_M32: #define __SSE__ 1 +// CHECK_BTVER2_M32: #define __SSSE3__ 1 +// CHECK_BTVER2_M32: #define __btver2 1 +// CHECK_BTVER2_M32: #define __btver2__ 1 +// CHECK_BTVER2_M32: #define __i386 1 +// CHECK_BTVER2_M32: #define __i386__ 1 +// CHECK_BTVER2_M32: #define __tune_btver2__ 1 +// RUN: %clang -march=btver2 -m64 -E -dM %s -o - 2>&1 \ +// RUN: -target i386-unknown-linux \ +// RUN: | FileCheck %s -check-prefix=CHECK_BTVER2_M64 +// CHECK_BTVER2_M64-NOT: #define __3dNOW_A__ 1 +// CHECK_BTVER2_M64-NOT: #define __3dNOW__ 1 +// CHECK_BTVER2_M64: #define __AES__ 1 +// CHECK_BTVER2_M64: #define __AVX__ 1 +// CHECK_BTVER2_M64: #define __LZCNT__ 1 +// CHECK_BTVER2_M64: #define __MMX__ 1 +// CHECK_BTVER2_M64: #define __POPCNT__ 1 +// CHECK_BTVER2_M64: #define __SSE2_MATH__ 1 +// CHECK_BTVER2_M64: #define __SSE2__ 1 +// CHECK_BTVER2_M64: #define __SSE3__ 1 +// CHECK_BTVER2_M64: #define __SSE4A__ 1 +// CHECK_BTVER2_M64: #define __SSE_MATH__ 1 +// CHECK_BTVER2_M64: #define __SSE__ 1 +// CHECK_BTVER2_M64: #define __SSSE3__ 1 +// CHECK_BTVER2_M64: #define __amd64 1 +// CHECK_BTVER2_M64: #define __amd64__ 1 +// CHECK_BTVER2_M64: #define __btver2 1 +// CHECK_BTVER2_M64: #define __btver2__ 1 +// CHECK_BTVER2_M64: #define __tune_btver2__ 1 +// CHECK_BTVER2_M64: #define __x86_64 1 +// CHECK_BTVER2_M64: #define __x86_64__ 1 // RUN: %clang -march=bdver1 -m32 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ // RUN: | FileCheck %s -check-prefix=CHECK_BDVER1_M32 diff --git a/test/Preprocessor/stdint.c b/test/Preprocessor/stdint.c index 70c106b..c3be05d 100644 --- a/test/Preprocessor/stdint.c +++ b/test/Preprocessor/stdint.c @@ -528,6 +528,113 @@ // PPC:INTMAX_C_(0) 0LL // PPC:UINTMAX_C_(0) 0ULL // +// RUN: %clang_cc1 -E -ffreestanding -triple=s390x-none-none %s | FileCheck -check-prefix S390X %s +// +// S390X:typedef signed long long int int64_t; +// S390X:typedef unsigned long long int uint64_t; +// S390X:typedef int64_t int_least64_t; +// S390X:typedef uint64_t uint_least64_t; +// S390X:typedef int64_t int_fast64_t; +// S390X:typedef uint64_t uint_fast64_t; +// +// S390X:typedef signed int int32_t; +// S390X:typedef unsigned int uint32_t; +// S390X:typedef int32_t int_least32_t; +// S390X:typedef uint32_t uint_least32_t; +// S390X:typedef int32_t int_fast32_t; +// S390X:typedef uint32_t uint_fast32_t; +// +// S390X:typedef signed short int16_t; +// S390X:typedef unsigned short uint16_t; +// S390X:typedef int16_t int_least16_t; +// S390X:typedef uint16_t uint_least16_t; +// S390X:typedef int16_t int_fast16_t; +// S390X:typedef uint16_t uint_fast16_t; +// +// S390X:typedef signed char int8_t; +// S390X:typedef unsigned char uint8_t; +// S390X:typedef int8_t int_least8_t; +// S390X:typedef uint8_t uint_least8_t; +// S390X:typedef int8_t int_fast8_t; +// S390X:typedef uint8_t uint_fast8_t; +// +// S390X:typedef int64_t intptr_t; +// S390X:typedef uint64_t uintptr_t; +// +// S390X:typedef long long int intmax_t; +// S390X:typedef long long unsigned int uintmax_t; +// +// S390X:INT8_MAX_ 127 +// S390X:INT8_MIN_ (-127 -1) +// S390X:UINT8_MAX_ 255 +// S390X:INT_LEAST8_MIN_ (-127 -1) +// S390X:INT_LEAST8_MAX_ 127 +// S390X:UINT_LEAST8_MAX_ 255 +// S390X:INT_FAST8_MIN_ (-127 -1) +// S390X:INT_FAST8_MAX_ 127 +// S390X:UINT_FAST8_MAX_ 255 +// +// S390X:INT16_MAX_ 32767 +// S390X:INT16_MIN_ (-32767 -1) +// S390X:UINT16_MAX_ 65535 +// S390X:INT_LEAST16_MIN_ (-32767 -1) +// S390X:INT_LEAST16_MAX_ 32767 +// S390X:UINT_LEAST16_MAX_ 65535 +// S390X:INT_FAST16_MIN_ (-32767 -1) +// S390X:INT_FAST16_MAX_ 32767 +// S390X:UINT_FAST16_MAX_ 65535 +// +// S390X:INT32_MAX_ 2147483647 +// S390X:INT32_MIN_ (-2147483647 -1) +// S390X:UINT32_MAX_ 4294967295U +// S390X:INT_LEAST32_MIN_ (-2147483647 -1) +// S390X:INT_LEAST32_MAX_ 2147483647 +// S390X:UINT_LEAST32_MAX_ 4294967295U +// S390X:INT_FAST32_MIN_ (-2147483647 -1) +// S390X:INT_FAST32_MAX_ 2147483647 +// S390X:UINT_FAST32_MAX_ 4294967295U +// +// S390X:INT64_MAX_ 9223372036854775807L +// S390X:INT64_MIN_ (-9223372036854775807LL -1) +// S390X:UINT64_MAX_ 18446744073709551615UL +// S390X:INT_LEAST64_MIN_ (-9223372036854775807LL -1) +// S390X:INT_LEAST64_MAX_ 9223372036854775807L +// S390X:UINT_LEAST64_MAX_ 18446744073709551615UL +// S390X:INT_FAST64_MIN_ (-9223372036854775807LL -1) +// S390X:INT_FAST64_MAX_ 9223372036854775807L +// S390X:UINT_FAST64_MAX_ 18446744073709551615UL +// +// S390X:INTPTR_MIN_ (-9223372036854775807LL -1) +// S390X:INTPTR_MAX_ 9223372036854775807L +// S390X:UINTPTR_MAX_ 18446744073709551615UL +// S390X:PTRDIFF_MIN_ (-9223372036854775807LL -1) +// S390X:PTRDIFF_MAX_ 9223372036854775807L +// S390X:SIZE_MAX_ 18446744073709551615UL +// +// S390X:INTMAX_MIN_ (-9223372036854775807LL -1) +// S390X:INTMAX_MAX_ 9223372036854775807L +// S390X:UINTMAX_MAX_ 18446744073709551615UL +// +// S390X:SIG_ATOMIC_MIN_ (-2147483647 -1) +// S390X:SIG_ATOMIC_MAX_ 2147483647 +// S390X:WINT_MIN_ (-2147483647 -1) +// S390X:WINT_MAX_ 2147483647 +// +// S390X:WCHAR_MAX_ 2147483647 +// S390X:WCHAR_MIN_ (-2147483647 -1) +// +// S390X:INT8_C_(0) 0 +// S390X:UINT8_C_(0) 0U +// S390X:INT16_C_(0) 0 +// S390X:UINT16_C_(0) 0U +// S390X:INT32_C_(0) 0 +// S390X:UINT32_C_(0) 0U +// S390X:INT64_C_(0) 0L +// S390X:UINT64_C_(0) 0UL +// +// S390X:INTMAX_C_(0) 0L +// S390X:UINTMAX_C_(0) 0UL +// // RUN: %clang_cc1 -E -ffreestanding -triple=sparc-none-none %s | FileCheck -check-prefix SPARC %s // // SPARC:typedef signed long long int int64_t; diff --git a/test/Rewriter/rewrite-byref-in-nested-blocks.mm b/test/Rewriter/rewrite-byref-in-nested-blocks.mm index 022bb5f..f416b66 100644 --- a/test/Rewriter/rewrite-byref-in-nested-blocks.mm +++ b/test/Rewriter/rewrite-byref-in-nested-blocks.mm @@ -19,7 +19,7 @@ void f(void (^block)(void)); - (void)foo { __block int kerfluffle; // radar 7692183 - __block x; + __block int x; f(^{ f(^{ y = 42; diff --git a/test/Sema/MicrosoftCompatibility.cpp b/test/Sema/MicrosoftCompatibility.cpp new file mode 100644 index 0000000..15c2558 --- /dev/null +++ b/test/Sema/MicrosoftCompatibility.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility + +// PR15845 +int foo(xxx); // expected-error{{unknown type name}} diff --git a/test/Sema/arm-neon-types.c b/test/Sema/arm-neon-types.c index 1a170db..a49de12 100644 --- a/test/Sema/arm-neon-types.c +++ b/test/Sema/arm-neon-types.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple thumbv7-apple-darwin10 -target-cpu cortex-a8 -fsyntax-only -Wvector-conversion -ffreestanding -verify %s +#ifndef INCLUDE #include <arm_neon.h> @@ -33,3 +34,14 @@ int16x8_t test5(int *p) { void test6(float *p, int32x2_t v) { return vst1_s32(p, v); // expected-warning {{incompatible pointer types}} } + +#define INCLUDE +#include "arm-neon-types.c" +#else + +// Make sure we don't get a warning about using a static function in an +// extern inline function from a header. +extern inline uint8x8_t test7(uint8x8_t a, uint8x8_t b) { + return vadd_u8(a, b); +} +#endif diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c index b3cae60..f92852f 100644 --- a/test/Sema/array-init.c +++ b/test/Sema/array-init.c @@ -187,7 +187,7 @@ char r6[sizeof r5 == 15 ? 1 : -1]; const char r7[] = "zxcv"; char r8[5] = "5char"; char r9[5] = "6chars"; //expected-warning{{initializer-string for char array is too long}} - +unsigned char r10[] = __extension__ (_Generic(0, int: (__extension__ "foo" ))); int r11[0] = {}; //expected-warning{{zero size arrays are an extension}} expected-warning{{use of GNU empty initializer extension}} // Some struct tests diff --git a/test/Sema/asm.c b/test/Sema/asm.c index 2c60085..c81f16a 100644 --- a/test/Sema/asm.c +++ b/test/Sema/asm.c @@ -130,3 +130,19 @@ void test14(struct S *s) { __asm("": : "a"(*s)); // expected-error {{dereference of pointer to incomplete type 'struct S'}} __asm("": "=a" (*s) :); // expected-error {{dereference of pointer to incomplete type 'struct S'}} } + +// PR15759. +double test15() { + double ret = 0; + __asm("0.0":"="(ret)); // expected-error {{invalid output constraint '=' in asm}} + __asm("0.0":"=&"(ret)); // expected-error {{invalid output constraint '=&' in asm}} + __asm("0.0":"+?"(ret)); // expected-error {{invalid output constraint '+?' in asm}} + __asm("0.0":"+!"(ret)); // expected-error {{invalid output constraint '+!' in asm}} + __asm("0.0":"+#"(ret)); // expected-error {{invalid output constraint '+#' in asm}} + __asm("0.0":"+*"(ret)); // expected-error {{invalid output constraint '+*' in asm}} + __asm("0.0":"=%"(ret)); // expected-error {{invalid output constraint '=%' in asm}} + __asm("0.0":"=,="(ret)); // expected-error {{invalid output constraint '=,=' in asm}} + __asm("0.0":"=,g"(ret)); // no-error + __asm("0.0":"=g"(ret)); // no-error + return ret; +} diff --git a/test/Sema/atomic-expr.c b/test/Sema/atomic-expr.c new file mode 100644 index 0000000..ecc04c4 --- /dev/null +++ b/test/Sema/atomic-expr.c @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only +// expected-no-diagnostics + +_Atomic(unsigned int) data1; +int _Atomic data2; + +// Shift operations + +int func_01 (int x) { + return data1 << x; +} + +int func_02 (int x) { + return x << data1; +} + +int func_03 (int x) { + return data2 << x; +} + +int func_04 (int x) { + return x << data2; +} + +int func_05 () { + return data2 << data1; +} + +int func_06 () { + return data1 << data2; +} + +void func_07 (int x) { + data1 <<= x; +} + +void func_08 (int x) { + data2 <<= x; +} + +void func_09 (int* xp) { + *xp <<= data1; +} + +void func_10 (int* xp) { + *xp <<= data2; +} diff --git a/test/Sema/bitfield.c b/test/Sema/bitfield.c index a1ce894..ab05a77 100644 --- a/test/Sema/bitfield.c +++ b/test/Sema/bitfield.c @@ -39,3 +39,18 @@ int y; struct PR8025 { double : 2; // expected-error{{anonymous bit-field has non-integral type 'double'}} }; + +struct Test4 { + unsigned bitX : 4; + unsigned bitY : 4; + unsigned var; +}; +void test4(struct Test4 *t) { + (void) sizeof(t->bitX); // expected-error {{invalid application of 'sizeof' to bit-field}} + (void) sizeof((t->bitY)); // expected-error {{invalid application of 'sizeof' to bit-field}} + (void) sizeof(t->bitX = 4); // not a bitfield designator in C + (void) sizeof(t->bitX += 4); // not a bitfield designator in C + (void) sizeof((void) 0, t->bitX); // not a bitfield designator in C + (void) sizeof(t->var ? t->bitX : t->bitY); // not a bitfield designator in C + (void) sizeof(t->var ? t->bitX : t->bitX); // not a bitfield designator in C +} diff --git a/test/Sema/builtins-aarch64.c b/test/Sema/builtins-aarch64.c new file mode 100644 index 0000000..03e0334 --- /dev/null +++ b/test/Sema/builtins-aarch64.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s + +void test_clear_cache_chars(char *start, char *end) { + __clear_cache(start, end); +} + +void test_clear_cache_voids(void *start, void *end) { + __clear_cache(start, end); +} + +void test_clear_cache_no_args() { + // AArch32 version of this is variadic (at least syntactically). + // However, on AArch64 GCC does not permit this call and the + // implementation I've seen would go disastrously wrong. + __clear_cache(); // expected-error {{too few arguments to function call}} +} diff --git a/test/Sema/captured-statements.c b/test/Sema/captured-statements.c new file mode 100644 index 0000000..9285a78 --- /dev/null +++ b/test/Sema/captured-statements.c @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks + +void test_gotos() { + goto L1; // expected-error {{use of undeclared label 'L1'}} + goto L3; // OK + #pragma clang __debug captured + { +L1: + goto L2; // OK +L2: + goto L3; // expected-error {{use of undeclared label 'L3'}} + } +L3: ; +} + +void test_break_continue() { + while (1) { + #pragma clang __debug captured + { + break; // expected-error {{'break' statement not in loop or switch statement}} + continue; // expected-error {{'continue' statement not in loop statement}} + } + } +} + +void test_return() { + while (1) { + #pragma clang __debug captured + { + return; // expected-error {{cannot return from default captured statement}} + } + } +} + +void test_nest() { + int x; + #pragma clang __debug captured + { + int y; + #pragma clang __debug captured + { + int z; + #pragma clang __debug captured + { + x = z = y; // OK + } + } + } +} + +void test_nest_block() { + __block int x; + int y; + ^{ + int z; + #pragma clang __debug captured + { + x = y; // OK + y = z; // expected-error{{variable is not assignable (missing __block type specifier)}} + z = y; // OK + } + }(); + + __block int a; + int b; + #pragma clang __debug captured + { + __block int c; + int d; + ^{ + a = b; // OK + a = c; // OK + b = d; // OK - Consistent with block inside a lambda + c = a; // OK + d = b; // expected-error{{variable is not assignable (missing __block type specifier)}} + }(); + } +} diff --git a/test/Sema/crash-invalid-array.c b/test/Sema/crash-invalid-array.c index a3bc03b..eeac391 100644 --- a/test/Sema/crash-invalid-array.c +++ b/test/Sema/crash-invalid-array.c @@ -15,3 +15,10 @@ int main() p[i][i] = i; } } + +// rdar://13705391 +void foo(int a[*][2]) {(void)a[0][1]; } // expected-error {{variable length array must be bound in function definition}} +void foo1(int a[2][*]) {(void)a[0][1]; } // expected-error {{variable length array must be bound in function definition}} +void foo2(int a[*][*]) {(void)a[0][1]; } // expected-error {{variable length array must be bound in function definition}} +void foo3(int a[2][*][2]) {(void)a[0][1][1]; } // expected-error {{variable length array must be bound in function definition}} +void foo4(int a[2][*][*]) {(void)a[0][1][1]; } // expected-error {{variable length array must be bound in function definition}} diff --git a/test/Sema/extern-redecl.c b/test/Sema/extern-redecl.c index 9a085de..e9a4c57 100644 --- a/test/Sema/extern-redecl.c +++ b/test/Sema/extern-redecl.c @@ -33,3 +33,32 @@ void test3declarer() { extern int test3_array[]; int x = sizeof(test3_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} } + +void test4() { + extern int test4_array[]; + { + extern int test4_array[100]; + int x = sizeof(test4_array); // fine + } + int x = sizeof(test4_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} +} + +// Test that invalid local extern declarations of library +// builtins behave reasonably. +extern void abort(void); // expected-note 2 {{previous declaration is here}} +extern float *calloc(); // expected-warning {{incompatible redeclaration of library function}} expected-note {{is a builtin}} expected-note 2 {{previous declaration is here}} +void test5a() { + int abort(); // expected-error {{conflicting types}} + float *malloc(); // expected-warning {{incompatible redeclaration of library function}} expected-note 2 {{is a builtin}} + int *calloc(); // expected-error {{conflicting types}} +} +void test5b() { + int abort(); // expected-error {{conflicting types}} + float *malloc(); // expected-warning {{incompatible redeclaration of library function}} + int *calloc(); // expected-error {{conflicting types}} +} +void test5c() { + void (*_abort)(void) = &abort; + void *(*_malloc)() = &malloc; + float *(*_calloc)() = &calloc; +} diff --git a/test/Sema/function-redecl.c b/test/Sema/function-redecl.c index 3ee8763..561f7fa 100644 --- a/test/Sema/function-redecl.c +++ b/test/Sema/function-redecl.c @@ -62,7 +62,7 @@ void test2() { // <rdar://problem/6127293> int outer1(int); // expected-note{{previous declaration is here}} struct outer3 { }; -int outer4(int); +int outer4(int); // expected-note{{previous declaration is here}} int outer5; // expected-note{{previous definition is here}} int *outer7(int); @@ -70,7 +70,7 @@ void outer_test() { int outer1(float); // expected-error{{conflicting types for 'outer1'}} int outer2(int); // expected-note{{previous declaration is here}} int outer3(int); // expected-note{{previous declaration is here}} - int outer4(int); // expected-note{{previous declaration is here}} + int outer4(int); int outer5(int); // expected-error{{redefinition of 'outer5' as different kind of symbol}} int* outer6(int); // expected-note{{previous declaration is here}} int *outer7(int); diff --git a/test/Sema/function.c b/test/Sema/function.c index 1b0dc2a..bbf81a5 100644 --- a/test/Sema/function.c +++ b/test/Sema/function.c @@ -92,3 +92,14 @@ void t20(int i...) { } // expected-error {{requires a comma}} int n; void t21(int n, int (*array)[n]); + +int func_e(int x) { + int func_n(int y) { // expected-error {{function definition is not allowed here}} + if (y > 22) { + return y+2; + } else { + return y-2; + } + } + return x + 3; +} diff --git a/test/Sema/no-documentation-warn-tagdecl-specifier.c b/test/Sema/no-documentation-warn-tagdecl-specifier.c new file mode 100644 index 0000000..a0702ad --- /dev/null +++ b/test/Sema/no-documentation-warn-tagdecl-specifier.c @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -verify %s +// rdar://12390371 + +/** @return s Test*/ +struct s* f(void); +struct s; + +struct s1; +/** @return s1 Test 1*/ +struct s1* f1(void); + +struct s2; +/** @return s2 Test 2*/ +struct s2* f2(void); +struct s2; + +// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}} +/** @return s3 Test 3 - expected warning here */ +struct s3; +struct s3* f3(void); + +/** @return s4 Test 4 */ +struct s4* f4(void); +struct s4 { int is; }; + +// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}} +/** @return s5 Test 5 - expected warning here */ +struct s5 { int is; }; +struct s5* f5(void); + +// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}} +/** @return s6 Test 6 - expected warning here */ +struct s6 *ps6; +struct s6* f6(void); + +// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}} +/** @return s7 Test 7 - expected warning here */ +struct s7; +struct s7* f7(void); + +struct s8 { int is8; }; +/** @return s8 Test 8 */ +struct s4 *f8(struct s8 *p); + + +/** @return e Test*/ +enum e* g(void); +enum e; + +enum e1; +/** @return e1 Test 1*/ +enum e1* g1(void); + +enum e2; +/** @return e2 Test 2*/ +enum e2* g2(void); +enum e2; + +// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}} +/** @return e3 Test 3 - expected warning here */ +enum e3; +enum e3* g3(void); + +/** @return e4 Test 4 */ +enum e4* g4(void); +enum e4 { one }; + +// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}} +/** @return e5 Test 5 - expected warning here */ +enum e5 { two }; +enum e5* g5(void); + +// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}} +/** @return e6 Test 6 - expected warning here */ +enum e6 *pe6; +enum e6* g6(void); + +// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}} +/** @return e7 Test 7 - expected warning here */ +enum e7; +enum e7* g7(void); + +enum e8 { three }; +/** @return e8 Test 8 */ +enum e4 *g8(enum e8 *p); diff --git a/test/Sema/parentheses.c b/test/Sema/parentheses.c index c3b3aa7..300e585 100644 --- a/test/Sema/parentheses.c +++ b/test/Sema/parentheses.c @@ -1,25 +1,44 @@ // RUN: %clang_cc1 -Wparentheses -fsyntax-only -verify %s -// RUN: %clang_cc1 -Wparentheses -fixit %s -o - | %clang_cc1 -Wparentheses -Werror - +// RUN: %clang_cc1 -Wparentheses -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s // Test the various warnings under -Wparentheses void if_assign(void) { int i; if (i = 4) {} // expected-warning {{assignment as a condition}} \ - // expected-note{{use '==' to turn this assignment into an equality comparison}} \ - // expected-note{{place parentheses around the assignment to silence this warning}} + // expected-note{{place parentheses around the assignment to silence this warning}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:7-[[@LINE-3]]:7}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:12}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:9-[[@LINE-5]]:10}:"==" + if ((i = 4)) {} } void bitwise_rel(unsigned i) { (void)(i & 0x2 == 0); // expected-warning {{& has lower precedence than ==}} \ - // expected-note{{place parentheses around the & expression to evaluate it first}} \ - // expected-note{{place parentheses around the '==' expression to silence this warning}} + // expected-note{{place parentheses around the '==' expression to silence this warning}} \ + // expected-note{{place parentheses around the & expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:14-[[@LINE-3]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:22}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:10-[[@LINE-5]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:17-[[@LINE-6]]:17}:")" + (void)(0 == i & 0x2); // expected-warning {{& has lower precedence than ==}} \ - // expected-note{{place parentheses around the & expression to evaluate it first}} \ - // expected-note{{place parentheses around the '==' expression to silence this warning}} + // expected-note{{place parentheses around the '==' expression to silence this warning}} \ + // expected-note{{place parentheses around the & expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:22-[[@LINE-6]]:22}:")" + (void)(i & 0xff < 30); // expected-warning {{& has lower precedence than <}} \ - // expected-note{{place parentheses around the & expression to evaluate it first}} \ - // expected-note{{place parentheses around the '<' expression to silence this warning}} + // expected-note{{place parentheses around the '<' expression to silence this warning}} \ + // expected-note{{place parentheses around the & expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:14-[[@LINE-3]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:10-[[@LINE-5]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:18-[[@LINE-6]]:18}:")" + (void)((i & 0x2) == 0); (void)(i & (0x2 == 0)); // Eager logical op @@ -28,19 +47,33 @@ void bitwise_rel(unsigned i) { (void)(i & i | i); // expected-warning {{'&' within '|'}} \ // expected-note {{place parentheses around the '&' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:15-[[@LINE-3]]:15}:")" (void)(i | i & i); // expected-warning {{'&' within '|'}} \ // expected-note {{place parentheses around the '&' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:14-[[@LINE-2]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:19-[[@LINE-3]]:19}:")" (void)(i || i && i); // expected-warning {{'&&' within '||'}} \ - // expected-note {{place parentheses around the '&&' expression to silence this warning}} + // expected-note {{place parentheses around the '&&' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:14-[[@LINE-2]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:20}:")" + (void)(i || i && "w00t"); // no warning. (void)("w00t" && i || i); // no warning. + (void)(i || i && "w00t" || i); // expected-warning {{'&&' within '||'}} \ // expected-note {{place parentheses around the '&&' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:26-[[@LINE-3]]:26}:")" + (void)(i || "w00t" && i || i); // expected-warning {{'&&' within '||'}} \ // expected-note {{place parentheses around the '&&' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:26-[[@LINE-3]]:26}:")" + (void)(i && i || 0); // no warning. (void)(0 || i && i); // no warning. } @@ -49,25 +82,41 @@ _Bool someConditionFunc(); void conditional_op(int x, int y, _Bool b) { (void)(x + someConditionFunc() ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '+'}} \ - // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \ - // expected-note {{place parentheses around the '+' expression to silence this warning}} + // expected-note {{place parentheses around the '+' expression to silence this warning}} \ + // expected-note {{place parentheses around the '?:' expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:33-[[@LINE-4]]:33}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:41-[[@LINE-6]]:41}:")" (void)((x + someConditionFunc()) ? 1 : 2); // no warning (void)(x - b ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '-'}} \ - // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \ - // expected-note {{place parentheses around the '-' expression to silence this warning}} + // expected-note {{place parentheses around the '-' expression to silence this warning}} \ + // expected-note {{place parentheses around the '?:' expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:15-[[@LINE-4]]:15}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:23-[[@LINE-6]]:23}:")" (void)(x * (x == y) ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '*'}} \ - // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \ - // expected-note {{place parentheses around the '*' expression to silence this warning}} + // expected-note {{place parentheses around the '*' expression to silence this warning}} \ + // expected-note {{place parentheses around the '?:' expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:22}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:30-[[@LINE-6]]:30}:")" (void)(x / !x ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '/'}} \ - // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \ - // expected-note {{place parentheses around the '/' expression to silence this warning}} + // expected-note {{place parentheses around the '/' expression to silence this warning}} \ + // expected-note {{place parentheses around the '?:' expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:24-[[@LINE-6]]:24}:")" (void)(x % 2 ? 1 : 2); // no warning } -// RUN: %clang_cc1 -fsyntax-only -Wparentheses -Werror -fdiagnostics-show-option %s 2>&1 | FileCheck %s -// CHECK: error: using the result of an assignment as a condition without parentheses [-Werror,-Wparentheses] +// RUN: %clang_cc1 -fsyntax-only -Wparentheses -Werror -fdiagnostics-show-option %s 2>&1 | FileCheck %s -check-prefix=CHECK-FLAG +// CHECK-FLAG: error: using the result of an assignment as a condition without parentheses [-Werror,-Wparentheses] diff --git a/test/Sema/parentheses.cpp b/test/Sema/parentheses.cpp index da37dd3..ac2694f 100644 --- a/test/Sema/parentheses.cpp +++ b/test/Sema/parentheses.cpp @@ -1,20 +1,32 @@ // RUN: %clang_cc1 -Wparentheses -fsyntax-only -verify %s -// RUN: %clang_cc1 -Wparentheses -fixit %s -o - | %clang_cc1 -Wparentheses -Werror - +// RUN: %clang_cc1 -Wparentheses -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s bool someConditionFunc(); void conditional_op(int x, int y, bool b) { (void)(x + someConditionFunc() ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '+'}} \ - // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \ - // expected-note {{place parentheses around the '+' expression to silence this warning}} + // expected-note {{place parentheses around the '+' expression to silence this warning}} \ + // expected-note {{place parentheses around the '?:' expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:33-[[@LINE-4]]:33}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:41-[[@LINE-6]]:41}:")" (void)(x - b ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '-'}} \ - // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \ - // expected-note {{place parentheses around the '-' expression to silence this warning}} + // expected-note {{place parentheses around the '-' expression to silence this warning}} \ + // expected-note {{place parentheses around the '?:' expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:15-[[@LINE-4]]:15}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:23-[[@LINE-6]]:23}:")" (void)(x * (x == y) ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '*'}} \ - // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \ - // expected-note {{place parentheses around the '*' expression to silence this warning}} + // expected-note {{place parentheses around the '*' expression to silence this warning}} \ + // expected-note {{place parentheses around the '?:' expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:22}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:30-[[@LINE-6]]:30}:")" } class Stream { @@ -28,8 +40,28 @@ public: void f(Stream& s, bool b) { (void)(s << b ? "foo" : "bar"); // expected-warning {{operator '?:' has lower precedence than '<<'}} \ - // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \ - // expected-note {{place parentheses around the '<<' expression to silence this warning}} + // expected-note {{place parentheses around the '<<' expression to silence this warning}} \ + // expected-note {{place parentheses around the '?:' expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:32-[[@LINE-6]]:32}:")" + + (void)(s << 5 == 1); // expected-warning {{overloaded operator << has lower precedence than comparison operator}} \ + // expected-note {{place parentheses around the '<<' expression to silence this warning}} \ + // expected-note {{place parentheses around comparison expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:21-[[@LINE-6]]:21}:")" + + (void)(s >> 5 == 1); // expected-warning {{overloaded operator >> has lower precedence than comparison operator}} \ + // expected-note {{place parentheses around the '>>' expression to silence this warning}} \ + // expected-note {{place parentheses around comparison expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:21-[[@LINE-6]]:21}:")" } struct S { @@ -39,8 +71,12 @@ struct S { void test(S *s, bool (S::*m_ptr)()) { (void)(*s + true ? "foo" : "bar"); // expected-warning {{operator '?:' has lower precedence than '+'}} \ - // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \ - // expected-note {{place parentheses around the '+' expression to silence this warning}} + // expected-note {{place parentheses around the '+' expression to silence this warning}} \ + // expected-note {{place parentheses around the '?:' expression to evaluate it first}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:19-[[@LINE-4]]:19}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:35-[[@LINE-6]]:35}:")" (void)((*s + true) ? "foo" : "bar"); // No warning. @@ -51,11 +87,19 @@ void test(S *s, bool (S::*m_ptr)()) { void test(int a, int b, int c) { (void)(a >> b + c); // expected-warning {{operator '>>' has lower precedence than '+'; '+' will be evaluated first}} \ expected-note {{place parentheses around the '+' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:20}:")" + (void)(a - b << c); // expected-warning {{operator '<<' has lower precedence than '-'; '-' will be evaluated first}} \ expected-note {{place parentheses around the '-' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:15-[[@LINE-3]]:15}:")" + Stream() << b + c; Stream() >> b + c; // expected-warning {{operator '>>' has lower precedence than '+'; '+' will be evaluated first}} \ expected-note {{place parentheses around the '+' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:20}:")" } namespace PR15628 { diff --git a/test/Sema/pragma-arc-cf-code-audited.c b/test/Sema/pragma-arc-cf-code-audited.c index b646e89..c1aa804 100644 --- a/test/Sema/pragma-arc-cf-code-audited.c +++ b/test/Sema/pragma-arc-cf-code-audited.c @@ -13,6 +13,6 @@ #include "Inputs/pragma-arc-cf-code-audited.h" // expected-error {{cannot #include files inside '#pragma clang arc_cf_code_audited'}} // This is actually on the #pragma line in the header. -// expected-error {{'#pragma clang arc_cf_code_audited' was not ended within this file}} +// expected-error@Inputs/pragma-arc-cf-code-audited.h:16 {{'#pragma clang arc_cf_code_audited' was not ended within this file}} #pragma clang arc_cf_code_audited begin // expected-error {{'#pragma clang arc_cf_code_audited' was not ended within this file}} diff --git a/test/Sema/return.c b/test/Sema/return.c index e231e81..7e7c8b7 100644 --- a/test/Sema/return.c +++ b/test/Sema/return.c @@ -197,8 +197,14 @@ int test29() { exit(1); } -#include <setjmp.h> +// Include these declarations here explicitly so we don't depend on system headers. +typedef struct __jmp_buf_tag{} jmp_buf[1]; + +extern void longjmp (struct __jmp_buf_tag __env[1], int __val) __attribute__ ((noreturn)); +extern void _longjmp (struct __jmp_buf_tag __env[1], int __val) __attribute__ ((noreturn)); + jmp_buf test30_j; + int test30() { if (j) longjmp(test30_j, 1); diff --git a/test/Sema/thread-specifier.c b/test/Sema/thread-specifier.c index 8c40fcd..9d516e8 100644 --- a/test/Sema/thread-specifier.c +++ b/test/Sema/thread-specifier.c @@ -1,30 +1,110 @@ -// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s +// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s -DGNU +// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DGNU +// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s -DC11 -D__thread=_Thread_local +// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DC11 -D__thread=_Thread_local +// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DCXX11 -D__thread=thread_local -std=c++11 +// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DC11 -D__thread=_Thread_local -std=c++11 + +#ifdef __cplusplus +// In C++, we define __private_extern__ to extern. +#undef __private_extern__ +#endif __thread int t1; -__thread extern int t2; // expected-warning {{'__thread' before 'extern'}} -__thread static int t3; // expected-warning {{'__thread' before 'static'}} +__thread extern int t2; +__thread static int t3; +#ifdef GNU +// expected-warning@-3 {{'__thread' before 'extern'}} +// expected-warning@-3 {{'__thread' before 'static'}} +#endif + __thread __private_extern__ int t4; -struct t5 { __thread int x; }; // expected-error {{type name does not allow storage class to be specified}} -__thread int t6(); // expected-error {{'__thread' is only allowed on variable declarations}} +struct t5 { __thread int x; }; +#ifdef __cplusplus +// expected-error-re@-2 {{'(__thread|_Thread_local|thread_local)' is only allowed on variable declarations}} +#else +// FIXME: The 'is only allowed on variable declarations' diagnostic is better here. +// expected-error@-5 {{type name does not allow storage class to be specified}} +#endif -int f(__thread int t7) { // expected-error {{'__thread' is only allowed on variable declarations}} - __thread int t8; // expected-error {{'__thread' variables must have global storage}} +__thread int t6(); +#if defined(GNU) +// expected-error@-2 {{'__thread' is only allowed on variable declarations}} +#elif defined(C11) +// expected-error@-4 {{'_Thread_local' is only allowed on variable declarations}} +#else +// expected-error@-6 {{'thread_local' is only allowed on variable declarations}} +#endif + +int f(__thread int t7) { // expected-error {{' is only allowed on variable declarations}} + __thread int t8; +#if defined(GNU) + // expected-error@-2 {{'__thread' variables must have global storage}} +#elif defined(C11) + // expected-error@-4 {{'_Thread_local' variables must have global storage}} +#endif extern __thread int t9; static __thread int t10; __thread __private_extern__ int t11; - __thread auto int t12; // expected-error {{'__thread' variables must have global storage}} - __thread register int t13; // expected-error {{'__thread' variables must have global storage}} +#if __cplusplus < 201103L + __thread auto int t12a; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local)' declaration specifier}} + auto __thread int t12b; // expected-error {{cannot combine with previous 'auto' declaration specifier}} +#elif !defined(CXX11) + __thread auto t12a = 0; // expected-error-re {{'_Thread_local' variables must have global storage}} + auto __thread t12b = 0; // expected-error-re {{'_Thread_local' variables must have global storage}} +#endif + __thread register int t13a; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local|thread_local)' declaration specifier}} + register __thread int t13b; // expected-error {{cannot combine with previous 'register' declaration specifier}} } -__thread typedef int t14; // expected-error {{'__thread' is only allowed on variable declarations}} -__thread int t15; // expected-note {{previous definition is here}} -int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}} -int t16; // expected-note {{previous definition is here}} +__thread typedef int t14; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local|thread_local)' declaration specifier}} +__thread int t15; // expected-note {{previous declaration is here}} +extern int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}} +extern int t16; // expected-note {{previous declaration is here}} __thread int t16; // expected-error {{thread-local declaration of 't16' follows non-thread-local declaration}} +#ifdef CXX11 +extern thread_local int t17; // expected-note {{previous declaration is here}} +_Thread_local int t17; // expected-error {{thread-local declaration of 't17' with static initialization follows declaration with dynamic initialization}} +extern _Thread_local int t18; // expected-note {{previous declaration is here}} +thread_local int t18; // expected-error {{thread-local declaration of 't18' with dynamic initialization follows declaration with static initialization}} +#endif + // PR13720 __thread int thread_int; -int *thread_int_ptr = &thread_int; // expected-error{{initializer element is not a compile-time constant}} +int *thread_int_ptr = &thread_int; +#ifndef __cplusplus +// expected-error@-2 {{initializer element is not a compile-time constant}} +#endif void g() { int *p = &thread_int; // This is perfectly fine, though. } +#if __cplusplus >= 201103L +constexpr int *thread_int_ptr_2 = &thread_int; // expected-error {{must be initialized by a constant expression}} +#endif + +int non_const(); +__thread int non_const_init = non_const(); +#if !defined(__cplusplus) +// expected-error@-2 {{initializer element is not a compile-time constant}} +#elif !defined(CXX11) +// expected-error@-4 {{initializer for thread-local variable must be a constant expression}} +#if __cplusplus >= 201103L +// expected-note@-6 {{use 'thread_local' to allow this}} +#endif +#endif + +#ifdef __cplusplus +struct S { + ~S(); +}; +__thread S s; +#if !defined(CXX11) +// expected-error@-2 {{type of thread-local variable has non-trivial destruction}} +#if __cplusplus >= 201103L +// expected-note@-4 {{use 'thread_local' to allow this}} +#endif +#endif +#endif + +__thread int aggregate[10] = {0}; diff --git a/test/Sema/var-redecl.c b/test/Sema/var-redecl.c index f7576b6..363458b 100644 --- a/test/Sema/var-redecl.c +++ b/test/Sema/var-redecl.c @@ -4,7 +4,7 @@ int outer1; // expected-note{{previous definition is here}} extern int outer2; // expected-note{{previous definition is here}} int outer4; int outer4; // expected-note{{previous definition is here}} -int outer5; +int outer5; // expected-note{{previous definition is here}} int outer6(float); // expected-note{{previous definition is here}} int outer7(float); @@ -13,7 +13,7 @@ void outer_test() { extern float outer2; // expected-error{{redefinition of 'outer2' with a different type}} extern float outer3; // expected-note{{previous definition is here}} double outer4; - extern int outer5; // expected-note{{previous definition is here}} + extern int outer5; extern int outer6; // expected-error{{redefinition of 'outer6' as different kind of symbol}} int outer7; extern int outer8; // expected-note{{previous definition is here}} diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp index 0132ef2..b3ab019 100644 --- a/test/Sema/warn-documentation.cpp +++ b/test/Sema/warn-documentation.cpp @@ -892,10 +892,10 @@ typedef const struct test_nocrash7 * test_nocrash8; // We used to crash on this. +// expected-warning@+1 {{unknown command tag name}} /// aaa \unknown aaa \unknown aaa int test_nocrash9; - // We used to crash on this. PR15068 // expected-warning@+2 {{empty paragraph passed to '@param' command}} diff --git a/test/Sema/warn-documentation.m b/test/Sema/warn-documentation.m index 1e3acf1..0737a8d 100644 --- a/test/Sema/warn-documentation.m +++ b/test/Sema/warn-documentation.m @@ -149,6 +149,7 @@ struct S; @class NSArray; @interface NSArray @end +// expected-warning@+3 {{unknown command tag name}} /*! @interface NSMutableArray @super NSArray diff --git a/test/Sema/warn-duplicate-enum.c b/test/Sema/warn-duplicate-enum.c index 239f6f1..f108b3a 100644 --- a/test/Sema/warn-duplicate-enum.c +++ b/test/Sema/warn-duplicate-enum.c @@ -90,3 +90,12 @@ enum { NMax = N2, NCount = NMax + 1 }; + +// PR15693 +enum enum1 { + VALUE // expected-note{{previous definition is here}} +}; + +enum enum2 { + VALUE // expected-error{{redefinition of enumerator 'VALUE'}} +}; diff --git a/test/SemaCXX/Inputs/warn-unused-variables.h b/test/SemaCXX/Inputs/warn-unused-variables.h new file mode 100644 index 0000000..5fac459 --- /dev/null +++ b/test/SemaCXX/Inputs/warn-unused-variables.h @@ -0,0 +1,11 @@ +// Verify that we don't warn about variables of internal-linkage type in +// headers, as the use may be in another TU. +namespace PR15558 { +namespace { +class A {}; +} + +class B { + static A a; +}; +} diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp index 449e24b..ab3ff69 100644 --- a/test/SemaCXX/MicrosoftExtensions.cpp +++ b/test/SemaCXX/MicrosoftExtensions.cpp @@ -208,3 +208,128 @@ void ::f(); // expected-warning{{extra qualification on member 'f'}} class C { C::C(); // expected-warning{{extra qualification on member 'C'}} }; + +struct StructWithProperty { + __declspec(property(get=GetV)) int V1; + __declspec(property(put=SetV)) int V2; + __declspec(property(get=GetV, put=SetV_NotExist)) int V3; + __declspec(property(get=GetV_NotExist, put=SetV)) int V4; + __declspec(property(get=GetV, put=SetV)) int V5; + + int GetV() { return 123; } + void SetV(int i) {} +}; +void TestProperty() { + StructWithProperty sp; + int i = sp.V2; // expected-error{{no getter defined for property 'V2'}} + sp.V1 = 12; // expected-error{{no setter defined for property 'V1'}} + int j = sp.V4; // expected-error{{no member named 'GetV_NotExist' in 'StructWithProperty'}} expected-error{{cannot find suitable getter for property 'V4'}} + sp.V3 = 14; // expected-error{{no member named 'SetV_NotExist' in 'StructWithProperty'}} expected-error{{cannot find suitable setter for property 'V3'}} + int k = sp.V5; + sp.V5 = k++; +} + +/* 4 tests for PseudoObject, begin */ +struct SP1 +{ + bool operator()() { return true; } +}; +struct SP2 +{ + __declspec(property(get=GetV)) SP1 V; + SP1 GetV() { return SP1(); } +}; +void TestSP2() { + SP2 sp2; + bool b = sp2.V(); +} + +struct SP3 { + template <class T> + void f(T t) {} +}; +template <class T> +struct SP4 +{ + __declspec(property(get=GetV)) int V; + int GetV() { return 123; } + void f() { SP3 s2; s2.f(V); } +}; +void TestSP4() { + SP4<int> s; + s.f(); +} + +template <class T> +struct SP5 +{ + __declspec(property(get=GetV)) T V; + int GetV() { return 123; } + void f() { int *p = new int[V]; } +}; + +template <class T> +struct SP6 +{ +public: + __declspec(property(get=GetV)) T V; + T GetV() { return 123; } + void f() { int t = V; } +}; +void TestSP6() { + SP6<int> c; + c.f(); +} +/* 4 tests for PseudoObject, end */ + +// Property access: explicit, implicit, with Qualifier +struct SP7 { + __declspec(property(get=GetV, put=SetV)) int V; + int GetV() { return 123; } + void SetV(int v) {} + + void ImplicitAccess() { int i = V; V = i; } + void ExplicitAccess() { int i = this->V; this->V = i; } +}; +struct SP8: public SP7 { + void AccessWithQualifier() { int i = SP7::V; SP7::V = i; } +}; + +// Property usage +template <class T> +struct SP9 { + __declspec(property(get=GetV, put=SetV)) T V; + T GetV() { return 0; } + void SetV(T v) {} + void f() { V = this->V; V < this->V; } + void g() { V++; } + void h() { V*=2; } +}; +struct SP10 { + SP10(int v) {} + bool operator<(const SP10& v) { return true; } + SP10 operator*(int v) { return *this; } + SP10 operator+(int v) { return *this; } + SP10& operator=(const SP10& v) { return *this; } +}; +void TestSP9() { + SP9<int> c; + int i = c.V; // Decl initializer + i = c.V; // Binary op operand + c.SetV(c.V); // CallExpr arg + int *p = new int[c.V + 1]; // Array size + p[c.V] = 1; // Array index + + c.V = 123; // Setter + + c.V++; // Unary op operand + c.V *= 2; // Unary op operand + + SP9<int*> c2; + c2.V[0] = 123; // Array + + SP9<SP10> c3; + c3.f(); // Overloaded binary op operand + c3.g(); // Overloaded incdec op operand + c3.h(); // Overloaded unary op operand +} diff --git a/test/SemaCXX/access.cpp b/test/SemaCXX/access.cpp index 18ad301..50f2eff 100644 --- a/test/SemaCXX/access.cpp +++ b/test/SemaCXX/access.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s class C { struct S; // expected-note {{previously declared 'private' here}} @@ -32,3 +32,77 @@ namespace test1 { class X {}; }; } + +// PR15209 +namespace PR15209 { + namespace alias_templates { + template<typename T1, typename T2> struct U { }; + template<typename T1> using W = U<T1, float>; + + class A { + typedef int I; + static constexpr I x = 0; // expected-note {{implicitly declared private here}} + static constexpr I y = 42; // expected-note {{implicitly declared private here}} + friend W<int>; + }; + + template<typename T1> + struct U<T1, float> { + int v_; + // the following will trigger for U<float, float> instantiation, via W<float> + U() : v_(A::x) { } // expected-error {{'x' is a private member of 'PR15209::alias_templates::A'}} + }; + + template<typename T1> + struct U<T1, int> { + int v_; + U() : v_(A::y) { } // expected-error {{'y' is a private member of 'PR15209::alias_templates::A'}} + }; + + template struct U<int, int>; // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<int, int>::U' requested here}} + + void f() + { + W<int>(); + // we should issue diagnostics for the following + W<float>(); // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<float, float>::U' requested here}} + } + } + + namespace templates { + class A { + typedef int I; // expected-note {{implicitly declared private here}} + static constexpr I x = 0; // expected-note {{implicitly declared private here}} + + template<int> friend struct B; + template<int> struct C; + template<template<int> class T> friend struct TT; + template<typename T> friend void funct(T); + }; + template<A::I> struct B { }; + + template<A::I> struct A::C { }; + + template<template<A::I> class T> struct TT { + T<A::x> t; + }; + + template struct TT<B>; + template<A::I> struct D { }; // expected-error {{'I' is a private member of 'PR15209::templates::A'}} + template struct TT<D>; + + // function template case + template<typename T> + void funct(T) + { + (void)A::x; + } + + template void funct<int>(int); + + void f() + { + (void)A::x; // expected-error {{'x' is a private member of 'PR15209::templates::A'}} + } + } +} diff --git a/test/SemaCXX/alignof.cpp b/test/SemaCXX/alignof.cpp new file mode 100644 index 0000000..a9de1ad --- /dev/null +++ b/test/SemaCXX/alignof.cpp @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// rdar://13784901 + +struct S0 { + int x; + static const int test0 = __alignof__(x); // expected-error {{invalid application of 'alignof' to a field of a class still being defined}} + static const int test1 = __alignof__(S0::x); // expected-error {{invalid application of 'alignof' to a field of a class still being defined}} + auto test2() -> char(&)[__alignof__(x)]; // expected-error {{invalid application of 'alignof' to a field of a class still being defined}} +}; + +struct S1; // expected-note 5 {{forward declaration}} +extern S1 s1; +const int test3 = __alignof__(s1); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} + +struct S2 { + S2(); + S1 &s; + int x; + + int test4 = __alignof__(x); // ok + int test5 = __alignof__(s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} +}; + +const int test6 = __alignof__(S2::x); +const int test7 = __alignof__(S2::s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} + +// Arguably, these should fail like the S1 cases do: the alignment of +// 's2.x' should depend on the alignment of both x-within-S2 and +// s2-within-S3 and thus require 'S3' to be complete. If we start +// doing the appropriate recursive walk to do that, we should make +// sure that these cases don't explode. +struct S3 { + S2 s2; + + static const int test8 = __alignof__(s2.x); + static const int test9 = __alignof__(s2.s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} + auto test10() -> char(&)[__alignof__(s2.x)]; + static const int test11 = __alignof__(S3::s2.x); + static const int test12 = __alignof__(S3::s2.s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} + auto test13() -> char(&)[__alignof__(s2.x)]; +}; + +// Same reasoning as S3. +struct S4 { + union { + int x; + }; + static const int test0 = __alignof__(x); + static const int test1 = __alignof__(S0::x); + auto test2() -> char(&)[__alignof__(x)]; +}; diff --git a/test/SemaCXX/ast-print.cpp b/test/SemaCXX/ast-print.cpp index 5de8c4b..921f7d8 100644 --- a/test/SemaCXX/ast-print.cpp +++ b/test/SemaCXX/ast-print.cpp @@ -137,3 +137,14 @@ void test12() { ConstrWithCleanupsClass cwcExplicitArg(VirualDestrClass(56)); } +// CHECK: void test13() { +// CHECK: _Atomic(int) i; +// CHECK: __c11_atomic_init(&i, 0); +// CHECK: __c11_atomic_load(&i, 0); +// CHECK: } +void test13() { + _Atomic(int) i; + __c11_atomic_init(&i, 0); + __c11_atomic_load(&i, 0); +} + diff --git a/test/SemaCXX/attr-noreturn.cpp b/test/SemaCXX/attr-noreturn.cpp index f3d548b..41214c4 100644 --- a/test/SemaCXX/attr-noreturn.cpp +++ b/test/SemaCXX/attr-noreturn.cpp @@ -80,3 +80,86 @@ namespace PR12948 { template<typename> void wibble() __attribute__((__noreturn__)); template<typename> voidfn wibble; } + +// PR15291 +// Overload resolution per over.over should allow implicit noreturn adjustment. +namespace PR15291 { + __attribute__((noreturn)) void foo(int) {} + __attribute__((noreturn)) void foo(double) {} + + template <typename T> + __attribute__((noreturn)) void bar(T) {} + + void baz(int) {} + void baz(double) {} + + template <typename T> + void qux(T) {} + + // expected-note@+5 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} + // expected-note@+4 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} + // expected-note@+3 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} + // expected-note@+2 {{candidate function [with T = void (*)(int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} + // expected-note@+1 {{candidate function [with T = void (int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} + template <typename T> void accept_T(T) {} + + // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} + void accept_fptr(void (*f)(int)) { + f(42); + } + + // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} + // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} + void accept_noreturn_fptr(void __attribute__((noreturn)) (*f)(int)) { + f(42); + } + + typedef void (*fptr_t)(int); + typedef void __attribute__((noreturn)) (*fptr_noreturn_t)(int); + + // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'fptr_t' (aka 'void (*)(int)') for 1st argument}} + void accept_fptr_t(fptr_t f) { + f(42); + } + + // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}} + // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}} + void accept_fptr_noreturn_t(fptr_noreturn_t f) { + f(42); + } + + // Stripping noreturn should work if everything else is correct. + void strip_noreturn() { + accept_fptr(foo); + accept_fptr(bar<int>); + accept_fptr(bar<double>); // expected-error {{no matching function for call to 'accept_fptr'}} + + accept_fptr_t(foo); + accept_fptr_t(bar<int>); + accept_fptr_t(bar<double>); // expected-error {{no matching function for call to 'accept_fptr_t'}} + + accept_T<void __attribute__((noreturn)) (*)(int)>(foo); + accept_T<void __attribute__((noreturn)) (*)(int)>(bar<int>); + accept_T<void __attribute__((noreturn)) (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}} + + accept_T<void (*)(int)>(foo); + accept_T<void (*)(int)>(bar<int>); + accept_T<void (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}} + + accept_T<void (int)>(foo); + accept_T<void (int)>(bar<int>); + accept_T<void (int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}} + } + + // Introducing noreturn should not work. + void introduce_noreturn() { + accept_noreturn_fptr(baz); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}} + accept_noreturn_fptr(qux<int>); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}} + + accept_fptr_noreturn_t(baz); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}} + accept_fptr_noreturn_t(qux<int>); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}} + + accept_T<void __attribute__((noreturn)) (*)(int)>(baz); // expected-error {{no matching function for call to 'accept_T'}} + accept_T<void __attribute__((noreturn)) (*)(int)>(qux<int>); // expected-error {{no matching function for call to 'accept_T'}} + } +} diff --git a/test/SemaCXX/captured-statements.cpp b/test/SemaCXX/captured-statements.cpp new file mode 100644 index 0000000..dbb18a7 --- /dev/null +++ b/test/SemaCXX/captured-statements.cpp @@ -0,0 +1,166 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -fblocks + +void test_nest_lambda() { + int x; + int y; + [&,y]() { + int z; + #pragma clang __debug captured + { + x = y; // OK + y = z; // expected-error{{cannot assign to a variable captured by copy in a non-mutable lambda}} + z = y; // OK + } + }(); + + int a; + #pragma clang __debug captured + { + int b; + int c; + [&,c]() { + a = b; // OK + b = c; // OK + c = a; // expected-error{{cannot assign to a variable captured by copy in a non-mutable lambda}} + }(); + } +} + +class test_obj_capture { + int a; + void b(); + static void test() { + test_obj_capture c; + #pragma clang __debug captured + { (void)c.a; } // OK + #pragma clang __debug captured + { c.b(); } // OK + } +}; + +class test_this_capture { + int a; + void b(); + void test() { + #pragma clang __debug captured + { (void)this; } // OK + #pragma clang __debug captured + { (void)a; } // OK + #pragma clang __debug captured + { b(); } // OK + } +}; + +template <typename T> +void template_capture_var() { + T x; // expected-error{{declaration of reference variable 'x' requires an initializer}} + #pragma clang _debug captured + { + (void)x; + } +} + +template <typename T> +class Val { + T v; +public: + void set(const T &v0) { + #pragma clang __debug captured + { + v = v0; + } + } +}; + +void test_capture_var() { + template_capture_var<int>(); // OK + template_capture_var<int&>(); // expected-note{{in instantiation of function template specialization 'template_capture_var<int &>' requested here}} + + Val<float> Obj; + Obj.set(0.0f); // OK +} + +template <typename S, typename T> +S template_capture_var(S x, T y) { + #pragma clang _debug captured + { + x++; + y++; // expected-error{{read-only variable is not assignable}} + } + + return x; +} + +// Check if can recover from a template error. +void test_capture_var_error() { + template_capture_var<int, int>(0, 1); // OK + template_capture_var<int, const int>(0, 1); // expected-note{{in instantiation of function template specialization 'template_capture_var<int, const int>' requested here}} + template_capture_var<int, int>(0, 1); // OK +} + +template <typename T> +void template_capture_in_lambda() { + T x, y; + [=, &y]() { + #pragma clang __debug captured + { + y += x; + } + }(); +} + +void test_lambda() { + template_capture_in_lambda<int>(); // OK +} + +struct Foo { + void foo() { } + static void bar() { } +}; + +template <typename T> +void template_capture_func(T &t) { + #pragma clang __debug captured + { + t.foo(); + } + + #pragma clang __debug captured + { + T::bar(); + } +} + +void test_template_capture_func() { + Foo Obj; + template_capture_func(Obj); +} + +template <typename T> +T captured_sum(const T &a, const T &b) { + T result; + + #pragma clang __debug captured + { + result = a + b; + } + + return result; +} + +template <typename T, typename... Args> +T captured_sum(const T &a, const Args&... args) { + T result; + + #pragma clang __debug captured + { + result = a + captured_sum(args...); + } + + return result; +} + +void test_capture_variadic() { + (void)captured_sum(1, 2, 3); // OK + (void)captured_sum(1, 2, 3, 4, 5); // OK +} diff --git a/test/SemaCXX/compound-literal.cpp b/test/SemaCXX/compound-literal.cpp index fe0e45d..595747e 100644 --- a/test/SemaCXX/compound-literal.cpp +++ b/test/SemaCXX/compound-literal.cpp @@ -1,4 +1,8 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++03 -verify -ast-dump %s > %t-03 +// RUN: FileCheck --input-file=%t-03 %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -ast-dump %s > %t-11 +// RUN: FileCheck --input-file=%t-11 %s +// RUN: FileCheck --input-file=%t-11 %s --check-prefix=CHECK-CXX11 // http://llvm.org/PR7905 namespace PR7905 { @@ -12,3 +16,63 @@ void foo2() { (void)(M<short> []) {{3}}; } } + +// Check compound literals mixed with C++11 list-initialization. +namespace brace_initializers { + struct POD { + int x, y; + }; + struct HasCtor { + HasCtor(int x, int y); + }; + struct HasDtor { + int x, y; + ~HasDtor(); + }; + struct HasCtorDtor { + HasCtorDtor(int x, int y); + ~HasCtorDtor(); + }; + + void test() { + (void)(POD){1, 2}; + // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::POD' + // CHECK: CompoundLiteralExpr {{.*}} 'struct brace_initializers::POD' + // CHECK-NEXT: InitListExpr {{.*}} 'struct brace_initializers::POD' + // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} + // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}} + + (void)(HasDtor){1, 2}; + // CHECK: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::HasDtor' + // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'struct brace_initializers::HasDtor' + // CHECK-NEXT: InitListExpr {{.*}} 'struct brace_initializers::HasDtor' + // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} + // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}} + +#if __cplusplus >= 201103L + (void)(HasCtor){1, 2}; + // CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::HasCtor' + // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'struct brace_initializers::HasCtor' + // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'struct brace_initializers::HasCtor' + // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}} + // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}} + + (void)(HasCtorDtor){1, 2}; + // CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::HasCtorDtor' + // CHECK-CXX11-NEXT: CompoundLiteralExpr {{.*}} 'struct brace_initializers::HasCtorDtor' + // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'struct brace_initializers::HasCtorDtor' + // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}} + // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}} +#endif + } + + struct PrivateDtor { + int x, y; + private: + ~PrivateDtor(); // expected-note {{declared private here}} + }; + + void testPrivateDtor() { + (void)(PrivateDtor){1, 2}; // expected-error {{temporary of type 'brace_initializers::PrivateDtor' has private destructor}} + } +} diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp index d805881..73f3dce 100644 --- a/test/SemaCXX/condition.cpp +++ b/test/SemaCXX/condition.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s void test() { int x; @@ -6,7 +6,7 @@ void test() { if (int x=0) ++x; typedef int arr[10]; - while (arr x=0) ; // expected-error {{an array type is not allowed here}} expected-error {{array initializer must be an initializer list}} + while (arr x={0}) ; // expected-error {{an array type is not allowed here}} while (int f()=0) ; // expected-error {{a function type is not allowed here}} struct S {} s; @@ -19,9 +19,7 @@ void test() { while (struct NewS *x=0) ; while (struct S {} *x=0) ; // expected-error {{types may not be defined in conditions}} while (struct {} *x=0) ; // expected-error {{types may not be defined in conditions}} - switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} \ - // expected-warning{{enumeration value 'E' not handled in switch}} expected-warning {{switch statement has empty body}} \ - // expected-note{{put the semicolon on a separate line}} + switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} if (int x=0) { // expected-note 2 {{previous definition is here}} int x; // expected-error {{redefinition of 'x'}} diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index 30aa7d7..09a9cb5 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -21,7 +21,7 @@ template<typename T, size_t N> constexpr T *begin(T (&xs)[N]) { return xs; } template<typename T, size_t N> constexpr T *end(T (&xs)[N]) { return xs + N; } struct MemberZero { - constexpr int zero() { return 0; } + constexpr int zero() const { return 0; } }; namespace DerivedToVBaseCast { @@ -304,16 +304,16 @@ struct Str { expected-note {{reinterpret_cast is not allowed in a constant expression}} int c : (S*)(long)(sptr) == (S*)(long)(sptr); // \ expected-warning {{not an integral constant expression}} \ - expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}} + expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} int d : (S*)(42) == (S*)(42); // \ expected-warning {{not an integral constant expression}} \ - expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}} + expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} int e : (Str*)(sptr) == (Str*)(sptr); // \ expected-warning {{not an integral constant expression}} \ - expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}} + expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} int f : &(U&)(*sptr) == &(U&)(*sptr); // \ expected-warning {{not an integral constant expression}} \ - expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}} + expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} int g : (S*)(void*)(sptr) == sptr; // \ expected-warning {{not an integral constant expression}} \ expected-note {{cast from 'void *' is not allowed in a constant expression}} @@ -362,7 +362,7 @@ constexpr char c0 = "nought index"[0]; constexpr char c1 = "nice index"[10]; constexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is past the end}} expected-note {{read of dereferenced one-past-the-end pointer}} constexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is before the beginning}} expected-note {{cannot refer to element -1 of array of 15 elements}} -constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast which performs the conversions of a reinterpret_cast}} +constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast that performs the conversions of a reinterpret_cast}} constexpr const char *p = "test" + 2; static_assert(*p == 's', ""); @@ -414,6 +414,19 @@ struct V { }; static_assert(V().c[1] == "i"[0], ""); +namespace Parens { + constexpr unsigned char a[] = ("foo"), b[] = {"foo"}, c[] = {("foo")}, + d[4] = ("foo"), e[5] = {"foo"}, f[6] = {("foo")}; + static_assert(a[0] == 'f', ""); + static_assert(b[1] == 'o', ""); + static_assert(c[2] == 'o', ""); + static_assert(d[0] == 'f', ""); + static_assert(e[1] == 'o', ""); + static_assert(f[2] == 'o', ""); + static_assert(f[5] == 0, ""); + static_assert(f[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}} +} + } namespace Array { @@ -486,7 +499,7 @@ static_assert(CountZero(arr, arr + 40) == 36, ""); struct ArrayElem { constexpr ArrayElem() : n(0) {} int n; - constexpr int f() { return n; } + constexpr int f() const { return n; } }; struct ArrayRVal { constexpr ArrayRVal() {} @@ -731,14 +744,14 @@ namespace ConversionOperators { struct T { constexpr T(int n) : k(5*n - 3) {} - constexpr operator int() { return k; } + constexpr operator int() const { return k; } int k; }; struct S { constexpr S(int n) : k(2*n + 1) {} - constexpr operator int() { return k; } - constexpr operator T() { return T(k); } + constexpr operator int() const { return k; } + constexpr operator T() const { return T(k); } int k; }; @@ -750,7 +763,7 @@ static_assert(check(S(5), 11), ""); namespace PR14171 { struct X { - constexpr (operator int)() { return 0; } + constexpr (operator int)() const { return 0; } }; static_assert(X() == 0, ""); @@ -764,13 +777,13 @@ namespace Temporaries { struct S { constexpr S() {} - constexpr int f(); + constexpr int f() const; }; struct T : S { constexpr T(int n) : S(), n(n) {} int n; }; -constexpr int S::f() { +constexpr int S::f() const { // 'this' must be the postfix-expression in a class member access expression, // so we can't just use // return static_cast<T*>(this)->n; @@ -825,7 +838,7 @@ namespace MemberPointer { struct A { constexpr A(int n) : n(n) {} int n; - constexpr int f() { return n + 3; } + constexpr int f() const { return n + 3; } }; constexpr A a(7); static_assert(A(5).*&A::n == 5, ""); @@ -836,7 +849,7 @@ namespace MemberPointer { struct B : A { constexpr B(int n, int m) : A(n), m(m) {} int m; - constexpr int g() { return n + m + 1; } + constexpr int g() const { return n + m + 1; } }; constexpr B b(9, 13); static_assert(B(4, 11).*&A::n == 4, ""); @@ -857,7 +870,7 @@ namespace MemberPointer { m(m), n(n), pf(pf), pn(pn) {} constexpr S() : m(), n(), pf(&S::f), pn(&S::n) {} - constexpr int f() { return this->*pn; } + constexpr int f() const { return this->*pn; } virtual int g() const; int m, n; @@ -938,7 +951,7 @@ namespace ArrayBaseDerived { }; struct Derived : Base { constexpr Derived() {} - constexpr const int *f() { return &n; } + constexpr const int *f() const { return &n; } }; constexpr Derived a[10]; @@ -1038,7 +1051,7 @@ static_assert(makeComplexWrap(1,0) != complex(0, 1), ""); } namespace PR11595 { - struct A { constexpr bool operator==(int x) { return true; } }; + struct A { constexpr bool operator==(int x) const { return true; } }; struct B { B(); A& x; }; static_assert(B().x == 3, ""); // expected-error {{constant expression}} expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}} @@ -1312,6 +1325,13 @@ namespace InvalidClasses { } } +namespace NamespaceAlias { + constexpr int f() { + namespace NS = NamespaceAlias; // expected-warning {{use of this statement in a constexpr function is a C++1y extension}} + return &NS::f != nullptr; + } +} + // Constructors can be implicitly constexpr, even for a non-literal type. namespace ImplicitConstexpr { struct Q { Q() = default; Q(const Q&) = default; Q(Q&&) = default; ~Q(); }; // expected-note 3{{here}} @@ -1455,3 +1475,31 @@ namespace PR14203 { // constructor here. int n = sizeof(short{duration(duration())}); } + +namespace ArrayEltInit { + struct A { + constexpr A() : p(&p) {} + void *p; + }; + constexpr A a[10]; + static_assert(a[0].p == &a[0].p, ""); + static_assert(a[9].p == &a[9].p, ""); + static_assert(a[0].p != &a[9].p, ""); + static_assert(a[9].p != &a[0].p, ""); + + constexpr A b[10] = {}; + static_assert(b[0].p == &b[0].p, ""); + static_assert(b[9].p == &b[9].p, ""); + static_assert(b[0].p != &b[9].p, ""); + static_assert(b[9].p != &b[0].p, ""); +} + +namespace PR15884 { + struct S {}; + constexpr S f() { return {}; } + constexpr S *p = &f(); + // expected-error@-1 {{taking the address of a temporary}} + // expected-error@-2 {{constexpr variable 'p' must be initialized by a constant expression}} + // expected-note@-3 {{pointer to temporary is not a constant expression}} + // expected-note@-4 {{temporary created here}} +} diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp new file mode 100644 index 0000000..60ec820 --- /dev/null +++ b/test/SemaCXX/constant-expression-cxx1y.cpp @@ -0,0 +1,459 @@ +// RUN: %clang_cc1 -std=c++1y -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu + +struct S { + // dummy ctor to make this a literal type + constexpr S(int); + + S(); + + int arr[10]; + + constexpr int &get(int n) { return arr[n]; } + constexpr const int &get(int n) const { return arr[n]; } +}; + +S s = S(); +const S &sr = s; +static_assert(&s.get(4) - &sr.get(2) == 2, ""); + +// Compound-statements can be used in constexpr functions. +constexpr int e() {{{{}} return 5; }} +static_assert(e() == 5, ""); + +// Types can be defined in constexpr functions. +constexpr int f() { + enum E { e1, e2, e3 }; + + struct S { + constexpr S(E e) : e(e) {} + constexpr int get() { return e; } + E e; + }; + + return S(e2).get(); +} +static_assert(f() == 1, ""); + +// Variables can be declared in constexpr functions. +constexpr int g(int k) { + const int n = 9; + int k2 = k * k; + int k3 = k2 * k; + return 3 * k3 + 5 * k2 + n * k - 20; +} +static_assert(g(2) == 42, ""); +constexpr int h(int n) { + static const int m = n; // expected-error {{static variable not permitted in a constexpr function}} + return m; +} +constexpr int i(int n) { + thread_local const int m = n; // expected-error {{thread_local variable not permitted in a constexpr function}} + return m; +} + +// if-statements can be used in constexpr functions. +constexpr int j(int k) { + if (k == 5) + return 1; + if (k == 1) + return 5; + else { + if (int n = 2 * k - 4) { + return n + 1; + return 2; + } + } +} // expected-note 2{{control reached end of constexpr function}} +static_assert(j(0) == -3, ""); +static_assert(j(1) == 5, ""); +static_assert(j(2), ""); // expected-error {{constant expression}} expected-note {{in call to 'j(2)'}} +static_assert(j(3) == 3, ""); +static_assert(j(4) == 5, ""); +static_assert(j(5) == 1, ""); + +// There can be 0 return-statements. +constexpr void k() { +} + +// If the return type is not 'void', no return statements => never a constant +// expression, so still diagnose that case. +[[noreturn]] constexpr int fn() { // expected-error {{no return statement in constexpr function}} + fn(); +} + +// We evaluate the body of a constexpr constructor, to check for side-effects. +struct U { + constexpr U(int n) { + if (j(n)) {} // expected-note {{in call to 'j(2)'}} + } +}; +constexpr U u1{1}; +constexpr U u2{2}; // expected-error {{constant expression}} expected-note {{in call to 'U(2)'}} + +// We allow expression-statements. +constexpr int l(bool b) { + if (b) + throw "invalid value for b!"; // expected-note {{subexpression not valid}} + return 5; +} +static_assert(l(false) == 5, ""); +static_assert(l(true), ""); // expected-error {{constant expression}} expected-note {{in call to 'l(true)'}} + +// Potential constant expression checking is still applied where possible. +constexpr int htonl(int x) { // expected-error {{never produces a constant expression}} + typedef unsigned char uchar; + uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) }; + return *reinterpret_cast<int*>(arr); // expected-note {{reinterpret_cast is not allowed in a constant expression}} +} + +constexpr int maybe_htonl(bool isBigEndian, int x) { + if (isBigEndian) + return x; + + typedef unsigned char uchar; + uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) }; + return *reinterpret_cast<int*>(arr); // expected-note {{reinterpret_cast is not allowed in a constant expression}} +} + +constexpr int swapped = maybe_htonl(false, 123); // expected-error {{constant expression}} expected-note {{in call}} + +namespace NS { + constexpr int n = 0; +} +constexpr int namespace_alias() { + namespace N = NS; + return N::n; +} + +namespace assign { + constexpr int a = 0; + const int b = 0; + int c = 0; // expected-note 2{{here}} + + constexpr void set(const int &a, int b) { + const_cast<int&>(a) = b; // expected-note 2{{constant expression cannot modify an object that is visible outside that expression}} + } + constexpr int wrap(int a, int b) { + set(a, b); + return a; + } + + static_assert((set(a, 1), a) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(a, 1)'}} + static_assert((set(b, 1), b) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(b, 1)'}} + static_assert((set(c, 1), c) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}} + + static_assert(wrap(a, 1) == 1, ""); + static_assert(wrap(b, 1) == 1, ""); + static_assert(wrap(c, 1) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}} +} + +namespace string_assign { + template<typename T> + constexpr void swap(T &a, T &b) { + T tmp = a; + a = b; + b = tmp; + } + template<typename Iterator> + constexpr void reverse(Iterator begin, Iterator end) { + while (begin != end && begin != --end) + swap(*begin++, *end); + } + template<typename Iterator1, typename Iterator2> + constexpr bool equal(Iterator1 a, Iterator1 ae, Iterator2 b, Iterator2 be) { + while (a != ae && b != be) + if (*a++ != *b++) + return false; + return a == ae && b == be; + } + constexpr bool test1(int n) { + char stuff[100] = "foobarfoo"; + const char stuff2[100] = "oofraboof"; + reverse(stuff, stuff + n); // expected-note {{cannot refer to element 101 of array of 100 elements}} + return equal(stuff, stuff + n, stuff2, stuff2 + n); + } + static_assert(!test1(1), ""); + static_assert(test1(3), ""); + static_assert(!test1(6), ""); + static_assert(test1(9), ""); + static_assert(!test1(100), ""); + static_assert(!test1(101), ""); // expected-error {{constant expression}} expected-note {{in call to 'test1(101)'}} + + // FIXME: We should be able to reject this before it's called + constexpr void f() { + char foo[10] = { "z" }; // expected-note {{here}} + foo[10] = 'x'; // expected-warning {{past the end}} expected-note {{assignment to dereferenced one-past-the-end pointer}} + } + constexpr int k = (f(), 0); // expected-error {{constant expression}} expected-note {{in call}} +} + +namespace array_resize { + constexpr int do_stuff(int k1, int k2) { + int arr[1234] = { 1, 2, 3, 4 }; + arr[k1] = 5; // expected-note {{past-the-end}} expected-note {{cannot refer to element 1235}} expected-note {{cannot refer to element -1}} + return arr[k2]; + } + static_assert(do_stuff(1, 2) == 3, ""); + static_assert(do_stuff(0, 0) == 5, ""); + static_assert(do_stuff(1233, 1233) == 5, ""); + static_assert(do_stuff(1233, 0) == 1, ""); + static_assert(do_stuff(1234, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} + static_assert(do_stuff(1235, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} + static_assert(do_stuff(-1, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} +} + +namespace potential_const_expr { + constexpr void set(int &n) { n = 1; } + constexpr int div_zero_1() { int z = 0; set(z); return 100 / z; } // no error + constexpr int div_zero_2() { // expected-error {{never produces a constant expression}} + int z = 0; + return 100 / (set(z), 0); // expected-note {{division by zero}} + } + int n; // expected-note {{declared here}} + constexpr int ref() { // expected-error {{never produces a constant expression}} + int &r = n; + return r; // expected-note {{read of non-const variable 'n'}} + } +} + +namespace subobject { + union A { constexpr A() : y(5) {} int x, y; }; + struct B { A a; }; + struct C : B {}; + union D { constexpr D() : c() {} constexpr D(int n) : n(n) {} C c; int n; }; + constexpr void f(D &d) { + d.c.a.y = 3; + // expected-note@-1 {{cannot modify an object that is visible outside}} + // expected-note@-2 {{assignment to member 'c' of union with active member 'n'}} + } + constexpr bool check(D &d) { return d.c.a.y == 3; } + + constexpr bool g() { D d; f(d); return d.c.a.y == 3; } + static_assert(g(), ""); + + D d; + constexpr bool h() { f(d); return check(d); } // expected-note {{in call}} + static_assert(h(), ""); // expected-error {{constant expression}} expected-note {{in call}} + + constexpr bool i() { D d(0); f(d); return check(d); } // expected-note {{in call}} + static_assert(i(), ""); // expected-error {{constant expression}} expected-note {{in call}} + + constexpr bool j() { D d; d.c.a.x = 3; return check(d); } // expected-note {{assignment to member 'x' of union with active member 'y'}} + static_assert(j(), ""); // expected-error {{constant expression}} expected-note {{in call}} +} + +namespace lifetime { + constexpr int &&id(int &&n) { return static_cast<int&&>(n); } + constexpr int &&dead() { return id(0); } // expected-note {{temporary created here}} + constexpr int bad() { int &&n = dead(); n = 1; return n; } // expected-note {{assignment to temporary whose lifetime has ended}} + static_assert(bad(), ""); // expected-error {{constant expression}} expected-note {{in call}} +} + +namespace const_modify { + constexpr int modify(int &n) { return n = 1; } // expected-note {{modification of object of const-qualified type 'const int'}} + constexpr int test1() { int k = 0; return modify(k); } + constexpr int test2() { const int k = 0; return modify(const_cast<int&>(k)); } // expected-note {{in call}} + static_assert(test1() == 1, ""); + static_assert(test2() == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} +} + +namespace null { + constexpr int test(int *p) { + return *p = 123; // expected-note {{assignment to dereferenced null pointer}} + } + static_assert(test(0), ""); // expected-error {{constant expression}} expected-note {{in call}} +} + +namespace incdec { + template<typename T> constexpr T &ref(T &&r) { return r; } + template<typename T> constexpr T postinc(T &&r) { return (r++, r); } + template<typename T> constexpr T postdec(T &&r) { return (r--, r); } + + static_assert(++ref(0) == 1, ""); + static_assert(ref(0)++ == 0, ""); + static_assert(postinc(0) == 1, ""); + static_assert(--ref(0) == -1, ""); + static_assert(ref(0)-- == 0, ""); + static_assert(postdec(0) == -1, ""); + + constexpr int overflow_int_inc_1 = ref(0x7fffffff)++; // expected-error {{constant}} expected-note {{2147483648}} + constexpr int overflow_int_inc_1_ok = ref(0x7ffffffe)++; + constexpr int overflow_int_inc_2 = ++ref(0x7fffffff); // expected-error {{constant}} expected-note {{2147483648}} + constexpr int overflow_int_inc_2_ok = ++ref(0x7ffffffe); + + // inc/dec on short can't overflow because we promote to int first + static_assert(++ref<short>(0x7fff) == (int)0xffff8000u, ""); + static_assert(--ref<short>(0x8000) == 0x7fff, ""); + + // inc on bool sets to true + static_assert(++ref(false), ""); // expected-warning {{deprecated}} + static_assert(++ref(true), ""); // expected-warning {{deprecated}} + + int arr[10]; + static_assert(++ref(&arr[0]) == &arr[1], ""); + static_assert(++ref(&arr[9]) == &arr[10], ""); + static_assert(++ref(&arr[10]) == &arr[11], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}} + static_assert(ref(&arr[0])++ == &arr[0], ""); + static_assert(ref(&arr[10])++ == &arr[10], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}} + static_assert(postinc(&arr[0]) == &arr[1], ""); + static_assert(--ref(&arr[10]) == &arr[9], ""); + static_assert(--ref(&arr[1]) == &arr[0], ""); + static_assert(--ref(&arr[0]) != &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}} + static_assert(ref(&arr[1])-- == &arr[1], ""); + static_assert(ref(&arr[0])-- == &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}} + static_assert(postdec(&arr[1]) == &arr[0], ""); + + int x; + static_assert(++ref(&x) == &x + 1, ""); + + static_assert(++ref(0.0) == 1.0, ""); + static_assert(ref(0.0)++ == 0.0, ""); + static_assert(postinc(0.0) == 1.0, ""); + static_assert(--ref(0.0) == -1.0, ""); + static_assert(ref(0.0)-- == 0.0, ""); + static_assert(postdec(0.0) == -1.0, ""); + + static_assert(++ref(1e100) == 1e100, ""); + static_assert(--ref(1e100) == 1e100, ""); + + union U { + int a, b; + }; + constexpr int f(U u) { + return ++u.b; // expected-note {{increment of member 'b' of union with active member 'a'}} + } + constexpr int wrong_member = f({0}); // expected-error {{constant}} expected-note {{in call to 'f({.a = 0})'}} + constexpr int vol = --ref<volatile int>(0); // expected-error {{constant}} expected-note {{decrement of volatile-qualified}} + + constexpr int incr(int k) { + int x = k; + if (x++ == 100) + return x; + return incr(x); + } + static_assert(incr(0) == 101, ""); +} + +namespace loops { + constexpr int fib_loop(int a) { + int f_k = 0, f_k_plus_one = 1; + for (int k = 1; k != a; ++k) { + int f_k_plus_two = f_k + f_k_plus_one; + f_k = f_k_plus_one; + f_k_plus_one = f_k_plus_two; + } + return f_k_plus_one; + } + static_assert(fib_loop(46) == 1836311903, ""); + + constexpr bool breaks_work() { + int a = 0; + for (int n = 0; n != 100; ++n) { + ++a; + if (a == 5) continue; + if ((a % 5) == 0) break; + } + + int b = 0; + while (b != 17) { + ++b; + if (b == 6) continue; + if ((b % 6) == 0) break; + } + + int c = 0; + do { + ++c; + if (c == 7) continue; + if ((c % 7) == 0) break; + } while (c != 21); + + return a == 10 && b == 12 & c == 14; + } + static_assert(breaks_work(), ""); + + void not_constexpr(); + constexpr bool no_cont_after_break() { + for (;;) { + break; + not_constexpr(); + } + while (true) { + break; + not_constexpr(); + } + do { + break; + not_constexpr(); + } while (true); + return true; + } + static_assert(no_cont_after_break(), ""); + + constexpr bool cond() { + for (int a = 1; bool b = a != 3; ++a) { + if (!b) + return false; + } + while (bool b = true) { + b = false; + break; + } + return true; + } + static_assert(cond(), ""); + + constexpr int range_for() { + int arr[] = { 1, 2, 3, 4, 5 }; + int sum = 0; + for (int x : arr) + sum = sum + x; + return sum; + } + static_assert(range_for() == 15, ""); + + template<int...N> struct ints {}; + template<typename A, typename B> struct join_ints; + template<int...As, int...Bs> struct join_ints<ints<As...>, ints<Bs...>> { + using type = ints<As..., sizeof...(As) + Bs...>; + }; + template<unsigned N> struct make_ints { + using type = typename join_ints<typename make_ints<N/2>::type, typename make_ints<(N+1)/2>::type>::type; + }; + template<> struct make_ints<0> { using type = ints<>; }; + template<> struct make_ints<1> { using type = ints<0>; }; + + struct ignore { template<typename ...Ts> constexpr ignore(Ts &&...) {} }; + + template<typename T, unsigned N> struct array { + constexpr array() : arr{} {} + template<typename ...X> + constexpr array(X ...x) : arr{} { + init(typename make_ints<sizeof...(X)>::type{}, x...); + } + template<int ...I, typename ...X> constexpr void init(ints<I...>, X ...x) { + ignore{arr[I] = x ...}; + } + T arr[N]; + struct iterator { + T *p; + constexpr explicit iterator(T *p) : p(p) {} + constexpr bool operator!=(iterator o) { return p != o.p; } + constexpr iterator &operator++() { ++p; return *this; } + constexpr T &operator*() { return *p; } + }; + constexpr iterator begin() { return iterator(arr); } + constexpr iterator end() { return iterator(arr + N); } + }; + + constexpr int range_for_2() { + array<int, 5> arr { 1, 2, 3, 4, 5 }; + int sum = 0; + for (int k : arr) { + sum = sum + k; + if (sum > 8) break; + } + return sum; + } + static_assert(range_for_2() == 10, ""); +} diff --git a/test/SemaCXX/constexpr-printing.cpp b/test/SemaCXX/constexpr-printing.cpp index 9170fa1..e545f45 100644 --- a/test/SemaCXX/constexpr-printing.cpp +++ b/test/SemaCXX/constexpr-printing.cpp @@ -9,7 +9,7 @@ struct S { int n, m; }; -constexpr int extract(const S &s) { return s.n; } // expected-note {{read of uninitialized object is not allowed in a constant expression}} +constexpr int extract(const S &s) { return s.n; } // expected-note {{read of object outside its lifetime is not allowed in a constant expression}} constexpr S s1; // ok void f() { diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp index e459f09..d137bd8 100644 --- a/test/SemaCXX/constexpr-value-init.cpp +++ b/test/SemaCXX/constexpr-value-init.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify struct A { - constexpr A() : a(b + 1), b(a + 1) {} // expected-note {{uninitialized}} + constexpr A() : a(b + 1), b(a + 1) {} // expected-note {{outside its lifetime}} int a; int b; }; diff --git a/test/SemaCXX/cxx11-ast-print.cpp b/test/SemaCXX/cxx11-ast-print.cpp index f95eeb5..f7bfc11 100644 --- a/test/SemaCXX/cxx11-ast-print.cpp +++ b/test/SemaCXX/cxx11-ast-print.cpp @@ -41,3 +41,5 @@ const char *p10 = 3.300e+15_fritz; // CHECK: ; ; // CHECK-NOT: ; + + diff --git a/test/SemaCXX/cxx11-crashes.cpp b/test/SemaCXX/cxx11-crashes.cpp index bd51af1..a4d4829 100644 --- a/test/SemaCXX/cxx11-crashes.cpp +++ b/test/SemaCXX/cxx11-crashes.cpp @@ -70,7 +70,9 @@ namespace b6981007 { for (auto x : s) { // We used to attempt to evaluate the initializer of this variable, // and crash because it has an undeduced type. - const int &n(x); + // FIXME: We should set the loop variable to be invalid if we can't build + // the loop, to suppress this follow-on error. + const int &n(x); // expected-error {{could not bind to an lvalue of type 'auto'}} } } } diff --git a/test/SemaCXX/cxx11-inheriting-ctors.cpp b/test/SemaCXX/cxx11-inheriting-ctors.cpp new file mode 100644 index 0000000..67d5521 --- /dev/null +++ b/test/SemaCXX/cxx11-inheriting-ctors.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +// expected-no-diagnostics + +namespace PR15757 { + struct S { + }; + + template<typename X, typename Y> struct T { + template<typename A> T(X x, A &&a) {} + + template<typename A> explicit T(A &&a) + noexcept(noexcept(T(X(), static_cast<A &&>(a)))) + : T(X(), static_cast<A &&>(a)) {} + }; + + template<typename X, typename Y> struct U : T<X, Y> { + using T<X, Y>::T; + }; + + U<S, char> foo(char ch) { return U<S, char>(ch); } + + int main() { + U<S, int> a(42); + U<S, char> b('4'); + return 0; + } +} diff --git a/test/SemaCXX/cxx11-thread-local-print.cpp b/test/SemaCXX/cxx11-thread-local-print.cpp new file mode 100644 index 0000000..9d9a82b --- /dev/null +++ b/test/SemaCXX/cxx11-thread-local-print.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -std=c++11 -triple=x86_64-linux-gnu -ast-print %s | FileCheck %s + +// CHECK: __thread int gnu_tl; +// CHECK: _Thread_local int c11_tl; +// CHECK: thread_local int cxx11_tl; +__thread int gnu_tl; +_Thread_local int c11_tl; +thread_local int cxx11_tl; + diff --git a/test/SemaCXX/cxx11-thread-local.cpp b/test/SemaCXX/cxx11-thread-local.cpp new file mode 100644 index 0000000..f1dddc1 --- /dev/null +++ b/test/SemaCXX/cxx11-thread-local.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++11 -triple=x86_64-linux-gnu -verify %s + +struct S { + static thread_local int a; + static int b; // expected-note {{here}} + thread_local int c; // expected-error {{'thread_local' is only allowed on variable declarations}} + static thread_local int d; // expected-note {{here}} +}; + +thread_local int S::a; +thread_local int S::b; // expected-error {{thread-local declaration of 'b' follows non-thread-local declaration}} +thread_local int S::c; // expected-error {{non-static data member defined out-of-line}} +int S::d; // expected-error {{non-thread-local declaration of 'd' follows thread-local declaration}} + +thread_local int x[3]; +thread_local int y[3]; +thread_local int z[3]; // expected-note {{previous}} + +void f() { + thread_local int x; + static thread_local int y; + extern thread_local int z; // expected-error {{redefinition of 'z' with a different type}} +} diff --git a/test/SemaCXX/cxx11-user-defined-literals-unused.cpp b/test/SemaCXX/cxx11-user-defined-literals-unused.cpp new file mode 100644 index 0000000..cd93ffb --- /dev/null +++ b/test/SemaCXX/cxx11-user-defined-literals-unused.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s -Wunused + +namespace { +double operator"" _x(long double value) { return double(value); } +int operator"" _ii(long double value) { return int(value); } // expected-warning {{not needed and will not be emitted}} +} + +namespace rdar13589856 { + template<class T> double value() { return 3.2_x; } + template<class T> int valuei() { return 3.2_ii; } + + double get_value() { return value<double>(); } +} diff --git a/test/SemaCXX/cxx1y-array-runtime-bound.cpp b/test/SemaCXX/cxx1y-array-runtime-bound.cpp new file mode 100644 index 0000000..1643adb --- /dev/null +++ b/test/SemaCXX/cxx1y-array-runtime-bound.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -std=c++1y %s -verify -triple=x86_64-linux-gnu -pedantic-errors + +// FIXME: many diagnostics here say 'variably modified type'. +// catch this case and say 'array of runtime bound' instead. + +namespace std { struct type_info; } + +struct S { + int arr[__SIZE_MAX__ / 32]; +}; +S s[32]; // expected-error {{array is too large}} + +int n; +int a[n]; // expected-error {{not allowed at file scope}} + +struct T { + int a[n]; // expected-error {{fields must have a constant size}} + static int b[n]; // expected-error {{not allowed at file scope}} +}; + +int g(int n, int a[n]); + +template<typename T> struct X {}; +template<int N, int[N]> struct Y {}; +template<int[n]> struct Z {}; // expected-error {{of variably modified type}} + +int f(int n) { + int arb[n]; // expected-note 3{{here}} + [arb] {} (); // expected-error {{cannot be captured}} + + // FIXME: an array of runtime bound can be captured by reference. + [&arb] { // expected-error {{cannot be captured}} + // Capturing the array implicitly captures the bound, if we need it + // in a range-based for loop. + for (auto &n : arb) { } // expected-error {{cannot be captured}} + } (); + + X<int[n]> x; // expected-error {{variably modified type}} + + int arb_neg[-1]; // expected-error {{negative size}} + int arb_of_array[n][2]; + int arr[3] = { 1, 2, 3, 4 }; // expected-error {{excess elements}} + char foo[4] = "fool"; // expected-error {{initializer-string for char array is too long}} + + static int not_auto1[n]; // expected-error {{can not have 'static'}} + extern int not_auto2[n]; // expected-error {{can not have 'extern'}} + // FIXME: say 'thread_local' not 'static'. + thread_local int not_auto1[n]; // expected-error {{can not have 'static'}} + + // FIXME: these should all be invalid. + auto &&ti1 = typeid(arb); + auto &&ti2 = typeid(int[n]); + auto &&so1 = sizeof(arb); + auto &&so2 = sizeof(int[n]); + auto *p = &arb; + decltype(arb) arb2; + int (*arbp)[n] = 0; + const int (&arbr)[n] = arbr; // expected-warning {{not yet bound}} + typedef int arbty[n]; + int array_of_arb[2][n]; + + struct Dyn { Dyn() {} Dyn(int) {} ~Dyn() {} }; + + // FIXME: these should be valid. + int arb_dynamic[n] = { 1, 2, 3, 4 }; // expected-error {{may not be initialized}} + Dyn dyn[n]; // expected-error {{non-POD}} + Dyn dyn_init[n] = { 1, 2, 3, 4 }; // expected-error {{non-POD}} +} diff --git a/test/SemaCXX/cxx1y-constexpr-not-const.cpp b/test/SemaCXX/cxx1y-constexpr-not-const.cpp new file mode 100644 index 0000000..3f100b8 --- /dev/null +++ b/test/SemaCXX/cxx1y-constexpr-not-const.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify +// RUN: %clang_cc1 -std=c++1y %s -verify -DCXX1Y + +struct X { + constexpr int f(); // @5 + int f(); // @6 +}; + +#ifdef CXX1Y +// FIXME: Detect this situation and provide a better recovery. + +// expected-error@6 {{class member cannot be redeclared}} +// expected-note@5 {{previous}} +// expected-error@6 {{non-constexpr declaration of 'f' follows constexpr declaration}} +// expected-note@5 {{previous}} +#else +// expected-warning@5 {{'constexpr' non-static member function will not be implicitly 'const' in C++1y; add 'const' to avoid a change in behavior}} +#endif diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp new file mode 100644 index 0000000..f0146f8 --- /dev/null +++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp @@ -0,0 +1,338 @@ +// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s + +auto f(); // expected-note {{previous}} +int f(); // expected-error {{differ only in their return type}} + +auto &g(); +auto g() -> auto &; + +auto h() -> auto *; +auto *h(); + +struct Conv1 { + operator auto(); // expected-note {{declared here}} +} conv1; +int conv1a = conv1; // expected-error {{function 'operator auto' with deduced return type cannot be used before it is defined}} +// expected-error@-1 {{no viable conversion}} +Conv1::operator auto() { return 123; } +int conv1b = conv1; +int conv1c = conv1.operator auto(); +int conv1d = conv1.operator int(); // expected-error {{no member named 'operator int'}} + +struct Conv2 { + operator auto() { return 0; } // expected-note 2{{previous}} + operator auto() { return 0.; } // expected-error {{cannot be redeclared}} expected-error {{redefinition of 'operator auto'}} +}; + +struct Conv3 { + operator auto() { int *p = nullptr; return p; } // expected-note {{candidate}} + operator auto*() { int *p = nullptr; return p; } // expected-note {{candidate}} +} conv3; +int *conv3a = conv3; // expected-error {{ambiguous}} +int *conv3b = conv3.operator auto(); +int *conv3c = conv3.operator auto*(); + +template<typename T> +struct Conv4 { + operator auto() { return T(); } +}; +Conv4<int> conv4int; +int conv4a = conv4int; +int conv4b = conv4int.operator auto(); + +auto a(); +auto a() { return 0; } +using T = decltype(a()); +using T = int; +auto a(); // expected-note {{previous}} +using T = decltype(a()); +auto *a(); // expected-error {{differ only in their return type}} + +auto b(bool k) { + if (k) + return "hello"; + return "goodbye"; +} + +auto *ptr_1() { + return 100; // expected-error {{cannot deduce return type 'auto *' from returned value of type 'int'}} +} + +const auto &ref_1() { + return 0; // expected-warning {{returning reference to local temporary}} +} + +auto init_list() { + return { 1, 2, 3 }; // expected-error {{cannot deduce return type from initializer list}} +} + +auto fwd_decl(); // expected-note 2{{here}} + +int n = fwd_decl(); // expected-error {{function 'fwd_decl' with deduced return type cannot be used before it is defined}} +int k = sizeof(fwd_decl()); // expected-error {{used before it is defined}} + +auto fac(int n) { + if (n <= 2) + return n; + return n * fac(n-1); // ok +} + +auto fac_2(int n) { // expected-note {{declared here}} + if (n > 2) + return n * fac_2(n-1); // expected-error {{cannot be used before it is defined}} + return n; +} + +auto void_ret() {} +using Void = void; +using Void = decltype(void_ret()); + +auto &void_ret_2() {} // expected-error {{cannot deduce return type 'auto &' for function with no return statements}} +const auto void_ret_3() {} // ok, return type 'const void' is adjusted to 'void' + +const auto void_ret_4() { + if (false) + return void(); + if (false) + return; + return 0; // expected-error {{'auto' in return type deduced as 'int' here but deduced as 'void' in earlier return statement}} +} + +namespace Templates { + template<typename T> auto f1() { + return T() + 1; + } + template<typename T> auto &f2(T &&v) { return v; } + int a = f1<int>(); + const int &b = f2(0); + double d; + float &c = f2(0.0); // expected-error {{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'double'}} + + template<typename T> auto fwd_decl(); // expected-note {{declared here}} + int e = fwd_decl<int>(); // expected-error {{cannot be used before it is defined}} + template<typename T> auto fwd_decl() { return 0; } + int f = fwd_decl<int>(); + template<typename T> auto fwd_decl(); + int g = fwd_decl<char>(); + + auto (*p)() = f1; // expected-error {{incompatible initializer}} + auto (*q)() = f1<int>; // ok + + typedef decltype(f2(1.2)) dbl; // expected-note {{previous}} + typedef float dbl; // expected-error {{typedef redefinition with different types ('float' vs 'decltype(f2(1.2))' (aka 'double &'))}} + + extern template auto fwd_decl<double>(); + int k1 = fwd_decl<double>(); + extern template int fwd_decl<char>(); // expected-error {{does not refer to a function template}} + int k2 = fwd_decl<char>(); + + template<typename T> auto instantiate() { T::error; } // expected-error {{has no members}} + extern template auto instantiate<int>(); // ok + int k = instantiate<int>(); // expected-note {{in instantiation of}} + template<> auto instantiate<char>() {} // ok + template<> void instantiate<double>() {} // expected-error {{no function template matches}} + + template<typename T> auto arg_single() { return 0; } + template<typename T> auto arg_multi() { return 0l; } + template<typename T> auto arg_multi(int) { return "bad"; } + template<typename T> struct Outer { + static auto arg_single() { return 0.f; } + static auto arg_multi() { return 0.; } + static auto arg_multi(int) { return "bad"; } + }; + template<typename T> T &take_fn(T (*p)()); + + int &check1 = take_fn(arg_single); // expected-error {{no matching}} expected-note@-2 {{couldn't infer}} + int &check2 = take_fn(arg_single<int>); + int &check3 = take_fn<int>(arg_single); // expected-error {{no matching}} expected-note@-4{{no overload of 'arg_single'}} + int &check4 = take_fn<int>(arg_single<int>); + long &check5 = take_fn(arg_multi); // expected-error {{no matching}} expected-note@-6 {{couldn't infer}} + long &check6 = take_fn(arg_multi<int>); + long &check7 = take_fn<long>(arg_multi); // expected-error {{no matching}} expected-note@-8{{no overload of 'arg_multi'}} + long &check8 = take_fn<long>(arg_multi<int>); + + float &mem_check1 = take_fn(Outer<int>::arg_single); + float &mem_check2 = take_fn<float>(Outer<char>::arg_single); + double &mem_check3 = take_fn(Outer<long>::arg_multi); + double &mem_check4 = take_fn<double>(Outer<double>::arg_multi); + + namespace Deduce1 { + template<typename T> auto f() { return 0; } // expected-note {{candidate}} + template<typename T> void g(T(*)()); // expected-note 2{{candidate}} + void h() { + auto p = f<int>; + auto (*q)() = f<int>; + int (*r)() = f; // expected-error {{does not match}} + g(f<int>); + g<int>(f); // expected-error {{no matching function}} + g(f); // expected-error {{no matching function}} + } + } + + namespace Deduce2 { + template<typename T> auto f(int) { return 0; } // expected-note {{candidate}} + template<typename T> void g(T(*)(int)); // expected-note 2{{candidate}} + void h() { + auto p = f<int>; + auto (*q)(int) = f<int>; + int (*r)(int) = f; // expected-error {{does not match}} + g(f<int>); + g<int>(f); // expected-error {{no matching function}} + g(f); // expected-error {{no matching function}} + } + } + + namespace Deduce3 { + template<typename T> auto f(T) { return 0; } + template<typename T> void g(T(*)(int)); // expected-note {{couldn't infer}} + void h() { + auto p = f<int>; + auto (*q)(int) = f<int>; + int (*r)(int) = f; // ok + g(f<int>); + g<int>(f); // ok + g(f); // expected-error {{no matching function}} + } + } + + namespace DeduceInDeducedReturnType { + template<typename T, typename U> auto f() -> auto (T::*)(U) { + int (T::*result)(U) = nullptr; + return result; + } + struct S {}; + int (S::*(*p)())(double) = f; + int (S::*(*q)())(double) = f<S, double>; + } +} + +auto fwd_decl_using(); +namespace N { using ::fwd_decl_using; } +auto fwd_decl_using() { return 0; } +namespace N { int k = N::fwd_decl_using(); } + +namespace OverloadResolutionNonTemplate { + auto f(); + auto f(int); // expected-note {{here}} + + int &g(int (*f)()); // expected-note {{not viable: no overload of 'f' matching 'int (*)()'}} + char &g(int (*f)(int)); // expected-note {{not viable: no overload of 'f' matching 'int (*)(int)'}} + + int a = g(f); // expected-error {{no matching function}} + + auto f() { return 0; } + + // FIXME: It's not completely clear whether this should be ill-formed. + int &b = g(f); // expected-error {{used before it is defined}} + + auto f(int) { return 0.0; } + + int &c = g(f); // ok +} + +namespace OverloadResolutionTemplate { + auto f(); + template<typename T> auto f(T); + + int &g(int (*f)()); // expected-note {{not viable: no overload of 'f' matching 'int (*)()'}} expected-note {{candidate}} + char &g(int (*f)(int)); // expected-note {{not viable: no overload of 'f' matching 'int (*)(int)'}} expected-note {{candidate}} + + int a = g(f); // expected-error {{no matching function}} + + auto f() { return 0; } + + int &b = g(f); // ok (presumably), due to deduction failure forming type of 'f<int>' + + template<typename T> auto f(T) { return 0; } + + int &c = g(f); // expected-error {{ambiguous}} +} + +namespace DefaultedMethods { + struct A { + auto operator=(const A&) = default; // expected-error {{must return 'DefaultedMethods::A &'}} + A &operator=(A&&); // expected-note {{previous}} + }; + auto A::operator=(A&&) = default; // expected-error {{differs from the declaration in the return type}} +} + +namespace Constexpr { + constexpr auto f1(int n) { return n; } + struct NonLiteral { ~NonLiteral(); } nl; // expected-note {{user-provided destructor}} + constexpr auto f2(int n) { return nl; } // expected-error {{return type 'Constexpr::NonLiteral' is not a literal type}} +} + +// It's not really clear whether these are valid, but this matches g++. +using size_t = decltype(sizeof(0)); +auto operator new(size_t n, const char*); // expected-error {{must return type 'void *'}} +auto operator delete(void *, const char*); // expected-error {{must return type 'void'}} + +namespace Virtual { + struct S { + virtual auto f() { return 0; } // expected-error {{function with deduced return type cannot be virtual}} expected-note {{here}} + }; + // Allow 'auto' anyway for error recovery. + struct T : S { + int f(); + }; + struct U : S { + auto f(); // expected-error {{different return}} + }; + + // And here's why... + struct V { virtual auto f(); }; // expected-error {{cannot be virtual}} + struct W : V { virtual auto f(); }; // expected-error {{cannot be virtual}} + auto V::f() { return 0; } // in tu1.cpp + auto W::f() { return 0.0; } // in tu2.cpp + W w; + int k1 = w.f(); + int k2 = ((V&)w).f(); +} + +namespace std_examples { + +namespace NoReturn { + auto f() {} + void (*p)() = &f; + + auto *g() {} // expected-error {{cannot deduce return type 'auto *' for function with no return statements}} +} + +namespace UseBeforeComplete { + auto n = n; // expected-error {{variable 'n' declared with 'auto' type cannot appear in its own initializer}} + auto f(); // expected-note {{declared here}} + void g() { &f; } // expected-error {{function 'f' with deduced return type cannot be used before it is defined}} + auto sum(int i) { + if (i == 1) + return i; + else + return sum(i - 1) + i; + } +} + +namespace Redecl { + auto f(); + auto f() { return 42; } + auto f(); // expected-note 2{{previous}} + int f(); // expected-error {{functions that differ only in their return type cannot be overloaded}} + decltype(auto) f(); // expected-error {{cannot be overloaded}} + + template<typename T> auto g(T t) { return t; } // expected-note {{candidate}} + template auto g(int); + template char g(char); // expected-error {{does not refer to a function}} + template<> auto g(double); + + template<typename T> T g(T t) { return t; } // expected-note {{candidate}} + template char g(char); + template auto g(float); + + void h() { return g(42); } // expected-error {{ambiguous}} +} + +namespace ExplicitInstantiationDecl { + template<typename T> auto f(T t) { return t; } + extern template auto f(int); + int (*p)(int) = f; +} + +} diff --git a/test/SemaCXX/cxx1y-initializer-aggregates.cpp b/test/SemaCXX/cxx1y-initializer-aggregates.cpp new file mode 100644 index 0000000..9b54240 --- /dev/null +++ b/test/SemaCXX/cxx1y-initializer-aggregates.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -std=c++1y %s -verify + +namespace in_class_init { + union U { char c; double d = 4.0; }; + constexpr U u1 = U(); + constexpr U u2 {}; + constexpr U u3 { 'x' }; + static_assert(u1.d == 4.0, ""); + static_assert(u2.d == 4.0, ""); + static_assert(u3.c == 'x', ""); + + struct A { + int n = 5; + int m = n * 3; + union { + char c; + double d = 4.0; + }; + }; + constexpr A a1 {}; + constexpr A a2 { 8 }; + constexpr A a3 { 1, 2, { 3 } }; + constexpr A a4 { 1, 2, { .d = 3.0 } }; + static_assert(a1.d == 4.0, ""); + static_assert(a2.m == 24, ""); + static_assert(a2.d == 4.0, ""); + static_assert(a3.c == 3, ""); + static_assert(a3.d == 4.0, ""); // expected-error {{constant expression}} expected-note {{active member 'c'}} + static_assert(a4.d == 3.0, ""); + + struct B { + int n; + constexpr int f() { return n * 5; } + int m = f(); + }; + B b1 {}; + constexpr B b2 { 2 }; + B b3 { 1, 2 }; + static_assert(b2.m == 10, ""); + + struct C { + int k; + union { + int l = k; // expected-error {{invalid use of non-static}} + }; + }; +} + +namespace nested_aggregate_init { + struct A { + int n = 5; + int b = n * 3; + }; + struct B { + constexpr B(int k) : d(1.23), k(k) {} + // Within this aggregate, both this object's 'this' and the temporary's + // 'this' are used. + constexpr int f() const { return A{k}.b; } + double d; + int k; + }; + static_assert(B(6).f() == 18, ""); +} diff --git a/test/SemaCXX/cxx98-compat-pedantic.cpp b/test/SemaCXX/cxx98-compat-pedantic.cpp index 18fd152..208ea4c 100644 --- a/test/SemaCXX/cxx98-compat-pedantic.cpp +++ b/test/SemaCXX/cxx98-compat-pedantic.cpp @@ -1,3 +1,5 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++1y -DCXX1Y -Wc++98-compat-pedantic -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++1y -DCXX1Y -Wc++98-compat -Werror %s // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -verify %s // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -Werror %s // RUN: %clang_cc1 -fsyntax-only -std=c++98 -Werror %s @@ -38,3 +40,12 @@ long long ll1 = // expected-warning {{'long long' is incompatible with C++98}} unsigned long long ull1 = // expected-warning {{'long long' is incompatible with C++98}} 42ULL; // expected-warning {{'long long' is incompatible with C++98}} +int k = 0b1001; +#ifdef CXX1Y +// expected-warning@-2 {{binary integer literals are incompatible with C++ standards before C++1y}} +#endif + +void f(int n) { int a[n]; } +#ifdef CXX1Y +// expected-warning@-2 {{arrays of runtime bound are incompatible with C++ standards before C++1y}} +#endif diff --git a/test/SemaCXX/enum-unscoped-nonexistent.cpp b/test/SemaCXX/enum-unscoped-nonexistent.cpp index d49800c..e9da38f 100644 --- a/test/SemaCXX/enum-unscoped-nonexistent.cpp +++ b/test/SemaCXX/enum-unscoped-nonexistent.cpp @@ -5,8 +5,8 @@ struct Base { }; template<typename T> struct S : Base { enum E : int; - constexpr int f(); - constexpr int g(); // expected-note {{declared here}} + constexpr int f() const; + constexpr int g() const; // expected-note {{declared here}} void h(); }; template<> enum S<char>::E : int {}; // expected-note {{enum 'S<char>::E' was explicitly specialized here}} @@ -16,13 +16,13 @@ template<typename T> enum S<T>::E : int { b = 8 }; // The unqualified-id here names a member of the non-dependent base class Base // and not the injected enumerator name 'a' from the specialization. -template<typename T> constexpr int S<T>::f() { return a; } +template<typename T> constexpr int S<T>::f() const { return a; } static_assert(S<char>().f() == 1, ""); static_assert(S<int>().f() == 1, ""); // The unqualified-id here names a member of the current instantiation, which // bizarrely might not exist in some instantiations. -template<typename T> constexpr int S<T>::g() { return b; } // expected-error {{enumerator 'b' does not exist in instantiation of 'S<char>'}} +template<typename T> constexpr int S<T>::g() const { return b; } // expected-error {{enumerator 'b' does not exist in instantiation of 'S<char>'}} static_assert(S<char>().g() == 1, ""); // expected-note {{here}} expected-error {{not an integral constant expression}} expected-note {{undefined}} static_assert(S<short>().g() == 2, ""); static_assert(S<long>().g() == 8, ""); diff --git a/test/SemaCXX/for-range-unused.cpp b/test/SemaCXX/for-range-unused.cpp index ce6b379..ec11015 100644 --- a/test/SemaCXX/for-range-unused.cpp +++ b/test/SemaCXX/for-range-unused.cpp @@ -7,7 +7,7 @@ template <typename T> void doIt() { int a; // expected-warning {{unused variable 'a'}} - for (auto& e : elements) + for (auto& e : elements) // expected-warning {{unused variable 'e'}} ; } @@ -17,5 +17,5 @@ template <typename T> int main(int, char**) { Vector<int> vector; - vector.doIt(); + vector.doIt(); // expected-note {{here}} } diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp index 5631577..c80323c 100644 --- a/test/SemaCXX/i-c-e-cxx.cpp +++ b/test/SemaCXX/i-c-e-cxx.cpp @@ -60,7 +60,7 @@ int* y = reinterpret_cast<const char&>(x); // expected-error {{cannot initialize // This isn't an integral constant expression, but make sure it folds anyway. struct PR8836 { char _; long long a; }; // expected-warning {{long long}} -int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast<const volatile char&>((((PR8836*)0)->a))]; // expected-warning {{folded to constant array as an extension}} expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}} +int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast<const volatile char&>((((PR8836*)0)->a))]; // expected-warning {{folded to constant array as an extension}} expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} const int nonconst = 1.0; // expected-note {{declared here}} int arr[nonconst]; // expected-warning {{folded to constant array as an extension}} expected-note {{initializer of 'nonconst' is not a constant expression}} diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp index 0ba9508..504df0d 100644 --- a/test/SemaCXX/linkage-spec.cpp +++ b/test/SemaCXX/linkage-spec.cpp @@ -106,3 +106,11 @@ namespace PR9162 { return sizeof(ArtsSink); } } + +namespace pr14958 { + namespace js { extern int ObjectClass; } + extern "C" { + namespace js {} + } + int js::ObjectClass; +} diff --git a/test/SemaCXX/linkage.cpp b/test/SemaCXX/linkage.cpp index 6b73d59..13d295a 100644 --- a/test/SemaCXX/linkage.cpp +++ b/test/SemaCXX/linkage.cpp @@ -94,3 +94,12 @@ extern "C" { // CHECK: define linkonce_odr i8* @_ZN5test21A1BILj0EE3fooEv( // CHECK: define linkonce_odr i8* @_ZN5test11A3fooILj0EEEPvv( + +namespace test5 { + struct foo { + }; + extern "C" { + const foo bar[] = { + }; + } +} diff --git a/test/SemaCXX/linkage2.cpp b/test/SemaCXX/linkage2.cpp index ddf4064..3cfa981 100644 --- a/test/SemaCXX/linkage2.cpp +++ b/test/SemaCXX/linkage2.cpp @@ -152,3 +152,15 @@ namespace test15 { const int a = 5; // expected-note {{previous definition is here}} static const int a; // expected-error {{redefinition of 'a'}} } + +namespace test16 { + extern "C" { + class Foo { + int x; + friend int bar(Foo *y); + }; + int bar(Foo *y) { + return y->x; + } + } +} diff --git a/test/SemaCXX/pascal-strings.cpp b/test/SemaCXX/pascal-strings.cpp index 89194b5..f4c692d 100644 --- a/test/SemaCXX/pascal-strings.cpp +++ b/test/SemaCXX/pascal-strings.cpp @@ -4,3 +4,5 @@ const wchar_t *pascalString = L"\pThis is a Pascal string"; unsigned char a[3] = "\pa"; unsigned char b[3] = "\pab"; unsigned char c[3] = "\pabc"; // expected-error {{initializer-string for char array is too long}} +unsigned char d[3] = ("\pab"); +unsigned char e[3] = ("\pabc"); // expected-error {{initializer-string for char array is too long}} diff --git a/test/SemaCXX/trailing-return-0x.cpp b/test/SemaCXX/trailing-return-0x.cpp index 462b4fa..bd601db 100644 --- a/test/SemaCXX/trailing-return-0x.cpp +++ b/test/SemaCXX/trailing-return-0x.cpp @@ -85,3 +85,12 @@ namespace PR12053 { f2(0); // expected-error{{no matching function for call to 'f2'}} } } + +namespace DR1608 { + struct S { + void operator+(); + int operator[](int); + auto f() -> decltype(+*this); // expected-note {{here}} + auto f() -> decltype((*this)[0]); // expected-error {{cannot be overloaded}} + }; +} diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp index 839fdaf..1b76a86 100644 --- a/test/SemaCXX/undefined-internal.cpp +++ b/test/SemaCXX/undefined-internal.cpp @@ -323,3 +323,10 @@ namespace test13 { } } +namespace test14 { + extern "C" const int foo; + + int f() { + return foo; + } +} diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp index 2aa5662..665cfe7 100644 --- a/test/SemaCXX/uninitialized.cpp +++ b/test/SemaCXX/uninitialized.cpp @@ -511,3 +511,15 @@ namespace operators { int x = x = 5; } + +namespace lambdas { + struct A { + template<typename T> A(T) {} + int x; + }; + A a0([] { return a0.x; }); // ok + void f() { + A a1([=] { return a1.x; }); // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}} + A a2([&] { return a2.x; }); // ok + } +} diff --git a/test/SemaCXX/warn-c++11-extensions.cpp b/test/SemaCXX/warn-c++11-extensions.cpp index 8f35171..bf8612a 100644 --- a/test/SemaCXX/warn-c++11-extensions.cpp +++ b/test/SemaCXX/warn-c++11-extensions.cpp @@ -5,3 +5,5 @@ long long ll1 = // expected-warning {{'long long' is a C++11 extension}} unsigned long long ull1 = // expected-warning {{'long long' is a C++11 extension}} 42ULL; // expected-warning {{'long long' is a C++11 extension}} +enum struct E1 { A, B }; // expected-warning {{scoped enumerations are a C++11 extension}} +enum class E2 { C, D }; // expected-warning {{scoped enumerations are a C++11 extension}} diff --git a/test/SemaCXX/warn-overloaded-virtual.cpp b/test/SemaCXX/warn-overloaded-virtual.cpp index 9b0f5aa..629d59d 100644 --- a/test/SemaCXX/warn-overloaded-virtual.cpp +++ b/test/SemaCXX/warn-overloaded-virtual.cpp @@ -120,3 +120,21 @@ struct MostDerived: Derived3, Derived2 { void func(); }; } + +namespace { + class A { + virtual int foo(bool) const; + // expected-note@-1{{type mismatch at 1st parameter ('bool' vs 'int')}} + virtual int foo(int, int) const; + // expected-note@-1{{different number of parameters (2 vs 1)}} + virtual int foo(int*) const; + // expected-note@-1{{type mismatch at 1st parameter ('int *' vs 'int')}} + virtual int foo(int) volatile; + // expected-note@-1{{different qualifiers (volatile vs const)}} + }; + + class B : public A { + virtual int foo(int) const; + // expected-warning@-1{{hides overloaded virtual functions}} + }; +} diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp index 3f41124..bc4b40e 100644 --- a/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1475,8 +1475,8 @@ namespace substitution_test { public: Mutex mu; - void lockData() __attribute__((exclusive_lock_function(mu))) { } - void unlockData() __attribute__((unlock_function(mu))) { } + void lockData() __attribute__((exclusive_lock_function(mu))); + void unlockData() __attribute__((unlock_function(mu))); void doSomething() __attribute__((exclusive_locks_required(mu))) { } }; @@ -1484,8 +1484,8 @@ namespace substitution_test { class DataLocker { public: - void lockData (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { } - void unlockData(MyData *d) __attribute__((unlock_function(d->mu))) { } + void lockData (MyData *d) __attribute__((exclusive_lock_function(d->mu))); + void unlockData(MyData *d) __attribute__((unlock_function(d->mu))); }; @@ -2858,7 +2858,7 @@ void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_) { } void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) { - mu1_.Lock(); + mu1_.ReaderLock(); } void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) { @@ -3640,8 +3640,8 @@ class Foo { LOCKS_EXCLUDED(mu2_); void lock() EXCLUSIVE_LOCK_FUNCTION(mu1_) EXCLUSIVE_LOCK_FUNCTION(mu2_); - void readerlock() EXCLUSIVE_LOCK_FUNCTION(mu1_) - EXCLUSIVE_LOCK_FUNCTION(mu2_); + void readerlock() SHARED_LOCK_FUNCTION(mu1_) + SHARED_LOCK_FUNCTION(mu2_); void unlock() UNLOCK_FUNCTION(mu1_) UNLOCK_FUNCTION(mu2_); bool trylock() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_) @@ -3663,9 +3663,9 @@ void Foo::foo2() { } void Foo::foo3() { } -void Foo::lock() { } -void Foo::readerlock() { } -void Foo::unlock() { } +void Foo::lock() { mu1_.Lock(); mu2_.Lock(); } +void Foo::readerlock() { mu1_.ReaderLock(); mu2_.ReaderLock(); } +void Foo::unlock() { mu1_.Unlock(); mu2_.Unlock(); } bool Foo::trylock() { return true; } bool Foo::readertrylock() { return true; } @@ -3915,3 +3915,73 @@ void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2()); } // end namespace UnevaluatedContextTest + +namespace LockUnlockFunctionTest { + +// Check built-in lock functions +class LOCKABLE MyLockable { +public: + void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); } + void readerLock() SHARED_LOCK_FUNCTION() { mu_.ReaderLock(); } + void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); } + +private: + Mutex mu_; +}; + + +class Foo { +public: + // Correct lock/unlock functions + void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) { + mu_.Lock(); + } + + void readerLock() SHARED_LOCK_FUNCTION(mu_) { + mu_.ReaderLock(); + } + + void unlock() UNLOCK_FUNCTION(mu_) { + mu_.Unlock(); + } + + // Check failure to lock. + void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} + mu2_.Lock(); + mu2_.Unlock(); + } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} + + void readerLockBad() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} + mu2_.Lock(); + mu2_.Unlock(); + } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} + + void unlockBad() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} + mu2_.Lock(); + mu2_.Unlock(); + } // expected-warning {{mutex 'mu_' is still locked at the end of function}} + + // Check locking the wrong thing. + void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} + mu2_.Lock(); // expected-note {{mutex acquired here}} + } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \ + // expected-warning {{mutex 'mu2_' is still locked at the end of function}} + + + void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} + mu2_.ReaderLock(); // expected-note {{mutex acquired here}} + } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \ + // expected-warning {{mutex 'mu2_' is still locked at the end of function}} + + + void unlockBad2() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} + mu2_.Unlock(); // expected-warning {{unlocking 'mu2_' that was not locked}} + } // expected-warning {{mutex 'mu_' is still locked at the end of function}} + +private: + Mutex mu_; + Mutex mu2_; +}; + +} // end namespace LockUnlockFunctionTest + diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp index e12668b..9fb6011 100644 --- a/test/SemaCXX/warn-unused-filescoped.cpp +++ b/test/SemaCXX/warn-unused-filescoped.cpp @@ -133,6 +133,27 @@ namespace test6 { }; } +namespace test7 +{ + template<typename T> + static inline void foo(T) { } + + // This should not emit an unused-function warning since it inherits + // the static storage type from the base template. + template<> + inline void foo(int) { } + + // Partial specialization + template<typename T, typename U> + static inline void bar(T, U) { } + + template<typename U> + inline void bar(int, U) { } + + template<> + inline void bar(int, int) { } +}; + namespace pr14776 { namespace { struct X {}; diff --git a/test/SemaCXX/warn-unused-variables-error.cpp b/test/SemaCXX/warn-unused-variables-error.cpp new file mode 100644 index 0000000..6386c4b --- /dev/null +++ b/test/SemaCXX/warn-unused-variables-error.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -verify %s + +namespace PR6948 { + template<typename T> class X; // expected-note{{template is declared here}} + + void f() { + X<char> str (read_from_file()); // expected-error{{use of undeclared identifier 'read_from_file'}} \ + expected-error{{implicit instantiation of undefined template 'PR6948::X<char>'}} + } +} diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp index 4e8d51d..00597f9 100644 --- a/test/SemaCXX/warn-unused-variables.cpp +++ b/test/SemaCXX/warn-unused-variables.cpp @@ -41,15 +41,6 @@ void test_dependent_init(T *p) { (void)i; } -namespace PR6948 { - template<typename T> class X; // expected-note{{template is declared here}} - - void f() { - X<char> str (read_from_file()); // expected-error{{use of undeclared identifier 'read_from_file'}} \ - expected-error{{implicit instantiation of undefined template 'PR6948::X<char>'}} - } -} - void unused_local_static() { static int x = 0; static int y = 0; // expected-warning{{unused variable 'y'}} @@ -135,3 +126,5 @@ namespace ctor_with_cleanups { S2 s((S1())); } } + +#include "Inputs/warn-unused-variables.h" diff --git a/test/SemaObjC/arc-repeated-weak.mm b/test/SemaObjC/arc-repeated-weak.mm index e652bee..b5d9002 100644 --- a/test/SemaObjC/arc-repeated-weak.mm +++ b/test/SemaObjC/arc-repeated-weak.mm @@ -327,6 +327,32 @@ void doWhileLoop(Test *a) { } @end +@interface Base1 +@end +@interface Sub1 : Base1 +@end +@interface Sub1(cat) +-(id)prop; +@end + +void test1(Sub1 *s) { + use([s prop]); + use([s prop]); +} + +@interface Base1(cat) +@property (weak) id prop; +@end + +void test2(Sub1 *s) { + // This does not warn because the "prop" in "Base1(cat)" was introduced + // after the method declaration and we don't find it as overridden. + // Always looking for overridden methods after the method declaration is expensive + // and it's not clear it is worth it currently. + use([s prop]); + use([s prop]); +} + class Wrapper { Test *a; diff --git a/test/SemaObjC/arc-system-header.m b/test/SemaObjC/arc-system-header.m index 3443bda..d9392ed 100644 --- a/test/SemaObjC/arc-system-header.m +++ b/test/SemaObjC/arc-system-header.m @@ -1,30 +1,30 @@ -// silly workaround expected-note {{marked unavailable here}} // RUN: %clang_cc1 -fobjc-arc -isystem %S/Inputs %s -DNO_USE // RUN: %clang_cc1 -fobjc-arc -isystem %S/Inputs %s -verify -// another silly workaround expected-note {{marked unavailable here}} #include <arc-system-header.h> #ifndef NO_USE void test(id op, void *cp) { cp = test0(op); // expected-error {{'test0' is unavailable: converts between Objective-C and C pointers in -fobjc-arc}} cp = *test1(&op); // expected-error {{'test1' is unavailable: converts between Objective-C and C pointers in -fobjc-arc}} +// expected-note@arc-system-header.h:1 {{marked unavailable here}} +// expected-note@arc-system-header.h:5 {{marked unavailable here}} } -// workaround expected-note {{marked unavailable here}} void test3(struct Test3 *p) { p->field = 0; // expected-error {{'field' is unavailable: this system declaration uses an unsupported type}} + // expected-note@arc-system-header.h:14 {{marked unavailable here}} } -// workaround expected-note {{marked unavailable here}} void test4(Test4 *p) { p->field1 = 0; // expected-error {{'field1' is unavailable: this system declaration uses an unsupported type}} + // expected-note@arc-system-header.h:19 {{marked unavailable here}} p->field2 = 0; } -// workaround expected-note {{marked unavailable here}} void test5(struct Test5 *p) { p->field = 0; // expected-error {{'field' is unavailable: this system field has retaining ownership}} + // expected-note@arc-system-header.h:25 {{marked unavailable here}} } id test6() { @@ -38,12 +38,13 @@ id test6() { x = (id) (test6_helper(), kMagicConstant); } -// workaround expected-note 4 {{marked unavailable here}} expected-note 2 {{property 'prop' is declared unavailable here}} void test7(Test7 *p) { *p.prop = 0; // expected-error {{'prop' is unavailable: this system declaration uses an unsupported type}} p.prop = 0; // expected-error {{'prop' is unavailable: this system declaration uses an unsupported type}} *[p prop] = 0; // expected-error {{'prop' is unavailable: this system declaration uses an unsupported type}} [p setProp: 0]; // expected-error {{'setProp:' is unavailable: this system declaration uses an unsupported type}} +// expected-note@arc-system-header.h:41 4 {{marked unavailable here}} +// expected-note@arc-system-header.h:41 2 {{property 'prop' is declared unavailable here}} } #endif diff --git a/test/SemaObjC/arc-unavailable-for-weakref.m b/test/SemaObjC/arc-unavailable-for-weakref.m index b140c64..b9b5cc5 100644 --- a/test/SemaObjC/arc-unavailable-for-weakref.m +++ b/test/SemaObjC/arc-unavailable-for-weakref.m @@ -56,9 +56,33 @@ __attribute__((objc_arc_weak_reference_unavailable)) @interface I { } -@property (weak) NSFont *font; // expected-note {{property declared here}} +@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}} @end -@implementation I -@synthesize font = _font; // expected-error {{synthesis of a weak-unavailable property is disallowed because it requires synthesis of an instance variable of the __weak object}} +@implementation I // expected-note {{when implemented by class I}} +@synthesize font = _font; +@end + +// rdar://13676793 +@protocol MyProtocol +@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}} +@end + +@interface I1 <MyProtocol> +@end + +@implementation I1 // expected-note {{when implemented by class I1}} +@synthesize font = _font; +@end + +@interface Super +@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}} +@end + + +@interface I2 : Super +@end + +@implementation I2 // expected-note {{when implemented by class I2}} +@synthesize font = _font; @end diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m index d89d035..1d4e42d 100644 --- a/test/SemaObjC/arc.m +++ b/test/SemaObjC/arc.m @@ -756,3 +756,14 @@ void rdar12569201(id key, id value) { @interface C - (void)method:(id[])objects; // expected-error{{must explicitly describe intended ownership of an object array parameter}} @end + +// rdar://13752880 +@interface NSMutableArray : NSArray @end + +typedef __strong NSMutableArray * PSNS; + +void test(NSArray *x) { + NSMutableArray *y = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}} + __strong NSMutableArray *y1 = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}} + PSNS y2 = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}} +} diff --git a/test/SemaObjC/attr-availability.m b/test/SemaObjC/attr-availability.m index bf7ef19..fddcd50 100644 --- a/test/SemaObjC/attr-availability.m +++ b/test/SemaObjC/attr-availability.m @@ -17,7 +17,7 @@ // rdar://11475360 @interface B : A -- (void)method; // expected-note {{method 'method' declared here}} +- (void)method; // NOTE: we expect 'method' to *not* inherit availability. - (void)overridden __attribute__((availability(macosx,introduced=10.4))); // expected-warning{{overriding method introduced after overridden method on OS X (10.4 vs. 10.3)}} - (void)overridden2 __attribute__((availability(macosx,introduced=10.2))); - (void)overridden3 __attribute__((availability(macosx,deprecated=10.4))); @@ -28,7 +28,35 @@ void f(A *a, B *b) { [a method]; // expected-warning{{'method' is deprecated: first deprecated in OS X 10.2}} - [b method]; // expected-warning {{'method' is deprecated: first deprecated in OS X 10.2}} + [b method]; // no-warning [a proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in OS X 10.2}} [b proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in OS X 10.2}} } + +// Test case for <rdar://problem/11627873>. Warn about +// using a deprecated method when that method is re-implemented in a +// subclass where the redeclared method is not deprecated. +@interface C +- (void) method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{method 'method' declared here}} +@end + +@interface D : C +- (void) method; +@end + +@interface E : D +- (void) method; +@end + +@implementation D +- (void) method { + [super method]; // expected-warning {{'method' is deprecated: first deprecated in OS X 10.2}} +} +@end + +@implementation E +- (void) method { + [super method]; // no-warning +} +@end + diff --git a/test/SemaObjC/warn-isa-ref.m b/test/SemaObjC/deprecated-objc-introspection.m index b1ffb4f..faaef25 100644 --- a/test/SemaObjC/warn-isa-ref.m +++ b/test/SemaObjC/deprecated-objc-introspection.m @@ -1,4 +1,10 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fsyntax-only -verify %s + +//====------------------------------------------------------------====// +// Test deprecated direct usage of the 'isa' pointer. +//====------------------------------------------------------------====// + +typedef unsigned long NSUInteger; typedef struct objc_object { struct objc_class *isa; @@ -81,3 +87,11 @@ static void func() { } @end +// Test for introspection of Objective-C pointers via bitmasking. + +void testBitmasking(NSObject *p) { + (void) (((NSUInteger) p) & 0x1); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}} + (void) (0x1 & ((NSUInteger) p)); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}} + (void) (((NSUInteger) p) ^ 0x1); // no-warning + (void) (0x1 ^ ((NSUInteger) p)); // no-warning +}
\ No newline at end of file diff --git a/test/SemaObjC/format-arg-attribute.m b/test/SemaObjC/format-arg-attribute.m index 6edb8fd..dede433 100644 --- a/test/SemaObjC/format-arg-attribute.m +++ b/test/SemaObjC/format-arg-attribute.m @@ -14,7 +14,7 @@ union u1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'form enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}} extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2))); -extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{attribute takes one argument}} +extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{use of undeclared identifier 'foo'}} /* format_arg formats must take and return a string. */ extern NSString *fi0 (int) __attribute__((format_arg(1))); // expected-error {{format argument not a string type}} diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m index bd33ad4..8490130 100644 --- a/test/SemaObjC/format-strings-objc.m +++ b/test/SemaObjC/format-strings-objc.m @@ -13,6 +13,7 @@ typedef signed char BOOL; typedef unsigned int NSUInteger; +typedef long NSInteger; @class NSString, Protocol; extern void NSLog(NSString *format, ...); extern void NSLogv(NSString *format, va_list args); @@ -235,3 +236,8 @@ void testByValueObjectInFormat(Foo *obj) { [Bar log2:@"%d", *obj]; // expected-error {{cannot pass object with interface type 'Foo' by value to variadic method; expected type from format string was 'int'}} } +// <rdar://problem/13557053> +void testTypeOf(NSInteger dW, NSInteger dH) { + NSLog(@"dW %d dH %d",({ __typeof__(dW) __a = (dW); __a < 0 ? -__a : __a; }),({ __typeof__(dH) __a = (dH); __a < 0 ? -__a : __a; })); // expected-warning 2 {{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} +} + diff --git a/test/SemaObjC/message.m b/test/SemaObjC/message.m index f43bdf9..40fa102 100644 --- a/test/SemaObjC/message.m +++ b/test/SemaObjC/message.m @@ -106,3 +106,15 @@ void foo5(id p) { // expected-note {{to match this '['}} \ // expected-warning {{instance method '-bar' not found}} } + +@interface I1 +-(void)unavail_meth __attribute__((unavailable)); // expected-note {{marked unavailable here}} +@end + +// rdar://13620447 +void foo6(I1 *p) { + [p + bar]; // expected-warning {{instance method '-bar' not found}} + [p + unavail_meth]; // expected-error {{unavailable}} +} diff --git a/test/SemaObjC/method-conflict-2.m b/test/SemaObjC/method-conflict-2.m index df59f24..ec80a43 100644 --- a/test/SemaObjC/method-conflict-2.m +++ b/test/SemaObjC/method-conflict-2.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -Wmethod-signatures -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -Wmethod-signatures -fsyntax-only -verify -Wno-objc-root-class %s @interface A @end @interface B : A @end @@ -42,3 +43,24 @@ - (A*) test1 { return 0; } // id -> A* is rdar://problem/8596987 - (id) test2 { return 0; } @end + +// rdar://12522752 +typedef int int32_t; +typedef long long int64_t; + +@interface NSObject @end + +@protocol CKMessage +@property (nonatomic,readonly,assign) int64_t sequenceNumber; // expected-note {{previous definition is here}} +@end + +@protocol CKMessage; + +@interface CKIMMessage : NSObject<CKMessage> +@end + +@implementation CKIMMessage +- (int32_t)sequenceNumber { // expected-warning {{conflicting return type in implementation of 'sequenceNumber': 'int64_t' (aka 'long long') vs 'int32_t' (aka 'int')}} + return 0; +} +@end diff --git a/test/SemaObjC/property-category-4.m b/test/SemaObjC/property-category-4.m index e7939b3..ccf5e9b 100644 --- a/test/SemaObjC/property-category-4.m +++ b/test/SemaObjC/property-category-4.m @@ -16,3 +16,108 @@ @dynamic d_selectedObjects; // expected-error {{property declared in category 'CAT' cannot be implemented in class implementation}} @end + +// rdar://13713098 +// Test1 +@interface NSArray +- (int)count; +@end + +@protocol MyCountable +@property (readonly) int count; +@end + + +@interface NSArray(Additions) <MyCountable> +@end + +@implementation NSArray(Additions) +@end + +// Test2 +@protocol NSProtocol +- (int)count; +@end + +@interface NSArray1 <NSProtocol> +@end + +@interface NSArray1(Additions) <MyCountable> +@end + +@implementation NSArray1(Additions) +@end + +// Test3 +@interface Super <NSProtocol> +@end + +@interface NSArray2 : Super @end + +@interface NSArray2(Additions) <MyCountable> +@end + +@implementation NSArray2(Additions) +@end + +// Test3 +@interface Super1 <NSProtocol> +@property (readonly) int count; +@end + +@protocol MyCountable1 +@end + +@interface NSArray3 : Super1 <MyCountable1> +@end + +@implementation NSArray3 +@end + +// Test4 +@interface I +@property int d1; +@end + +@interface I(CAT) +@property int d1; +@end + +@implementation I(CAT) +@end + +// Test5 +@interface C @end + +@interface C (CAT) +- (int) p; +@end + + +@interface C (Category) +@property (readonly) int p; // no warning for this property - a getter is declared in another category +@property (readonly) int p1; // expected-note {{property declared here}} +@property (readonly) int p2; // no warning for this property - a getter is declared in this category +- (int) p2; +@end + +@implementation C (Category) // expected-warning {{property 'p1' requires method 'p1' to be defined - use @dynamic or provide a method implementation in this category}} +@end + +// Test6 +@protocol MyProtocol +@property (readonly) float anotherFloat; // expected-note {{property declared here}} +@property (readonly) float Float; // no warning for this property - a getter is declared in this protocol +- (float) Float; +@end + +@interface MyObject +{ float anotherFloat; } +@end + +@interface MyObject (CAT) <MyProtocol> +@end + +@implementation MyObject (CAT) // expected-warning {{property 'anotherFloat' requires method 'anotherFloat' to be defined - use @dynamic or provide a method implementation in this category}} +@end + diff --git a/test/SemaObjC/property-category-impl.m b/test/SemaObjC/property-category-impl.m index be42dea..135b005 100644 --- a/test/SemaObjC/property-category-impl.m +++ b/test/SemaObjC/property-category-impl.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// expected-no-diagnostics /* This test is for categories which don't implement the accessors but some accessors are implemented in their base class implementation. In this case,no warning must be issued. @@ -24,10 +25,10 @@ @end @interface MyClass (public) -@property(readwrite) int foo; // expected-note {{property declared here}} +@property(readwrite) int foo; @end -@implementation MyClass (public)// expected-warning {{property 'foo' requires method 'setFoo:' to be defined }} +@implementation MyClass (public) @end // rdar://12568064 diff --git a/test/SemaObjC/property-deprecated-warning.m b/test/SemaObjC/property-deprecated-warning.m index aa7b764..7e10356 100644 --- a/test/SemaObjC/property-deprecated-warning.m +++ b/test/SemaObjC/property-deprecated-warning.m @@ -5,37 +5,51 @@ typedef signed char BOOL; @protocol P -@property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{property 'ptarget' is declared deprecated here}} +@property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'ptarget' is declared deprecated here}} expected-note {{method 'ptarget' declared here}} @end @protocol P1<P> -- (void)setPtarget:(id)arg; // expected-note {{method 'setPtarget:' declared here}} +- (void)setPtarget:(id)arg; @end @interface UITableViewCell<P1> -@property(nonatomic,assign) id target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'target' is declared deprecated here}} +@property(nonatomic,assign) id target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'target' is declared deprecated here}} expected-note {{method 'setTarget:' declared here}} @end @interface PSTableCell : UITableViewCell - - (void)setTarget:(id)target; // expected-note {{method 'setTarget:' declared here}} + - (void)setTarget:(id)target; @end @interface UITableViewCell(UIDeprecated) -@property(nonatomic,assign) id dep_target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{method 'dep_target' declared here}} \ - // expected-note 2 {{property 'dep_target' is declared deprecated here}} \ - // expected-note {{method 'setDep_target:' declared here}} +@property(nonatomic,assign) id dep_target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{method 'dep_target' declared here}} \ + // expected-note 4 {{property 'dep_target' is declared deprecated here}} \ + // expected-note 2 {{method 'setDep_target:' declared here}} @end @implementation PSTableCell - (void)setTarget:(id)target {}; - (void)setPtarget:(id)val {}; - (void) Meth { + [self setTarget: (id)0]; // no-warning + [self setDep_target: [self dep_target]]; // expected-warning {{'dep_target' is deprecated: first deprecated in iOS 3.0}} \ + // expected-warning {{'setDep_target:' is deprecated: first deprecated in iOS 3.0}} + + [self setPtarget: (id)0]; // no-warning +} +@end + +@implementation UITableViewCell +@synthesize target; +@synthesize ptarget; +- (void)setPtarget:(id)val {}; +- (void)setTarget:(id)target {}; +- (void) Meth { [self setTarget: (id)0]; // expected-warning {{'setTarget:' is deprecated: first deprecated in iOS 3.0}} [self setDep_target: [self dep_target]]; // expected-warning {{'dep_target' is deprecated: first deprecated in iOS 3.0}} \ // expected-warning {{'setDep_target:' is deprecated: first deprecated in iOS 3.0}} - [self setPtarget: (id)0]; // expected-warning {{setPtarget:' is deprecated: first deprecated in iOS 3.0}} + [self setPtarget: (id)0]; // no-warning } @end @@ -56,9 +70,11 @@ void testCustomAccessorNames(CustomAccessorNames *obj) { @end @interface ProtocolInCategory (TheCategory) <P1> -- (id)ptarget; // expected-note {{method 'ptarget' declared here}} +- (id)ptarget; @end -id useDeprecatedProperty(ProtocolInCategory *obj) { - return [obj ptarget]; // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}} +id useDeprecatedProperty(ProtocolInCategory *obj, id<P> obj2, int flag) { + if (flag) + return [obj ptarget]; // no-warning + return [obj2 ptarget]; // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}} } diff --git a/test/SemaObjC/property-noninherited-availability-attr.m b/test/SemaObjC/property-noninherited-availability-attr.m index 79cdd3e..0c2a5d3 100644 --- a/test/SemaObjC/property-noninherited-availability-attr.m +++ b/test/SemaObjC/property-noninherited-availability-attr.m @@ -5,7 +5,8 @@ @interface NSObject @end @protocol myProtocol -@property int myProtocolProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); +@property int myProtocolProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note {{method 'myProtocolProperty' declared here}} \ + // expected-note {{property 'myProtocolProperty' is declared deprecated here}} @end @interface Foo : NSObject @@ -15,18 +16,19 @@ @end @interface Bar : Foo <myProtocol> -@property int myProperty; // expected-note {{'myProperty' declared here}} -@property int myProtocolProperty; // expected-note {{'myProtocolProperty' declared here}} +@property int myProperty; +@property int myProtocolProperty; @end -void test(Foo *y, Bar *x) { +void test(Foo *y, Bar *x, id<myProtocol> z) { y.myProperty = 0; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}} [y myProperty]; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}} x.myProperty = 1; // no-warning - [x myProperty]; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}} + [x myProperty]; // no-warning x.myProtocolProperty = 0; // no-warning - [x myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}} + [x myProtocolProperty]; // no-warning + [z myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}} } diff --git a/test/SemaObjC/property-user-setter.m b/test/SemaObjC/property-user-setter.m index cda983c..e84fad2 100644 --- a/test/SemaObjC/property-user-setter.m +++ b/test/SemaObjC/property-user-setter.m @@ -85,7 +85,7 @@ static int g_val; - (void)setFoo:(int)value; @end -void g(int); // expected-note {{passing argument to parameter here}} +void g(int); void f(C *c) { c.Foo = 17; // OK diff --git a/test/SemaObjC/property.m b/test/SemaObjC/property.m index 76fdf5b..7485447 100644 --- a/test/SemaObjC/property.m +++ b/test/SemaObjC/property.m @@ -11,7 +11,7 @@ @end @interface I(CAT) -@property int d1; // expected-note 2 {{property declared here}} +@property int d1; @end @implementation I @@ -22,8 +22,7 @@ @synthesize name; // OK! property with same name as an accessible ivar of same name @end -@implementation I(CAT) // expected-warning {{property 'd1' requires method 'd1' to be defined }} \ - // expected-warning {{property 'd1' requires method 'setD1:' to be defined }} +@implementation I(CAT) @synthesize d1; // expected-error {{@synthesize not allowed in a category's implementation}} @dynamic bad; // expected-error {{property implementation must have its declaration in the category 'CAT'}} @end diff --git a/test/SemaObjC/protocol-lookup-2.m b/test/SemaObjC/protocol-lookup-2.m index 9e8ed8a..90f6db0 100644 --- a/test/SemaObjC/protocol-lookup-2.m +++ b/test/SemaObjC/protocol-lookup-2.m @@ -32,3 +32,26 @@ } @end + + +@protocol ProtC +-document; +@end + +@interface I1 : NSObject +@end + +@interface I1(cat) +-document; +@end + +@interface I2 : NSObject +-document; +@end + +@interface I2() <ProtC> +@end + +@implementation I2 +- document { return 0; } +@end diff --git a/test/SemaObjC/typo-correction.m b/test/SemaObjC/typo-correction.m index 3fd61e2..893e312 100644 --- a/test/SemaObjC/typo-correction.m +++ b/test/SemaObjC/typo-correction.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -verify -fsyntax-only -fwarn-on-spellcheck +// RUN: %clang_cc1 %s -verify -fsyntax-only @interface B @property int x; @@ -8,8 +8,7 @@ @end // Spell-checking 'undefined' is ok. -undefined var; // expected-warning {{spell-checking initiated}} \ - // expected-error {{unknown type name}} +undefined var; // expected-error {{unknown type name}} typedef int super1; @implementation S diff --git a/test/SemaObjC/warn-missing-super.m b/test/SemaObjC/warn-missing-super.m index 02b8165..e9769a9 100644 --- a/test/SemaObjC/warn-missing-super.m +++ b/test/SemaObjC/warn-missing-super.m @@ -54,5 +54,5 @@ __attribute__((objc_root_class)) // CHECK-GC-ONLY: 1 warning generated. // RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-arc %s 2>&1 | FileCheck --check-prefix=CHECK-ARC %s -// CHECK-ARC: warn-missing-super.m:36:4: error: ARC forbids explicit message send of 'dealloc' +// CHECK-ARC: warn-missing-super.m:36:10: error: ARC forbids explicit message send of 'dealloc' // CHECK-ARC: 1 error generated. diff --git a/test/SemaObjCXX/arc-system-header.mm b/test/SemaObjCXX/arc-system-header.mm index 107b5b5..3358e5f 100644 --- a/test/SemaObjCXX/arc-system-header.mm +++ b/test/SemaObjCXX/arc-system-header.mm @@ -6,5 +6,4 @@ void f(A* a) { a->data.void_ptr = 0; a->data.a_b.b = 0; // expected-error{{'a_b' is unavailable: this system field has retaining ownership}} } -// Silly location below -// expected-note{{declaration has been explicitly marked unavailable here}} +// expected-note@arc-system-header.h:10{{declaration has been explicitly marked unavailable here}} diff --git a/test/SemaObjCXX/foreach.mm b/test/SemaObjCXX/foreach.mm index 3c4b908..d1302c1 100644 --- a/test/SemaObjCXX/foreach.mm +++ b/test/SemaObjCXX/foreach.mm @@ -12,8 +12,18 @@ void f(NSArray *a) { // expected-warning {{expression result unused}} for (id thisKey : keys); + + for (auto thisKey : keys) { } // expected-warning{{'auto' deduced as 'id' in declaration of 'thisKey'}} +} + +template<typename Collection> +void ft(Collection col) { + for (id x : col) { } + for (auto x : col) { } } +template void ft(NSArray *); + /* // rdar://9072298 */ @protocol NSObject @end @@ -59,3 +69,9 @@ void test2(NSObject<NSFastEnumeration> *collection) { // expected-warning {{property access result unused - getters should not be used for side effects}} } } + +void testErrors(NSArray *array) { + typedef int fn(int); + + for (fn x in array) { } // expected-error{{non-variable declaration in 'for' loop}} +} diff --git a/test/SemaObjCXX/property-reference.mm b/test/SemaObjCXX/property-reference.mm index b86ae5e..cfac9f3 100644 --- a/test/SemaObjCXX/property-reference.mm +++ b/test/SemaObjCXX/property-reference.mm @@ -57,3 +57,21 @@ template<typename T> void f() { } template void f<int>(); + +// rdar://13602832 +// +// Make sure that the default-argument checker looks through +// pseudo-object expressions correctly. The default argument +// needs to force l2r to test this effectively because the checker +// is syntactic and runs before placeholders are handled. +@interface Test13602832 +- (int) x; +@end +namespace test13602832 { + template <int N> void foo(Test13602832 *a, int limit = a.x + N) {} // expected-error {{default argument references parameter 'a'}} + + void test(Test13602832 *a) { + // FIXME: this is a useless cascade error. + foo<1024>(a); // expected-error {{no matching function}} + } +} diff --git a/test/SemaObjCXX/references.mm b/test/SemaObjCXX/references.mm index f63e17d..fa55207 100644 --- a/test/SemaObjCXX/references.mm +++ b/test/SemaObjCXX/references.mm @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -verify -emit-llvm -o - %s -// expected-no-diagnostics +// RUN: %clang_cc1 -verify -o - %s + +__attribute__((objc_root_class)) +@interface Root @end // Test reference binding. @@ -8,7 +10,7 @@ typedef struct { int f1; } T; -@interface A +@interface A : Root @property (assign) T p0; @property (assign) T& p1; @end @@ -61,3 +63,14 @@ void f6(baz* x) { f5d(ToBar()); (void)((foo&)ToBar()); } + +// rdar://13794269 +@interface B : Root @end +@implementation B { + unsigned bf : 4; // expected-note {{declared here}} +} + +- (void) foo { + unsigned &i = bf; // expected-error {{non-const reference cannot bind to bit-field 'bf'}} +} +@end diff --git a/test/SemaOpenCL/event_t.cl b/test/SemaOpenCL/event_t.cl index 57a0981..06197d0 100644 --- a/test/SemaOpenCL/event_t.cl +++ b/test/SemaOpenCL/event_t.cl @@ -2,7 +2,7 @@ event_t glb_evt; // expected-error {{the event_t type cannot be used to declare a program scope variable}} -struct evt_s { +constant struct evt_s { event_t evt; // expected-error {{the event_t type cannot be used to declare a structure or union field}} } evt_str; diff --git a/test/SemaOpenCL/storageclass.cl b/test/SemaOpenCL/storageclass.cl index fdfe134..d2678f2 100644 --- a/test/SemaOpenCL/storageclass.cl +++ b/test/SemaOpenCL/storageclass.cl @@ -2,6 +2,8 @@ static constant int A = 0; +int X = 0; // expected-error{{global variables must have a constant address space qualifier}} + // static is not allowed at local scope. void kernel foo() { static int X = 5; // expected-error{{variables in function scope cannot be declared static}} diff --git a/test/SemaTemplate/attributes.cpp b/test/SemaTemplate/attributes.cpp index 495f4a7..5a06a70 100644 --- a/test/SemaTemplate/attributes.cpp +++ b/test/SemaTemplate/attributes.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -verify %s namespace attribute_aligned { template<int N> @@ -18,6 +18,26 @@ namespace attribute_aligned { check_alignment<2>::t c2; check_alignment<3>::t c3; // expected-note 2 {{in instantiation}} check_alignment<4>::t c4; + + template<unsigned Size, unsigned Align> + class my_aligned_storage + { + __attribute__((align(Align))) char storage[Size]; + }; + + template<typename T> + class C { + public: + C() { + static_assert(sizeof(t) == sizeof(T), "my_aligned_storage size wrong"); + static_assert(alignof(t) == alignof(T), "my_aligned_storage align wrong"); // expected-warning{{'alignof' applied to an expression is a GNU extension}} + } + + private: + my_aligned_storage<sizeof(T), alignof(T)> t; + }; + + C<double> cd; } namespace PR9049 { diff --git a/test/SemaTemplate/dependent-names.cpp b/test/SemaTemplate/dependent-names.cpp index eb75e69..fa47ef5 100644 --- a/test/SemaTemplate/dependent-names.cpp +++ b/test/SemaTemplate/dependent-names.cpp @@ -264,7 +264,7 @@ namespace PR10053 { } namespace PR10187 { - namespace A { + namespace A1 { template<typename T> struct S { void f() { @@ -278,6 +278,25 @@ namespace PR10187 { } } + namespace A2 { + template<typename T> + struct S { + void f() { + for (auto &a : e) + __range(a); // expected-error {{undeclared identifier '__range'}} + } + T e[10]; + }; + void g() { + S<int>().f(); // expected-note {{here}} + } + struct X {}; + void __range(X); + void h() { + S<X>().f(); + } + } + namespace B { template<typename T> void g(); // expected-note {{not viable}} template<typename T> void f() { diff --git a/test/SemaTemplate/example-dynarray.cpp b/test/SemaTemplate/example-dynarray.cpp deleted file mode 100644 index 266d2d4..0000000 --- a/test/SemaTemplate/example-dynarray.cpp +++ /dev/null @@ -1,178 +0,0 @@ -// RUN: %clangxx -emit-llvm -c -o - %s -// XFAIL: hexagon -#include <stddef.h> -#include <stdlib.h> -#include <assert.h> - -// Placement new requires <new> to be included, but we don't support that yet. -void* operator new(size_t, void* ptr) throw() { - return ptr; -} -void operator delete(void*, void*) throw() { -} - -template<typename T> -class dynarray { -public: - dynarray() { Start = Last = End = 0; } - - dynarray(const dynarray &other) { - Start = (T*)malloc(sizeof(T) * other.size()); - Last = End = Start + other.size(); - - for (unsigned I = 0, N = other.size(); I != N; ++I) - new (Start + I) T(other[I]); - } - - ~dynarray() { - for (unsigned I = 0, N = size(); I != N; ++I) - Start[I].~T(); - - free(Start); - } - - dynarray &operator=(const dynarray &other) { - T* NewStart = (T*)malloc(sizeof(T) * other.size()); - - for (unsigned I = 0, N = other.size(); I != N; ++I) - new (NewStart + I) T(other[I]); - - for (unsigned I = 0, N = size(); I != N; ++I) - Start[I].~T(); - - free(Start); - Start = NewStart; - Last = End = NewStart + other.size(); - return *this; - } - - unsigned size() const { return Last - Start; } - unsigned capacity() const { return End - Start; } - - void push_back(const T& value); - - void pop_back() { - --Last; - Last->~T(); - } - - T& operator[](unsigned Idx) { - return Start[Idx]; - } - - const T& operator[](unsigned Idx) const { - return Start[Idx]; - } - - typedef T* iterator; - typedef const T* const_iterator; - - iterator begin() { return Start; } - const_iterator begin() const { return Start; } - - iterator end() { return Last; } - const_iterator end() const { return Last; } - - bool operator==(const dynarray &other) const { - if (size() != other.size()) - return false; - - for (unsigned I = 0, N = size(); I != N; ++I) - if ((*this)[I] != other[I]) - return false; - - return true; - } - - bool operator!=(const dynarray &other) const { - return !(*this == other); - } - -public: - T* Start, *Last, *End; -}; - -template<typename T> -void dynarray<T>::push_back(const T& value) { - if (Last == End) { - unsigned NewCapacity = capacity() * 2; - if (NewCapacity == 0) - NewCapacity = 4; - - T* NewStart = (T*)malloc(sizeof(T) * NewCapacity); - - unsigned Size = size(); - for (unsigned I = 0; I != Size; ++I) - new (NewStart + I) T(Start[I]); - - for (unsigned I = 0, N = size(); I != N; ++I) - Start[I].~T(); - free(Start); - - Start = NewStart; - Last = Start + Size; - End = Start + NewCapacity; - } - - new (Last) T(value); - ++Last; -} - -struct Point { - Point() { x = y = z = 0.0; } - Point(const Point& other) : x(other.x), y(other.y), z(other.z) { } - - float x, y, z; -}; - -int main() { - dynarray<int> di; - di.push_back(0); - di.push_back(1); - di.push_back(2); - di.push_back(3); - di.push_back(4); - assert(di.size() == 5); - for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I) - assert(*I == I - di.begin()); - - for (int I = 0, N = di.size(); I != N; ++I) - assert(di[I] == I); - - di.pop_back(); - assert(di.size() == 4); - di.push_back(4); - - dynarray<int> di2 = di; - assert(di2.size() == 5); - assert(di.begin() != di2.begin()); - for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end(); - I != IEnd; ++I) - assert(*I == I - di2.begin()); - - dynarray<int> di3(di); - assert(di3.size() == 5); - assert(di.begin() != di3.begin()); - for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end(); - I != IEnd; ++I) - assert(*I == I - di3.begin()); - - dynarray<int> di4; - assert(di4.size() == 0); - di4 = di; - assert(di4.size() == 5); - assert(di.begin() != di4.begin()); - for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end(); - I != IEnd; ++I) - assert(*I == I - di4.begin()); - - assert(di4 == di); - di4[3] = 17; - assert(di4 != di); - - dynarray<Point> dp; - dp.push_back(Point()); - assert(dp.size() == 1); - - return 0; -} diff --git a/test/SemaTemplate/local-member-templates.cpp b/test/SemaTemplate/local-member-templates.cpp new file mode 100644 index 0000000..3cdf5df --- /dev/null +++ b/test/SemaTemplate/local-member-templates.cpp @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 -std=c++1y -verify %s +// RUN: %clang_cc1 -std=c++1y -verify %s -fdelayed-template-parsing + +namespace nested_local_templates_1 { + +template <class T> struct Outer { + template <class U> int outer_mem(T t, U u) { + struct Inner { + template <class V> int inner_mem(T t, U u, V v) { + struct InnerInner { + template <class W> int inner_inner_mem(W w, T t, U u, V v) { + return 0; + } + }; + InnerInner().inner_inner_mem("abc", t, u, v); + return 0; + } + }; + Inner i; + i.inner_mem(t, u, 3.14); + return 0; + } + + template <class U> int outer_mem(T t, U *u); +}; + +template int Outer<int>::outer_mem(int, char); + +template <class T> template <class U> int Outer<T>::outer_mem(T t, U *u) { + struct Inner { + template <class V> + int inner_mem(T t, U u, V v) { //expected-note{{candidate function}} + struct InnerInner { + template <class W> int inner_inner_mem(W w, T t, U u, V v) { return 0; } + }; + InnerInner().inner_inner_mem("abc", t, u, v); + return 0; + } + }; + Inner i; + i.inner_mem(t, U{}, i); + i.inner_mem(t, u, 3.14); //expected-error{{no matching member function for call to 'inner}} + return 0; +} + +template int Outer<int>::outer_mem(int, char *); //expected-note{{in instantiation of function}} + +} // end ns + +namespace nested_local_templates_2 { + +template <class T> struct Outer { + template <class U> void outer_mem(T t, U u) { + struct Inner { + template <class V> struct InnerTemplateClass { + template <class W> + void itc_mem(T t, U u, V v, W w) { //expected-note{{candidate function}} + struct InnerInnerInner { + template <class X> void iii_mem(X x) {} + }; + InnerInnerInner i; + i.iii_mem("abc"); + } + }; + }; + Inner i; + typename Inner::template InnerTemplateClass<Inner> ii; + ii.itc_mem(t, u, i, "jim"); + ii.itc_mem(t, u, 0, "abd"); //expected-error{{no matching member function}} + } +}; + +template void +Outer<int>::outer_mem(int, char); //expected-note{{in instantiation of}} + +} diff --git a/test/SemaTemplate/ms-function-specialization-class-scope.cpp b/test/SemaTemplate/ms-function-specialization-class-scope.cpp index 131922b..9efb02c 100644 --- a/test/SemaTemplate/ms-function-specialization-class-scope.cpp +++ b/test/SemaTemplate/ms-function-specialization-class-scope.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s +// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s class A { diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp index 8f80cb5..cb1a7f5 100644 --- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp +++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp @@ -8,7 +8,6 @@ public: void g();// expected-note {{must qualify identifier to find this declaration in dependent base class}} }; - template <class T> class B : public A<T> { public: @@ -28,6 +27,31 @@ void test() b.z(3); } +struct A2 { + template<class T> void f(T) { + XX; //expected-error {{use of undeclared identifier 'XX'}} + A2::XX; //expected-error {{no member named 'XX' in 'A2'}} + } +}; +template void A2::f(int); + +template<class T0> +struct A3 { + template<class T1> void f(T1) { + XX; //expected-error {{use of undeclared identifier 'XX'}} + } +}; +template void A3<int>::f(int); + +template<class T0> +struct A4 { + void f(char) { + XX; //expected-error {{use of undeclared identifier 'XX'}} + } +}; +template class A4<int>; + + namespace lookup_dependent_bases_id_expr { template<class T> class A { diff --git a/test/SemaTemplate/overload-candidates.cpp b/test/SemaTemplate/overload-candidates.cpp index dc6d2a5..ad65397 100644 --- a/test/SemaTemplate/overload-candidates.cpp +++ b/test/SemaTemplate/overload-candidates.cpp @@ -62,3 +62,20 @@ template<typename T> struct NonTemplateFunction { typename boost::enable_if<sizeof(T) == 4, int>::type f(); // expected-error{{no type named 'type' in 'boost::enable_if<false, int>'; 'enable_if' cannot be used to disable this declaration}} }; NonTemplateFunction<char> NTFC; // expected-note{{here}} + +namespace NS1 { + template <class A> + class array {}; +} + +namespace NS2 { + template <class A> + class array {}; +} + +template <class A> +void foo(NS2::array<A>); // expected-note{{candidate template ignored: could not match 'NS2::array' against 'NS1::array'}} + +void test() { + foo(NS1::array<int>()); // expected-error{{no matching function for call to 'foo'}} +} diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp index 210b5e4..2450952 100644 --- a/test/SemaTemplate/temp_arg_nontype.cpp +++ b/test/SemaTemplate/temp_arg_nontype.cpp @@ -337,3 +337,12 @@ namespace rdar13000548 { } } + +namespace rdar13806270 { + template <unsigned N> class X { }; + const unsigned value = 32; + struct Y { + X<value + 1> x; + }; + void foo() {} +} diff --git a/test/Tooling/clang-check-args.cpp b/test/Tooling/clang-check-args.cpp index 9ba5d45..66950ae 100644 --- a/test/Tooling/clang-check-args.cpp +++ b/test/Tooling/clang-check-args.cpp @@ -2,6 +2,3 @@ // CHECK: C++ requires invalid; - -// FIXME: This is incompatible to -fms-compatibility. -// XFAIL: win32 diff --git a/test/Tooling/clang-check-builtin-headers.cpp b/test/Tooling/clang-check-builtin-headers.cpp index 504d197..ed2bea0 100644 --- a/test/Tooling/clang-check-builtin-headers.cpp +++ b/test/Tooling/clang-check-builtin-headers.cpp @@ -10,6 +10,3 @@ // CHECK: C++ requires invalid; - -// FIXME: This is incompatible to -fms-compatibility. -// XFAIL: win32 diff --git a/test/Tooling/clang-check-chdir.cpp b/test/Tooling/clang-check-chdir.cpp index 29b5abb..c811323 100644 --- a/test/Tooling/clang-check-chdir.cpp +++ b/test/Tooling/clang-check-chdir.cpp @@ -12,6 +12,3 @@ // CHECK: C++ requires invalid; - -// FIXME: This is incompatible to -fms-compatibility. -// XFAIL: win32 diff --git a/test/Tooling/clang-check.cpp b/test/Tooling/clang-check.cpp index 91ab01b..56835b3 100644 --- a/test/Tooling/clang-check.cpp +++ b/test/Tooling/clang-check.cpp @@ -7,6 +7,3 @@ // CHECK: C++ requires invalid; - -// FIXME: This is incompatible to -fms-compatibility. -// XFAIL: win32 diff --git a/test/Tooling/multi-jobs.cpp b/test/Tooling/multi-jobs.cpp index a3eb703..1e6bce1 100644 --- a/test/Tooling/multi-jobs.cpp +++ b/test/Tooling/multi-jobs.cpp @@ -2,6 +2,3 @@ // CHECK: C++ requires invalid; - -// FIXME: This is incompatible to -fms-compatibility. -// XFAIL: win32 diff --git a/test/lit.cfg b/test/lit.cfg index 4466f0f..6b0ad59 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -24,12 +24,21 @@ if platform.system() == 'Windows': config.environment['PATH'])) config.environment['PATH'] = path +# Choose between lit's internal shell pipeline runner and a real shell. If +# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override. +use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") +if use_lit_shell: + # 0 is external, "" is default, and everything else is internal. + execute_external = (use_lit_shell == "0") +else: + # Otherwise we default to internal on Windows and external elsewhere, as + # bash on Windows is usually very slow. + execute_external = (not sys.platform in ['win32']) + # testFormat: The test format to use to interpret tests. # # For now we require '&&' between commands, until they get globally killed and # the test runner updated. -execute_external = (platform.system() != 'Windows' - or lit.getBashPath() not in [None, ""]) config.test_format = lit.formats.ShTest(execute_external) # suffixes: A list of file extensions to treat as test files. @@ -219,17 +228,13 @@ if platform.system() not in ['FreeBSD']: config.available_features.add('crash-recovery') # Shell execution -if platform.system() not in ['Windows'] or lit.getBashPath() != '': +if execute_external: config.available_features.add('shell') # Exclude MSYS due to transforming '/' to 'X:/mingwroot/'. if not platform.system() in ['Windows'] or lit.getBashPath() == '': config.available_features.add('shell-preserves-root') -# For tests that require Darwin to run. -if platform.system() in ['Darwin']: - config.available_features.add('system-darwin') - # ANSI escape sequences in non-dumb terminal if platform.system() not in ['Windows']: config.available_features.add('ansi-escape-sequences') |