diff options
Diffstat (limited to 'test')
810 files changed, 25540 insertions, 3049 deletions
diff --git a/test/ARCMT/check-with-serialized-diag.m b/test/ARCMT/check-with-serialized-diag.m index d8073d0469..77bad96dcc 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 12efa93f07..377dce30ca 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 8cef0919bb..014c109299 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 0ca6dca1fe..e9ff8df34d 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 320bca2a36..8a8a030514 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 faca0b41aa..6e434a04b2 100644 --- a/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -59,4 +59,41 @@ namespace std { return 0; } }; + + class bad_alloc : public exception { + public: + bad_alloc() throw(); + bad_alloc(const bad_alloc&) throw(); + bad_alloc& operator=(const bad_alloc&) throw(); + virtual const char* what() const throw() { + return 0; + } + }; + + struct nothrow_t {}; + + extern const nothrow_t nothrow; + + template<class InputIter, class OutputIter> + OutputIter copy(InputIter II, InputIter IE, OutputIter OI) { + while (II != IE) + *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(); +void* operator new[](std::size_t, const std::nothrow_t&) throw(); +void operator delete(void*, const std::nothrow_t&) throw(); +void operator delete[](void*, const std::nothrow_t&) throw(); + +void* operator new (std::size_t size, void* ptr) throw() { return ptr; }; +void* operator new[] (std::size_t size, void* ptr) throw() { return ptr; }; +void operator delete (void* ptr, void*) throw() {}; +void operator delete[] (void* ptr, void*) throw() {}; diff --git a/test/Analysis/Inputs/system-header-simulator.h b/test/Analysis/Inputs/system-header-simulator.h index 04688c782a..dd1cd4942f 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 new file mode 100644 index 0000000000..5a596d47ec --- /dev/null +++ b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp @@ -0,0 +1,105 @@ +// 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 + +#include "Inputs/system-header-simulator-for-malloc.h" + +//-------------------------------------------------- +// Check that unix.Malloc catches all types of bugs. +//-------------------------------------------------- +void testMallocDoubleFree() { + int *p = (int *)malloc(sizeof(int)); + free(p); + free(p); // expected-warning{{Attempt to free released memory}} +} + +void testMallocLeak() { + int *p = (int *)malloc(sizeof(int)); +} // expected-warning{{Potential leak of memory pointed to by 'p'}} + +void testMallocUseAfterFree() { + int *p = (int *)malloc(sizeof(int)); + free(p); + int j = *p; // expected-warning{{Use of memory after it is freed}} +} + +void testMallocBadFree() { + int i; + free(&i); // expected-warning{{Argument to free() is the address of the local variable 'i', which is not memory allocated by malloc()}} +} + +void testMallocOffsetFree() { + int *p = (int *)malloc(sizeof(int)); + free(++p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}} +} + +//----------------------------------------------------------------- +// Check that unix.MismatchedDeallocator catches all types of bugs. +//----------------------------------------------------------------- +void testMismatchedDeallocator() { + int *x = (int *)malloc(sizeof(int)); + delete x; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} +} + +//---------------------------------------------------------------- +// Check that alpha.cplusplus.NewDelete catches all types of bugs. +//---------------------------------------------------------------- +void testNewDoubleFree() { + int *p = new int; + delete p; + delete p; // expected-warning{{Attempt to free released memory}} +} + +void testNewLeak() { + int *p = new int; +} +#ifdef LEAKS +// expected-warning@-2 {{Potential leak of memory pointed to by 'p'}} +#endif + +void testNewUseAfterFree() { + int *p = (int *)operator new(0); + delete p; + int j = *p; // expected-warning{{Use of memory after it is freed}} +} + +void testNewBadFree() { + int i; + delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}} +} + +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+MismatchedDeallocator_intersections.cpp b/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp new file mode 100644 index 0000000000..639790d31a --- /dev/null +++ b/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator -analyzer-store region -std=c++11 -verify %s +// expected-no-diagnostics + +typedef __typeof(sizeof(int)) size_t; +void *malloc(size_t); +void free(void *); + +//-------------------------------------------------------------------- +// Check that unix.Malloc + unix.MismatchedDeallocator does not enable +// warnings produced by the alpha.cplusplus.NewDelete checker. +//-------------------------------------------------------------------- +void testNewDeleteNoWarn() { + int i; + delete &i; // no-warning + + int *p1 = new int; + delete ++p1; // no-warning + + int *p2 = new int; + delete p2; + delete p2; // no-warning + + int *p3 = new int; // no-warning + + int *p4 = new int; + delete p4; + int j = *p4; // no-warning +} diff --git a/test/Analysis/Malloc+NewDelete_intersections.cpp b/test/Analysis/Malloc+NewDelete_intersections.cpp new file mode 100644 index 0000000000..310663646a --- /dev/null +++ b/test/Analysis/Malloc+NewDelete_intersections.cpp @@ -0,0 +1,15 @@ +// 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 + cplusplus.NewDelete does not enable +// warnings produced by unix.MismatchedDeallocator. +//------------------------------------------------------------------- +void testMismatchedDeallocator() { + int *p = (int *)malloc(sizeof(int)); + delete p; +} // expected-warning{{Potential leak of memory pointed to by 'p'}} diff --git a/test/Analysis/MismatchedDeallocator-checker-test.mm b/test/Analysis/MismatchedDeallocator-checker-test.mm new file mode 100644 index 0000000000..56d46d99b0 --- /dev/null +++ b/test/Analysis/MismatchedDeallocator-checker-test.mm @@ -0,0 +1,221 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s + +#include "Inputs/system-header-simulator-objc.h" +#include "Inputs/system-header-simulator-cxx.h" + +typedef __typeof__(sizeof(int)) size_t; +void *malloc(size_t); +void *realloc(void *ptr, size_t size); +void *calloc(size_t nmemb, size_t size); +char *strdup(const char *s); +void __attribute((ownership_returns(malloc))) *my_malloc(size_t); + +void free(void *); +void __attribute((ownership_takes(malloc, 1))) my_free(void *); + +//--------------------------------------------------------------- +// Test if an allocation function matches deallocation function +//--------------------------------------------------------------- + +//--------------- test malloc family +void testMalloc1() { + int *p = (int *)malloc(sizeof(int)); + delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} +} + +void testMalloc2() { + int *p = (int *)malloc(8); + int *q = (int *)realloc(p, 16); + delete q; // expected-warning{{Memory allocated by realloc() should be deallocated by free(), not 'delete'}} +} + +void testMalloc3() { + int *p = (int *)calloc(1, sizeof(int)); + delete p; // expected-warning{{Memory allocated by calloc() should be deallocated by free(), not 'delete'}} +} + +void testMalloc4(const char *s) { + char *p = strdup(s); + delete p; // expected-warning{{Memory allocated by strdup() should be deallocated by free(), not 'delete'}} +} + +void testMalloc5() { + int *p = (int *)my_malloc(sizeof(int)); + delete p; // expected-warning{{Memory allocated by my_malloc() should be deallocated by free(), not 'delete'}} +} + +void testMalloc6() { + int *p = (int *)malloc(sizeof(int)); + operator delete(p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete}} +} + +void testMalloc7() { + int *p = (int *)malloc(sizeof(int)); + delete[] p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete[]'}} +} + +void testMalloc8() { + int *p = (int *)malloc(sizeof(int)); + operator delete[](p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete[]}} +} + +//--------------- test new family +void testNew1() { + int *p = new int; + free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}} +} + +void testNew2() { + int *p = (int *)operator new(0); + free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}} +} + +void testNew3() { + int *p = new int[1]; + free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}} +} + +void testNew4() { + int *p = new int; + realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}} +} + +void testNew5() { + int *p = (int *)operator new(0); + realloc(p, sizeof(long)); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not realloc()}} +} + +void testNew6() { + int *p = new int[1]; + realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}} +} + +void testNew7() { + int *p = new int; + delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}} +} + +void testNew8() { + int *p = (int *)operator new(0); + delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}} +} + +void testNew9() { + int *p = new int[1]; + delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}} +} + +void testNew10() { + int *p = (int *)operator new[](0); + delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}} +} + +void testNew11(NSUInteger dataLength) { + int *p = new int; + NSData *d = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not +dataWithBytesNoCopy:length:freeWhenDone:}} + // FIXME: should be "+dataWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'." +} + +//------------------------------------------------------- +// Check for intersection with unix.Malloc bounded with +// unix.MismatchedDeallocator +//------------------------------------------------------- + +// new/delete oparators are subjects of cplusplus.NewDelete. +void testNewDeleteNoWarn() { + int i; + delete &i; // no-warning + + int *p1 = new int; + delete ++p1; // no-warning + + int *p2 = new int; + delete p2; + delete p2; // no-warning + + int *p3 = new int; // no-warning +} + +void testDeleteOpAfterFree() { + int *p = (int *)malloc(sizeof(int)); + free(p); + operator delete(p); // no-warning +} + +void testDeleteAfterFree() { + int *p = (int *)malloc(sizeof(int)); + free(p); + delete p; // no-warning +} + +void testStandardPlacementNewAfterFree() { + int *p = (int *)malloc(sizeof(int)); + free(p); + p = new(p) int; // no-warning +} + +//--------------------------------------------------------------- +// Check for intersection with cplusplus.NewDelete bounded with +// unix.MismatchedDeallocator +//--------------------------------------------------------------- + +// malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations +void testMallocFreeNoWarn() { + int i; + free(&i); // no-warning + + int *p1 = (int *)malloc(sizeof(int)); + free(++p1); // no-warning + + int *p2 = (int *)malloc(sizeof(int)); + free(p2); + free(p2); // no-warning + + int *p3 = (int *)malloc(sizeof(int)); // no-warning +} + +void testFreeAfterDelete() { + int *p = new int; + delete p; + free(p); // no-warning +} + +void testStandardPlacementNewAfterDelete() { + int *p = new int; + delete p; + p = new(p) int; // no-warning +} + + +// Smart pointer example +template <typename T> +struct SimpleSmartPointer { + T *ptr; + + explicit SimpleSmartPointer(T *p = 0) : ptr(p) {} + ~SimpleSmartPointer() { + delete ptr; + // expected-warning@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}} + // expected-warning@-2 {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} + } +}; + +void testSimpleSmartPointerArrayNew() { + { + SimpleSmartPointer<int> a(new int); + } // no-warning + + { + SimpleSmartPointer<int> a(new int[4]); + } +} + +void testSimpleSmartPointerMalloc() { + { + SimpleSmartPointer<int> a(new int); + } // no-warning + + { + SimpleSmartPointer<int> a((int *)malloc(4)); + } +} diff --git a/test/Analysis/MismatchedDeallocator-path-notes.cpp b/test/Analysis/MismatchedDeallocator-path-notes.cpp new file mode 100644 index 0000000000..369d8f6975 --- /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 new file mode 100644 index 0000000000..540c7a4eab --- /dev/null +++ b/test/Analysis/NSContainers.m @@ -0,0 +1,200 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NilArg -verify -Wno-objc-root-class %s +typedef unsigned long NSUInteger; +typedef signed char BOOL; +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject +@end +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end +@protocol NSMutableCopying +- (id)mutableCopyWithZone:(NSZone *)zone; +@end +@protocol NSCoding +- (void)encodeWithCoder:(NSCoder *)aCoder; +@end +@protocol NSFastEnumeration +@end +@protocol NSSecureCoding <NSCoding> +@required ++ (BOOL)supportsSecureCoding; +@end +@interface NSObject <NSObject> {} +- (id)init; ++ (id)alloc; +@end +@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration> + +- (NSUInteger)count; +- (id)objectAtIndex:(NSUInteger)index; + +@end + +@interface NSArray (NSExtendedArray) +- (NSArray *)arrayByAddingObject:(id)anObject; +- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx __attribute__((availability(macosx,introduced=10.8))); +@end + +@interface NSMutableArray : NSArray + +- (void)addObject:(id)anObject; +- (void)insertObject:(id)anObject atIndex:(NSUInteger)index; +- (void)removeLastObject; +- (void)removeObjectAtIndex:(NSUInteger)index; +- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject; + +@end + +@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration> + +- (NSUInteger)count; +- (id)objectForKey:(id)aKey; +- (NSEnumerator *)keyEnumerator; + +@end + +@interface NSDictionary (NSDictionaryCreation) + ++ (id)dictionary; ++ (id)dictionaryWithObject:(id)object forKey:(id <NSCopying>)key; +@end + +@interface NSMutableDictionary : NSDictionary + +- (void)removeObjectForKey:(id)aKey; +- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey; + +@end + +@interface NSMutableDictionary (NSExtendedMutableDictionary) + +- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary; +- (void)removeAllObjects; +- (void)removeObjectsForKeys:(NSArray *)keyArray; +- (void)setDictionary:(NSDictionary *)otherDictionary; +- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key __attribute__((availability(macosx,introduced=10.8))); + +@end + +@interface NSString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding> + +@end + +// NSMutableArray API +void testNilArgNSMutableArray1() { + NSMutableArray *marray = [[NSMutableArray alloc] init]; + [marray addObject:0]; // expected-warning {{Argument to 'NSMutableArray' method 'addObject:' cannot be nil}} +} + +void testNilArgNSMutableArray2() { + NSMutableArray *marray = [[NSMutableArray alloc] init]; + [marray insertObject:0 atIndex:1]; // expected-warning {{Argument to 'NSMutableArray' method 'insertObject:atIndex:' cannot be nil}} +} + +void testNilArgNSMutableArray3() { + NSMutableArray *marray = [[NSMutableArray alloc] init]; + [marray replaceObjectAtIndex:1 withObject:0]; // expected-warning {{Argument to 'NSMutableArray' method 'replaceObjectAtIndex:withObject:' cannot be nil}} +} + +void testNilArgNSMutableArray4() { + NSMutableArray *marray = [[NSMutableArray alloc] init]; + [marray setObject:0 atIndexedSubscript:1]; // expected-warning {{Argument to 'NSMutableArray' method 'setObject:atIndexedSubscript:' cannot be nil}} +} + +void testNilArgNSMutableArray5() { + NSMutableArray *marray = [[NSMutableArray alloc] init]; + marray[1] = 0; // expected-warning {{Array element cannot be nil}} +} + +// NSArray API +void testNilArgNSArray1() { + NSArray *array = [[NSArray alloc] init]; + NSArray *copyArray = [array arrayByAddingObject:0]; // expected-warning {{Argument to 'NSArray' method 'arrayByAddingObject:' cannot be nil}} +} + +// NSMutableDictionary and NSDictionary APIs. +void testNilArgNSMutableDictionary1(NSMutableDictionary *d, NSString* key) { + [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 {{Key argument to 'setObject:forKey:' cannot be nil}} +} + +void testNilArgNSMutableDictionary3(NSMutableDictionary *d) { + [d removeObjectForKey:0]; // expected-warning {{Value argument to 'removeObjectForKey:' cannot be nil}} +} + +void testNilArgNSMutableDictionary5(NSMutableDictionary *d, NSString* key) { + 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 {{'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 {{Value argument to 'dictionaryWithObject:forKey:' cannot be nil}} +} +NSDictionary *testNilArgNSDictionary2(NSObject *obj) { + return [NSDictionary dictionaryWithObject:obj forKey:0]; // expected-warning {{Key argument to 'dictionaryWithObject:forKey:' cannot be nil}} +} + +// Test inline defensive checks suppression. +void idc(id x) { + if (x) + ; +} +void testIDC(NSMutableDictionary *d, NSString *key) { + idc(key); + d[key] = @"abc"; // no-warning +} + +@interface Foo { +@public + int x; +} +- (int *)getPtr; +- (int)getInt; +- (NSMutableDictionary *)getDictPtr; +@property (retain, readonly, nonatomic) Foo* data; +- (NSString*) stringForKeyFE: (id<NSCopying>)key; +@end + +void idc2(id x) { + if (!x) + return; +} +Foo *retNil() { + return 0; +} + +void testIDC2(Foo *obj) { + idc2(obj); + *[obj getPtr] = 1; // no-warning +} + +int testIDC3(Foo *obj) { + idc2(obj); + return 1/[obj getInt]; +} + +void testNilReceiverIDC(Foo *obj, NSString *key) { + NSMutableDictionary *D = [obj getDictPtr]; + idc(D); + D[key] = @"abc"; // no-warning +} + +void testNilReceiverRetNil2(NSMutableDictionary *D, Foo *FooPtrIn, id value) { + NSString* const kKeyIdentifier = @"key"; + Foo *FooPtr = retNil(); + NSString *key = [[FooPtr data] stringForKeyFE: kKeyIdentifier]; + // key is nil because FooPtr is nil. However, FooPtr is set to nil inside an + // inlined function, so this error report should be suppressed. + [D setObject: value forKey: key]; // no-warning +} + + diff --git a/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp new file mode 100644 index 0000000000..b606f23ec8 --- /dev/null +++ b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp @@ -0,0 +1,29 @@ +// 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; +void *malloc(size_t); +void free(void *); + +//------------------------------------------------------------------ +// Check that alpha.cplusplus.NewDelete + unix.MismatchedDeallocator +// does not enable warnings produced by the unix.Malloc checker. +//------------------------------------------------------------------ +void testMallocFreeNoWarn() { + int i; + free(&i); // no warn + + int *p1 = (int *)malloc(sizeof(int)); + free(++p1); // no warn + + int *p2 = (int *)malloc(sizeof(int)); + free(p2); + free(p2); // no warn + + int *p3 = (int *)malloc(sizeof(int)); // no warn + + int *p4 = (int *)malloc(sizeof(int)); + free(p4); + int j = *p4; // no warn +} diff --git a/test/Analysis/NewDelete-checker-test.cpp b/test/Analysis/NewDelete-checker-test.cpp new file mode 100644 index 0000000000..5d134bc36e --- /dev/null +++ b/test/Analysis/NewDelete-checker-test.cpp @@ -0,0 +1,208 @@ +// 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; +extern "C" void *malloc(size_t); +int *global; + +//------------------ +// check for leaks +//------------------ + +//----- Standard non-placement operators +void testGlobalOpNew() { + void *p = operator new(0); +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif + +void testGlobalOpNewArray() { + void *p = operator new[](0); +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif + +void testGlobalNewExpr() { + int *p = new int; +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif + +void testGlobalNewExprArray() { + int *p = new int[0]; +} +#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); +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif + +void testGlobalNoThrowPlacementExprNewBeforeOverload() { + int *p = new(std::nothrow) int; +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif + +//----- Standard pointer placement operators +void testGlobalPointerPlacementNew() { + int i; + + void *p1 = operator new(0, &i); // no warn + + void *p2 = operator new[](0, &i); // no warn + + int *p3 = new(&i) int; // no warn + + int *p4 = new(&i) int[0]; // no warn +} + +//----- Other cases +void testNewMemoryIsInHeap() { + int *p = new int; + if (global != p) // condition is always true as 'p' wraps a heap region that + // is different from a region wrapped by 'global' + global = p; // pointer escapes +} + +struct PtrWrapper { + int *x; + + PtrWrapper(int *input) : x(input) {} +}; + +void testNewInvalidationPlacement(PtrWrapper *w) { + // Ensure that we don't consider this a leak. + new (w) PtrWrapper(new int); // no warn +} + +//--------------- +// other checks +//--------------- + +class SomeClass { +public: + void f(int *p); +}; + +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}} +} + +void testDoubleDelete() { + int *p = new int; + delete p; + delete p; // expected-warning{{Attempt to free released memory}} +} + +void testExprDeleteArg() { + int i; + delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}} +} + +void testExprDeleteArrArg() { + int i; + delete[] &i; // expected-warning{{Argument to 'delete[]' is the address of the local variable 'i', which is not memory allocated by 'new[]'}} +} + +void testAllocDeallocNames() { + int *p = new(std::nothrow) int[1]; + delete[] (++p); // expected-warning{{Argument to 'delete[]' is offset by 4 bytes from the start of memory allocated by 'new[]'}} +} + +//-------------------------------- +// Test escape of newed const pointer. Note, a const pointer can be deleted. +//-------------------------------- +struct StWithConstPtr { + const int *memp; +}; +void escape(const int &x); +void escapeStruct(const StWithConstPtr &x); +void escapePtr(const StWithConstPtr *x); +void escapeVoidPtr(const void *x); + +void testConstEscape() { + int *p = new int(1); + escape(*p); +} // no-warning + +void testConstEscapeStruct() { + StWithConstPtr *St = new StWithConstPtr(); + escapeStruct(*St); +} // no-warning + +void testConstEscapeStructPtr() { + StWithConstPtr *St = new StWithConstPtr(); + escapePtr(St); +} // no-warning + +void testConstEscapeMember() { + StWithConstPtr St; + St.memp = new int(2); + escapeVoidPtr(St.memp); +} // no-warning + +void testConstEscapePlacementNew() { + int *x = (int *)malloc(sizeof(int)); + void *y = new (x) int; + escapeVoidPtr(y); +} // no-warning diff --git a/test/Analysis/NewDelete-custom.cpp b/test/Analysis/NewDelete-custom.cpp new file mode 100644 index 0000000000..c64bfce2de --- /dev/null +++ b/test/Analysis/NewDelete-custom.cpp @@ -0,0 +1,80 @@ +// 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); } +void *operator new(std::size_t size) throw() { return allocator(size); } +void *operator new(std::size_t size, std::nothrow_t& nothrow) throw() { return allocator(size); } +void *operator new(std::size_t, double d); + +class C { +public: + void *operator new(std::size_t); +}; + +void testNewMethod() { + void *p1 = C::operator new(0); // no warn + + C *p2 = new C; // no warn + + C *c3 = ::new C; +} +#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 +} + +void testNewExprArray() { + int *p = new int[0]; +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif + + +//----- Custom non-placement operators +void testOpNew() { + void *p = operator new(0); // call is inlined, no warn +} + +void testNewExpr() { + int *p = new int; +} +#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); +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif + +void testNewExprNoThrow() { + int *p = new(std::nothrow) int; +} +#ifdef LEAKS +// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} +#endif + +//----- Custom placement operators +void testOpNewPlacement() { + void *p = operator new(0, 0.1); // no warn +} + +void testNewExprPlacement() { + int *p = new(0.1) int; // no warn +} diff --git a/test/Analysis/NewDelete-intersections.mm b/test/Analysis/NewDelete-intersections.mm new file mode 100644 index 0000000000..9024ed5766 --- /dev/null +++ b/test/Analysis/NewDelete-intersections.mm @@ -0,0 +1,74 @@ +// 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" + +typedef __typeof__(sizeof(int)) size_t; +extern "C" void *malloc(size_t); +extern "C" void free(void *); + +//---------------------------------------------------------------------------- +// Check for intersections with unix.Malloc and unix.MallocWithAnnotations +// checkers bounded with cplusplus.NewDelete. +//---------------------------------------------------------------------------- + +//----- malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations +void testMallocFreeNoWarn() { + int i; + free(&i); // no warn + + int *p1 = (int *)malloc(sizeof(int)); + free(++p1); // no warn + + int *p2 = (int *)malloc(sizeof(int)); + free(p2); + free(p2); // no warn + + int *p3 = (int *)malloc(sizeof(int)); // no warn + + int *p4 = (int *)malloc(sizeof(int)); + free(p4); + int j = *p4; // no warn +} + +void testDeleteMalloced() { + int *p = (int *)malloc(sizeof(int)); + delete p; // no warn +} + +//----- Test free standard new +void testFreeOpNew() { + void *p = operator new(0); + free(p); +} +#ifdef LEAKS +// expected-warning@-2 {{Potential leak of memory pointed to by 'p'}} +#endif + +void testFreeNewExpr() { + int *p = new int; + free(p); +} +#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]; +#ifdef LEAKS + // expected-warning@-2 {{Potential leak of memory pointed to by 'p'}} +#endif +} + +void testFreeAfterDelete() { + int *p = new int; + delete p; + free(p); // expected-warning{{Use of memory after it is freed}} +} + +void testStandardPlacementNewAfterDelete() { + int *p = new int; + delete p; + p = new(p) int; // expected-warning{{Use of memory after it is freed}} +} diff --git a/test/Analysis/NewDelete-path-notes.cpp b/test/Analysis/NewDelete-path-notes.cpp new file mode 100644 index 0000000000..85b71be68c --- /dev/null +++ b/test/Analysis/NewDelete-path-notes.cpp @@ -0,0 +1,551 @@ +// 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() { + int *p = new int; + // expected-note@-1 {{Memory is allocated}} + if (p) + // expected-note@-1 {{Assuming 'p' is non-null}} + // expected-note@-2 {{Taking true branch}} + delete p; + // expected-note@-1 {{Memory is released}} + + delete p; // expected-warning {{Attempt to free released memory}} + // 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: <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>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: <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> +// 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>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: </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>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: <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>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: </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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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> diff --git a/test/Analysis/NewDelete-variadic.cpp b/test/Analysis/NewDelete-variadic.cpp new file mode 100644 index 0000000000..53dba463bb --- /dev/null +++ b/test/Analysis/NewDelete-variadic.cpp @@ -0,0 +1,19 @@ +// 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 { + typedef __typeof__(sizeof(int)) size_t; +} + +void *operator new(std::size_t, ...); +void *operator new[](std::size_t, ...); + +void testGlobalCustomVariadicNew() { + void *p1 = operator new(0); // no warn + + void *p2 = operator new[](0); // no warn + + int *p3 = new int; // no warn + + int *p4 = new int[0]; // no warn +} diff --git a/test/Analysis/PR3991.m b/test/Analysis/PR3991.m index 4d76fd347e..5f0919d6f0 100644 --- a/test/Analysis/PR3991.m +++ b/test/Analysis/PR3991.m @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 -Wno-incomplete-implementation %s +// expected-no-diagnostics //===----------------------------------------------------------------------===// // Delta-debugging produced forward declarations. @@ -32,16 +33,16 @@ typedef struct _NSZone NSZone; @protocol IHGoogleDocsAdapterDelegate - (void)googleDocsAdapter:(IHGoogleDocsAdapter*)inGoogleDocsAdapter accountVerifyIsValid:(BOOL)inIsValid error:(NSError *)inError; @end @interface IHGoogleDocsAdapter : NSObject { } -- (NSArray *)entries; // expected-note {{method definition for 'entries' not found}} +- (NSArray *)entries; @end extern Class const kGDataUseRegisteredClass ; -@interface IHGoogleDocsAdapter () - (GDataFeedDocList *)feedDocList; // expected-note {{method definition for 'feedDocList' not found}} -- (NSArray *)directoryPathComponents; // expected-note {{method definition for 'directoryPathComponents' not found}} -- (unsigned int)currentPathComponentIndex; // expected-note {{method definition for 'currentPathComponentIndex' not found}} -- (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex; // expected-note {{method definition for 'setCurrentPathComponentIndex:' not found}} -- (NSURL *)folderFeedURL; // expected-note {{method definition for 'folderFeedURL' not found}} +@interface IHGoogleDocsAdapter () - (GDataFeedDocList *)feedDocList; +- (NSArray *)directoryPathComponents; +- (unsigned int)currentPathComponentIndex; +- (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex; +- (NSURL *)folderFeedURL; @end -@implementation IHGoogleDocsAdapter - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject <IHGoogleDocsAdapterDelegate> *)owner { // expected-warning {{incomplete implementation}} +@implementation IHGoogleDocsAdapter - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject <IHGoogleDocsAdapterDelegate> *)owner { return 0; } diff --git a/test/Analysis/additive-folding-range-constraints.c b/test/Analysis/additive-folding-range-constraints.c index 7eb55ab1e1..b22eb2a5b3 100644 --- a/test/Analysis/additive-folding-range-constraints.c +++ b/test/Analysis/additive-folding-range-constraints.c @@ -170,3 +170,135 @@ void mixedComparisons9(signed char a) { clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}} clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}} } + + +void mixedSignedness1(int a) { + unsigned max = UINT_MAX; + clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness2(int a) { + unsigned max = UINT_MAX; + clang_analyzer_eval(a <= max); // expected-warning{{TRUE}} + clang_analyzer_eval((a + 2) <= max); // expected-warning{{TRUE}} + clang_analyzer_eval((a + 2U) <= max); // expected-warning{{TRUE}} +} + +void mixedSignedness3(unsigned a) { + int max = INT_MAX; + clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness4(unsigned a) { + int max = INT_MAX; + clang_analyzer_eval(a <= max); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) <= max); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) <= max); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness5(unsigned a) { + int min = INT_MIN; + clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) < min); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness6(unsigned a) { + int min = INT_MIN; + clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness7(unsigned a) { + unsigned min = 0; + clang_analyzer_eval(a < min); // expected-warning{{FALSE}} + clang_analyzer_eval((a + 2) < min); // expected-warning{{FALSE}} + clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}} +} + +void mixedSignedness8(unsigned a) { + unsigned min = 0; + clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness9(unsigned a) { + int min = 0; + clang_analyzer_eval(a < min); // expected-warning{{FALSE}} + clang_analyzer_eval((a + 2) < min); // expected-warning{{FALSE}} + clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}} +} + +void mixedSignedness10(unsigned a) { + int min = 0; + clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness11(int a) { + int min = 0; + clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}} +} + +void mixedSignedness12(int a) { + int min = 0; + clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness13(int a) { + unsigned max = INT_MAX; + clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness14(int a) { + unsigned max = INT_MAX; + clang_analyzer_eval(a <= max); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) <= max); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) <= max); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness15(int a) { + unsigned min = INT_MIN; + clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) < min); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness16(int a) { + unsigned min = INT_MIN; + clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}} + clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness17(int a) { + unsigned max = INT_MAX; + if (a < max) + return; + + clang_analyzer_eval(a < 0); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(a == 0); // expected-warning{{FALSE}} + clang_analyzer_eval(a == INT_MAX); // expected-warning{{UNKNOWN}} +} + +void mixedSignedness18(int a) { + if (a >= 0) + return; + + clang_analyzer_eval(a < 0); // expected-warning{{TRUE}} + clang_analyzer_eval(a == (unsigned)INT_MIN); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(a == UINT_MAX); // expected-warning{{UNKNOWN}} +} diff --git a/test/Analysis/additive-folding.cpp b/test/Analysis/additive-folding.cpp index 33f3b9b251..c2e502623e 100644 --- a/test/Analysis/additive-folding.cpp +++ b/test/Analysis/additive-folding.cpp @@ -184,6 +184,18 @@ void mixedSignedness(int a, unsigned b) { clang_analyzer_eval(b == uMin && b != sMin); // expected-warning{{FALSE}} } +void mixedSignedness2(int a) { + if (a != -1) + return; + clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}} +} + +void mixedSignedness3(unsigned a) { + if (a != UINT_MAX) + return; + clang_analyzer_eval(a == -1); // expected-warning{{TRUE}} +} + void multiplicativeSanityTest(int x) { // At one point we were ignoring the *4 completely -- the constraint manager diff --git a/test/Analysis/analyzer-config.c b/test/Analysis/analyzer-config.c index 7fa299b786..55b1df9ca8 100644 --- a/test/Analysis/analyzer-config.c +++ b/test/Analysis/analyzer-config.c @@ -1,18 +1,22 @@ -// 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() {} void foo() { bar(); } // CHECK: [config] +// CHECK-NEXT: cfg-conditional-static-initializers = true // CHECK-NEXT: cfg-temporary-dtors = false // CHECK-NEXT: faux-bodies = true // 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 = 9 +// CHECK-NEXT: num-entries = 12 + diff --git a/test/Analysis/analyzer-config.cpp b/test/Analysis/analyzer-config.cpp index 59587f6e11..bf18a5eb3e 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() {} @@ -11,17 +11,21 @@ public: }; // CHECK: [config] -// CHECK-NEXT: c++-inlining = constructors +// CHECK-NEXT: c++-container-inlining = false +// CHECK-NEXT: c++-inlining = destructors // CHECK-NEXT: c++-stdlib-inlining = true // CHECK-NEXT: c++-template-inlining = true +// CHECK-NEXT: cfg-conditional-static-initializers = true // CHECK-NEXT: cfg-temporary-dtors = false // CHECK-NEXT: faux-bodies = true // 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 = 12 +// CHECK-NEXT: num-entries = 16 diff --git a/test/Analysis/analyzer-stats.c b/test/Analysis/analyzer-stats.c index 9eeaade793..63073b7e40 100644 --- a/test/Analysis/analyzer-stats.c +++ b/test/Analysis/analyzer-stats.c @@ -2,7 +2,7 @@ int foo(); -int test() { // expected-warning{{Total CFGBlocks}} +int test() { // expected-warning-re{{test -> Total CFGBlocks: [0-9]+ \| Unreachable CFGBlocks: 0 \| Exhausted Block: no \| Empty WorkList: yes}} int a = 1; a = 34 / 12; diff --git a/test/Analysis/bool-assignment.cpp b/test/Analysis/bool-assignment.c index 9361d93aab..0f782fbfd9 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 22f4237adf..0000000000 --- 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/call-invalidation.cpp b/test/Analysis/call-invalidation.cpp new file mode 100644 index 0000000000..54281cc98a --- /dev/null +++ b/test/Analysis/call-invalidation.cpp @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s + +void clang_analyzer_eval(bool); + +void usePointer(int * const *); +void useReference(int * const &); + +void testPointer() { + int x; + int *p; + + p = &x; + x = 42; + clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} + usePointer(&p); + clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} + + p = &x; + x = 42; + clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} + useReference(p); + clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} + + int * const cp1 = &x; + x = 42; + clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} + usePointer(&cp1); + clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} + + int * const cp2 = &x; + x = 42; + clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} + useReference(cp2); + clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} +} + + +struct Wrapper { + int *ptr; +}; + +void useStruct(Wrapper &w); +void useConstStruct(const Wrapper &w); + +void testPointerStruct() { + int x; + Wrapper w; + + w.ptr = &x; + x = 42; + clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} + useStruct(w); + clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} + + w.ptr = &x; + x = 42; + clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} + useConstStruct(w); + clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} +} + + +struct RefWrapper { + int &ref; +}; + +void useStruct(RefWrapper &w); +void useConstStruct(const RefWrapper &w); + +void testReferenceStruct() { + int x; + RefWrapper w = { x }; + + x = 42; + clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} + useStruct(w); + clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} +} + +// FIXME: This test is split into two functions because region invalidation +// does not preserve reference bindings. <rdar://problem/13320347> +void testConstReferenceStruct() { + int x; + RefWrapper w = { x }; + + x = 42; + clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} + useConstStruct(w); + clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} +} + diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c index 087bd978e1..3e2f8077ed 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 c781ddf833..a8af394a26 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 0000000000..5a3c325b91 --- /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 38e84e17ce..9e437d2182 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 bae3d0a164..39c978ab60 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/ctor-inlining.mm b/test/Analysis/ctor-inlining.mm index 1603ff3893..8cdb005968 100644 --- a/test/Analysis/ctor-inlining.mm +++ b/test/Analysis/ctor-inlining.mm @@ -149,6 +149,19 @@ namespace PODUninitialized { : x(Other.x), y(Other.y) // expected-warning {{undefined}} { } + + NonPOD &operator=(const NonPOD &Other) + { + x = Other.x; + y = Other.y; // expected-warning {{undefined}} + return *this; + } + NonPOD &operator=(NonPOD &&Other) + { + x = Other.x; + y = Other.y; // expected-warning {{undefined}} + return *this; + } }; class NonPODWrapper { @@ -166,6 +179,19 @@ namespace PODUninitialized { : x(Other.x), y(Other.y) // expected-warning {{undefined}} { } + + Inner &operator=(const Inner &Other) + { + x = Other.x; // expected-warning {{undefined}} + y = Other.y; + return *this; + } + Inner &operator=(Inner &&Other) + { + x = Other.x; // expected-warning {{undefined}} + y = Other.y; + return *this; + } }; Inner p; @@ -216,4 +242,261 @@ namespace PODUninitialized { w.p.y = 1; NonPODWrapper w2 = move(w); } + + // Not strictly about constructors, but trivial assignment operators should + // essentially work the same way. + namespace AssignmentOperator { + void testPOD() { + POD p; + p.x = 1; + POD p2; + p2 = p; // no-warning + clang_analyzer_eval(p2.x == 1); // expected-warning{{TRUE}} + POD p3; + p3 = move(p); // no-warning + clang_analyzer_eval(p3.x == 1); // expected-warning{{TRUE}} + + PODWrapper w; + w.p.y = 1; + PODWrapper w2; + w2 = w; // no-warning + clang_analyzer_eval(w2.p.y == 1); // expected-warning{{TRUE}} + PODWrapper w3; + w3 = move(w); // no-warning + clang_analyzer_eval(w3.p.y == 1); // expected-warning{{TRUE}} + } + + void testReturnValue() { + POD p; + p.x = 1; + POD p2; + clang_analyzer_eval(&(p2 = p) == &p2); // expected-warning{{TRUE}} + + PODWrapper w; + w.p.y = 1; + PODWrapper w2; + clang_analyzer_eval(&(w2 = w) == &w2); // expected-warning{{TRUE}} + } + + void testNonPOD() { + NonPOD p; + p.x = 1; + NonPOD p2; + p2 = p; + } + + void testNonPODMove() { + NonPOD p; + p.x = 1; + NonPOD p2; + p2 = move(p); + } + + void testNonPODWrapper() { + NonPODWrapper w; + w.p.y = 1; + NonPODWrapper w2; + w2 = w; + } + + void testNonPODWrapperMove() { + NonPODWrapper w; + w.p.y = 1; + NonPODWrapper w2; + w2 = move(w); + } + } } + +namespace ArrayMembers { + struct Primitive { + int values[3]; + }; + + void testPrimitive() { + Primitive a = { { 1, 2, 3 } }; + + clang_analyzer_eval(a.values[0] == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[1] == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[2] == 3); // expected-warning{{TRUE}} + + Primitive b = a; + + clang_analyzer_eval(b.values[0] == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(b.values[1] == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(b.values[2] == 3); // expected-warning{{TRUE}} + + Primitive c; + c = b; + + clang_analyzer_eval(c.values[0] == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(c.values[1] == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(c.values[2] == 3); // expected-warning{{TRUE}} + } + + struct NestedPrimitive { + int values[2][3]; + }; + + void testNestedPrimitive() { + NestedPrimitive a = { { { 0, 0, 0 }, { 1, 2, 3 } } }; + + clang_analyzer_eval(a.values[1][0] == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[1][1] == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[1][2] == 3); // expected-warning{{TRUE}} + + NestedPrimitive b = a; + + clang_analyzer_eval(b.values[1][0] == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(b.values[1][1] == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(b.values[1][2] == 3); // expected-warning{{TRUE}} + + NestedPrimitive c; + c = b; + + clang_analyzer_eval(c.values[1][0] == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(c.values[1][1] == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(c.values[1][2] == 3); // expected-warning{{TRUE}} + } + + struct POD { + IntWrapper values[3]; + }; + + void testPOD() { + POD a = { { { 1 }, { 2 }, { 3 } } }; + + clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}} + + POD b = a; + + clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{TRUE}} + + POD c; + c = b; + + clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{TRUE}} + } + + struct NestedPOD { + IntWrapper values[2][3]; + }; + + void testNestedPOD() { + NestedPOD a = { { { { 0 }, { 0 }, { 0 } }, { { 1 }, { 2 }, { 3 } } } }; + + clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}} + + NestedPOD b = a; + + clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{TRUE}} + + NestedPOD c; + c = b; + + clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{TRUE}} + } + + struct NonPOD { + NonPODIntWrapper values[3]; + }; + + void testNonPOD() { + NonPOD a; + a.values[0].x = 1; + a.values[1].x = 2; + a.values[2].x = 3; + + clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}} + + NonPOD b = a; + + clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{UNKNOWN}} + + NonPOD c; + c = b; + + clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}} + } + + struct NestedNonPOD { + NonPODIntWrapper values[2][3]; + }; + + void testNestedNonPOD() { + NestedNonPOD a; + a.values[0][0].x = 0; + a.values[0][1].x = 0; + a.values[0][2].x = 0; + a.values[1][0].x = 1; + a.values[1][1].x = 2; + a.values[1][2].x = 3; + + clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}} + + NestedNonPOD b = a; + + clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{UNKNOWN}} + + NestedNonPOD c; + c = b; + + clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{UNKNOWN}} + } + + struct NonPODDefaulted { + NonPODIntWrapper values[3]; + + NonPODDefaulted() = default; + NonPODDefaulted(const NonPODDefaulted &) = default; + NonPODDefaulted &operator=(const NonPODDefaulted &) = default; + }; + + void testNonPODDefaulted() { + NonPODDefaulted a; + a.values[0].x = 1; + a.values[1].x = 2; + a.values[2].x = 3; + + clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}} + + NonPODDefaulted b = a; + + clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{UNKNOWN}} + + NonPODDefaulted c; + c = b; + + clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}} + } +}; diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c index 165a12b59b..067a0504f1 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 b846d2c28b..0664189a95 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 94774dd61d..03716de9ff 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/deref-track-symbolic-region.cpp b/test/Analysis/diagnostics/deref-track-symbolic-region.cpp index e166109ef8..6d348415aa 100644 --- a/test/Analysis/diagnostics/deref-track-symbolic-region.cpp +++ b/test/Analysis/diagnostics/deref-track-symbolic-region.cpp @@ -25,4 +25,19 @@ void testRefParam(int *ptr) { extern void use(int &ref); use(ref); // expected-warning{{Forming reference to null pointer}} // expected-note@-1{{Forming reference to null pointer}} +} + +int testRefToNullPtr() { + int *p = 0; // expected-note {{'p' initialized to a null pointer value}} + int *const &p2 = p; // expected-note{{'p2' initialized here}} + int *p3 = p2; // expected-note {{'p3' initialized to a null pointer value}} + return *p3; // expected-warning {{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} + +int testRefToNullPtr2() { + int *p = 0; // expected-note {{'p' initialized to a null pointer value}} + int *const &p2 = p;// expected-note{{'p2' initialized here}} + return *p2; //expected-warning {{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} }
\ No newline at end of file diff --git a/test/Analysis/diagnostics/explicit-suppression.cpp b/test/Analysis/diagnostics/explicit-suppression.cpp new file mode 100644 index 0000000000..57d2d16f89 --- /dev/null +++ b/test/Analysis/diagnostics/explicit-suppression.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=false -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=true -DSUPPRESSED=1 -verify %s + +#ifdef SUPPRESSED +// expected-no-diagnostics +#endif + +#include "../Inputs/system-header-simulator-cxx.h" + +void clang_analyzer_eval(bool); + +void testCopyNull(int *I, int *E) { + std::copy(I, E, (int *)0); +#ifndef SUPPRESSED + // expected-warning@../Inputs/system-header-simulator-cxx.h:80 {{Dereference of null pointer}} +#endif +} diff --git a/test/Analysis/diagnostics/shortest-path-suppression.c b/test/Analysis/diagnostics/shortest-path-suppression.c new file mode 100644 index 0000000000..4f648b986b --- /dev/null +++ b/test/Analysis/diagnostics/shortest-path-suppression.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=true -analyzer-output=text -verify %s +// expected-no-diagnostics + +int *returnNull() { return 0; } +int coin(); + +// Use a float parameter to ensure that the value is unknown. This will create +// a cycle in the generated ExplodedGraph. +void testCycle(float i) { + int *x = returnNull(); + int y; + while (i > 0) { + x = returnNull(); + y = 2; + i -= 1; + } + *x = 1; // no-warning + y += 1; +} diff --git a/test/Analysis/diagnostics/undef-value-param.c b/test/Analysis/diagnostics/undef-value-param.c index 597bf91fa2..5855f507f9 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 d6c8a16795..4de83bfb9c 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/dtor.cpp b/test/Analysis/dtor.cpp index a30823766e..18cd9853f6 100644 --- a/test/Analysis/dtor.cpp +++ b/test/Analysis/dtor.cpp @@ -328,3 +328,76 @@ namespace MultidimensionalArrays { clang_analyzer_eval(j == 42); // expected-warning{{UNKNOWN}} } } + +namespace LifetimeExtension { + struct IntWrapper { + int x; + IntWrapper(int y) : x(y) {} + IntWrapper() { + extern void use(int); + use(x); // no-warning + } + }; + + struct DerivedWrapper : public IntWrapper { + DerivedWrapper(int y) : IntWrapper(y) {} + }; + + DerivedWrapper get() { + return DerivedWrapper(1); + } + + void test() { + const DerivedWrapper &d = get(); // lifetime extended here + } + + + class SaveOnDestruct { + public: + static int lastOutput; + int value; + + SaveOnDestruct(); + ~SaveOnDestruct() { + lastOutput = value; + } + }; + + void testSimple() { + { + const SaveOnDestruct &obj = SaveOnDestruct(); + if (obj.value != 42) + return; + // destructor called here + } + + clang_analyzer_eval(SaveOnDestruct::lastOutput == 42); // expected-warning{{TRUE}} + } + + class VirtualDtorBase { + public: + int value; + virtual ~VirtualDtorBase() {} + }; + + class SaveOnVirtualDestruct : public VirtualDtorBase { + public: + static int lastOutput; + + SaveOnVirtualDestruct(); + virtual ~SaveOnVirtualDestruct() { + lastOutput = value; + } + }; + + void testVirtual() { + { + const VirtualDtorBase &obj = SaveOnVirtualDestruct(); + if (obj.value != 42) + return; + // destructor called here + } + + clang_analyzer_eval(SaveOnVirtualDestruct::lastOutput == 42); // expected-warning{{TRUE}} + } +} diff --git a/test/Analysis/enum.cpp b/test/Analysis/enum.cpp new file mode 100644 index 0000000000..571fa7ba22 --- /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/free.c b/test/Analysis/free.c index 0b283ee5d4..1dfc1082c7 100644 --- a/test/Analysis/free.c +++ b/test/Analysis/free.c @@ -50,7 +50,7 @@ void t10 () { void t11 () { char *p = (char*)__builtin_alloca(2); - free(p); // expected-warning {{Argument to free() was allocated by alloca(), not malloc()}} + free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}} } void t12 () { diff --git a/test/Analysis/global-region-invalidation.c b/test/Analysis/global-region-invalidation.c index 77de9dd326..bff22012c0 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 be337edab1..2369c09d22 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) @@ -11,9 +13,176 @@ id foo(int x) { return p; } -const int &globalInt = 42; +const int &globalIntRef = 42; -void testGlobal() { +void testGlobalRef() { // FIXME: Should be TRUE, but should at least not crash. + clang_analyzer_eval(globalIntRef == 42); // expected-warning{{UNKNOWN}} +} + +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}} + + 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(); + 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 a2dd98a6d0..dcdd23f74b 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 9a8cd7f495..5c42135b04 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 27853dc2aa..909e18017b 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}} } } @@ -288,6 +309,7 @@ namespace OperatorNew { IntWrapper *obj = new IntWrapper(42); // should be TRUE clang_analyzer_eval(obj->value == 42); // expected-warning{{UNKNOWN}} + delete obj; } void testPlacement() { @@ -350,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 new file mode 100644 index 0000000000..73b2957ad6 --- /dev/null +++ b/test/Analysis/inlining/containers.cpp @@ -0,0 +1,241 @@ +// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=false -verify %s +// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=true -DINLINE=1 -verify %s + +#ifndef HEADER + +void clang_analyzer_eval(bool); +void clang_analyzer_checkInlined(bool); + +#define HEADER +#include "containers.cpp" +#undef HEADER + +void test() { + MySet set(0); + + clang_analyzer_eval(set.isEmpty()); +#if INLINE + // expected-warning@-2 {{TRUE}} +#else + // expected-warning@-4 {{UNKNOWN}} +#endif + + clang_analyzer_eval(set.raw_begin() == set.raw_end()); +#if INLINE + // expected-warning@-2 {{TRUE}} +#else + // expected-warning@-4 {{UNKNOWN}} +#endif + + clang_analyzer_eval(set.begin().impl == set.end().impl); +#if INLINE + // expected-warning@-2 {{TRUE}} +#else + // expected-warning@-4 {{UNKNOWN}} +#endif +} + +void testSubclass(MySetSubclass &sub) { + sub.useIterator(sub.begin()); + + MySetSubclass local; +} + +void testWrappers(BeginOnlySet &w1, IteratorStructOnlySet &w2, + IteratorTypedefOnlySet &w3, IteratorUsingOnlySet &w4) { + BeginOnlySet local1; + IteratorStructOnlySet local2; + IteratorTypedefOnlySet local3; + IteratorUsingOnlySet local4; + + clang_analyzer_eval(w1.begin().impl.impl == w1.begin().impl.impl); +#if INLINE + // expected-warning@-2 {{TRUE}} +#else + // expected-warning@-4 {{UNKNOWN}} +#endif + + clang_analyzer_eval(w2.start().impl == w2.start().impl); +#if INLINE + // expected-warning@-2 {{TRUE}} +#else + // expected-warning@-4 {{UNKNOWN}} +#endif + + clang_analyzer_eval(w3.start().impl == w3.start().impl); +#if INLINE + // expected-warning@-2 {{TRUE}} +#else + // expected-warning@-4 {{UNKNOWN}} +#endif + + clang_analyzer_eval(w4.start().impl == w4.start().impl); +#if INLINE + // expected-warning@-2 {{TRUE}} +#else + // expected-warning@-4 {{UNKNOWN}} +#endif +} + + +#else // HEADER + +#include "../Inputs/system-header-simulator-cxx.h" + +class MySet { + int *storage; + unsigned size; +public: + MySet() : storage(0), size(0) { + clang_analyzer_checkInlined(true); +#if INLINE + // expected-warning@-2 {{TRUE}} +#endif + } + + MySet(unsigned n) : storage(new int[n]), size(n) { + clang_analyzer_checkInlined(true); +#if INLINE + // expected-warning@-2 {{TRUE}} +#endif + } + + ~MySet() { delete[] storage; } + + bool isEmpty() { + clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} + return size == 0; + } + + struct iterator { + int *impl; + + iterator(int *p) : impl(p) {} + }; + + iterator begin() { + clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} + return iterator(storage); + } + + iterator end() { + clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} + return iterator(storage+size); + } + + typedef int *raw_iterator; + + raw_iterator raw_begin() { + clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} + return storage; + } + raw_iterator raw_end() { + clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} + return storage + size; + } +}; + +class MySetSubclass : public MySet { +public: + MySetSubclass() { + clang_analyzer_checkInlined(true); +#if INLINE + // expected-warning@-2 {{TRUE}} +#endif + } + + void useIterator(iterator i) { + clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} + } +}; + +class BeginOnlySet { + MySet impl; +public: + struct IterImpl { + MySet::iterator impl; + typedef std::forward_iterator_tag iterator_category; + + IterImpl(MySet::iterator i) : impl(i) { + clang_analyzer_checkInlined(true); +#if INLINE + // expected-warning@-2 {{TRUE}} +#endif + } + }; + + BeginOnlySet() { + clang_analyzer_checkInlined(true); +#if INLINE + // expected-warning@-2 {{TRUE}} +#endif + } + + typedef IterImpl wrapped_iterator; + + wrapped_iterator begin() { + clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} + return IterImpl(impl.begin()); + } +}; + +class IteratorTypedefOnlySet { + MySet impl; +public: + + IteratorTypedefOnlySet() { + clang_analyzer_checkInlined(true); +#if INLINE + // expected-warning@-2 {{TRUE}} +#endif + } + + typedef MySet::iterator iterator; + + iterator start() { + clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} + return impl.begin(); + } +}; + +class IteratorUsingOnlySet { + MySet impl; +public: + + IteratorUsingOnlySet() { + clang_analyzer_checkInlined(true); +#if INLINE + // expected-warning@-2 {{TRUE}} +#endif + } + + using iterator = MySet::iterator; + + iterator start() { + clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} + return impl.begin(); + } +}; + +class IteratorStructOnlySet { + MySet impl; +public: + + IteratorStructOnlySet() { + clang_analyzer_checkInlined(true); +#if INLINE + // expected-warning@-2 {{TRUE}} +#endif + } + + struct iterator { + int *impl; + }; + + iterator start() { + clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} + return iterator{impl.begin().impl}; + } +}; + +#endif // HEADER diff --git a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp index 890e5640ce..d219446fc9 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 f3e7376156..65613658fc 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 3ee9d92b01..05411bbc77 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 bed64f1837..c5c6bb875e 100644 --- a/test/Analysis/inlining/false-positive-suppression.c +++ b/test/Analysis/inlining/false-positive-suppression.c @@ -9,6 +9,8 @@ int *getNull() { return 0; } +int* getPtr(); + int *dynCastToInt(void *ptr) { if (opaquePropertyCheck(ptr)) return (int *)ptr; @@ -141,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) @@ -191,3 +214,77 @@ void testAlwaysReturnNull(void *input) { #endif } +int derefArg(int *p) { + return *p; +#ifndef SUPPRESSED + // expected-warning@-2 {{Dereference of null pointer}} +#endif +} +void ternaryArg(char cond) { + static int x; + derefArg(cond ? &x : getNull()); +} + +int derefArgCast(char *p) { + return *p; +#ifndef SUPPRESSED + // expected-warning@-2 {{Dereference of null pointer}} +#endif +} +void ternaryArgCast(char cond) { + static int x; + derefArgCast((char*)((unsigned)cond ? &x : getNull())); +} + +int derefAssignment(int *p) { + return *p; +#ifndef SUPPRESSED + // expected-warning@-2 {{Dereference of null pointer}} +#endif +} + +void ternaryAssignment(char cond) { + static int x; + int *p = cond ? getNull() : getPtr(); + derefAssignment(p); +} + +int *retNull(char cond) { + static int x; + return cond ? &x : getNull(); +} +int ternaryRetNull(char cond) { + int *p = retNull(cond); + return *p; +#ifndef SUPPRESSED + // expected-warning@-2 {{Dereference of null pointer}} +#endif +} + +// Test suppression of nested conditional operators. +int testConditionalOperatorSuppress(int x) { + return *(x ? getNull() : getPtr()); +#ifndef SUPPRESSED + // expected-warning@-2 {{Dereference of null pointer}} +#endif +} +int testNestedConditionalOperatorSuppress(int x) { + return *(x ? (x ? getNull() : getPtr()) : getPtr()); +#ifndef SUPPRESSED + // expected-warning@-2 {{Dereference of null pointer}} +#endif +} +int testConditionalOperator(int x) { + return *(x ? 0 : getPtr()); // expected-warning {{Dereference of null pointer}} +} +int testNestedConditionalOperator(int x) { + return *(x ? (x ? 0 : getPtr()) : getPtr()); // expected-warning {{Dereference of null pointer}} +} + +int testConditionalOperatorSuppressFloatCond(float x) { + return *(x ? getNull() : getPtr()); +#ifndef SUPPRESSED + // expected-warning@-2 {{Dereference of null pointer}} +#endif +} + diff --git a/test/Analysis/inlining/false-positive-suppression.cpp b/test/Analysis/inlining/false-positive-suppression.cpp index f27c7cf364..bff6907809 100644 --- a/test/Analysis/inlining/false-positive-suppression.cpp +++ b/test/Analysis/inlining/false-positive-suppression.cpp @@ -40,6 +40,11 @@ inline void* operator new(__typeof__(sizeof(int)), void* __p) throw() extern bool coin(); +class SomeClass { +public: + void doSomething(); +}; + namespace References { class Map { int *&getNewBox(); @@ -79,15 +84,10 @@ namespace References { *box = 1; // no-warning int *&box2 = m.getValue(i); - box = 0; - *box = 1; // expected-warning {{Dereference of null pointer}} + box2 = 0; + *box2 = 1; // expected-warning {{Dereference of null pointer}} } - class SomeClass { - public: - void doSomething(); - }; - SomeClass *&getSomeClass() { if (coin()) { extern SomeClass *&opaqueClass(); @@ -125,3 +125,88 @@ namespace References { #endif } } + +class X{ +public: + void get(); +}; + +X *getNull() { + return 0; +} + +void deref1(X *const &p) { + return p->get(); + #ifndef SUPPRESSED + // expected-warning@-2 {{Called C++ object pointer is null}} + #endif +} + +void test1() { + return deref1(getNull()); +} + +void deref2(X *p3) { + p3->get(); + #ifndef SUPPRESSED + // expected-warning@-2 {{Called C++ object pointer is null}} + #endif +} + +void pass2(X *const &p2) { + deref2(p2); +} + +void test2() { + pass2(getNull()); +} + +void deref3(X *const &p2) { + X *p3 = p2; + p3->get(); + #ifndef SUPPRESSED + // expected-warning@-2 {{Called C++ object pointer is null}} + #endif +} + +void test3() { + deref3(getNull()); +} + + +namespace Cleanups { + class NonTrivial { + public: + ~NonTrivial(); + + SomeClass *getNull() { + return 0; + } + }; + + void testImmediate() { + NonTrivial().getNull()->doSomething(); +#ifndef SUPPRESSED + // expected-warning@-2 {{Called C++ object pointer is null}} +#endif + } + + void testAssignment() { + SomeClass *ptr = NonTrivial().getNull(); + ptr->doSomething(); +#ifndef SUPPRESSED + // expected-warning@-2 {{Called C++ object pointer is null}} +#endif + } + + void testArgumentHelper(SomeClass *arg) { + arg->doSomething(); +#ifndef SUPPRESSED + // expected-warning@-2 {{Called C++ object pointer is null}} +#endif + } + + void testArgument() { + testArgumentHelper(NonTrivial().getNull()); + } +} diff --git a/test/Analysis/inlining/false-positive-suppression.m b/test/Analysis/inlining/false-positive-suppression.m new file mode 100644 index 0000000000..53ec138367 --- /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 df3a8f2281..aa7f70030c 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 c77961d03c..b69c535657 100644 --- a/test/Analysis/inlining/inline-defensive-checks.cpp +++ b/test/Analysis/inlining/inline-defensive-checks.cpp @@ -1,6 +1,12 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s // expected-no-diagnostics +extern void __assert_fail (__const char *__assertion, __const char *__file, + unsigned int __line, __const char *__function) +__attribute__ ((__noreturn__)); +#define assert(expr) \ +((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) + class ButterFly { private: ButterFly() { } @@ -29,4 +35,39 @@ class X{ subtest1(); return subtest2(); } -};
\ No newline at end of file +}; + +typedef const int *Ty; +extern +Ty notNullArg(Ty cf) __attribute__((nonnull)); +typedef const void *CFTypeRef; +extern Ty getTyVal(); +inline void radar13224271_callee(Ty def, Ty& result ) { + result = def; + // Clearly indicates that result cannot be 0 if def is not NULL. + assert( (result != 0) || (def == 0) ); +} +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/inline-defensive-checks.m b/test/Analysis/inlining/inline-defensive-checks.m index bafc812486..0404ee6df8 100644 --- a/test/Analysis/inlining/inline-defensive-checks.m +++ b/test/Analysis/inlining/inline-defensive-checks.m @@ -16,7 +16,6 @@ typedef struct objc_object { -(id)retain; @end -// expected-no-diagnostics // Check that inline defensive checks is triggered for null expressions // within CompoundLiteralExpr. typedef union { @@ -44,3 +43,87 @@ dispatch_resume(dispatch_object_t object); dispatch_resume(p); // no warning } @end + +// Test nil receiver suppression. +// We only suppress on nil receiver if the nil value is directly causing the bug. +@interface Foo { +@public + int x; +} +- (Foo *)getFooPtr; +@end + +Foo *retNil() { + return 0; +} + +Foo *retInputOrNil(Foo *p) { + if (p) + return p; + return 0; +} + +void idc(Foo *p) { + if (p) + ; +} + +int testNilReceiver(Foo* fPtr) { + if (fPtr) + ; + // On a path where fPtr is nil, mem should be nil. + Foo *mem = [fPtr getFooPtr]; + return mem->x; // expected-warning {{Access to instance variable 'x' results in a dereference of a null pointer}} +} + +int suppressNilReceiverRetNullCond(Foo* fPtr) { + unsigned zero = 0; + fPtr = retInputOrNil(fPtr); + // On a path where fPtr is nzil, mem should be nil. + Foo *mem = [fPtr getFooPtr]; + return mem->x; +} + +int suppressNilReceiverRetNullCondCast(id fPtr) { + unsigned zero = 0; + fPtr = retInputOrNil(fPtr); + // On a path where fPtr is nzil, mem should be nil. + Foo *mem = ((id)([(Foo*)(fPtr) getFooPtr])); + return mem->x; +} + +int dontSuppressNilReceiverRetNullCond(Foo* fPtr) { + unsigned zero = 0; + fPtr = retInputOrNil(fPtr); + // On a path where fPtr is nil, mem should be nil. + // The warning is not suppressed because the receiver being nil is not + // directly related to the value that triggers the warning. + Foo *mem = [fPtr getFooPtr]; + if (!mem) + return 5/zero; // expected-warning {{Division by zero}} + return 0; +} + +int dontSuppressNilReceiverRetNull(Foo* fPtr) { + unsigned zero = 0; + fPtr = retNil(); + // On a path where fPtr is nil, mem should be nil. + // The warning is not suppressed because the receiver being nil is not + // directly related to the value that triggers the warning. + Foo *mem = [fPtr getFooPtr]; + if (!mem) + return 5/zero; // expected-warning {{Division by zero}} + return 0; +} + +int dontSuppressNilReceiverIDC(Foo* fPtr) { + unsigned zero = 0; + idc(fPtr); + // On a path where fPtr is nil, mem should be nil. + // The warning is not suppressed because the receiver being nil is not + // directly related to the value that triggers the warning. + Foo *mem = [fPtr getFooPtr]; + if (!mem) + return 5/zero; // expected-warning {{Division by zero}} + return 0; +} diff --git a/test/Analysis/inlining/path-notes.c b/test/Analysis/inlining/path-notes.c index b128aabf7e..660988535b 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 6c63e1400c..e0c83cbe32 100644 --- a/test/Analysis/inlining/path-notes.cpp +++ b/test/Analysis/inlining/path-notes.cpp @@ -184,7 +184,6 @@ namespace ReturnZeroNote { } } - int &returnNullReference() { int *x = 0; // expected-note@-1 {{'x' initialized to a null pointer value}} @@ -192,7 +191,79 @@ int &returnNullReference() { // expected-note@-1 {{Returning null reference}} } +struct FooWithInitializer { + int *ptr; + FooWithInitializer(int *p) : ptr(p) { // expected-note {{Null pointer value stored to 'f.ptr'}} + *ptr = 1; // expected-note {{Dereference of null pointer (loaded from field 'ptr')}} + // expected-warning@-1 {{Dereference of null pointer (loaded from field 'ptr')}} + } +}; + +void testPathNoteOnInitializer() { + int *p = 0; // expected-note {{'p' initialized to a null pointer value}} + + FooWithInitializer f(p); // expected-note {{Passing null pointer value via 1st parameter 'p'}} + // 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> @@ -706,11 +777,45 @@ int &returnNullReference() { // 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> @@ -744,7 +849,7 @@ int &returnNullReference() { // 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> @@ -960,11 +1065,45 @@ int &returnNullReference() { // 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> @@ -998,7 +1137,7 @@ int &returnNullReference() { // 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> @@ -1175,11 +1314,45 @@ int &returnNullReference() { // 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> @@ -1211,7 +1384,7 @@ int &returnNullReference() { // 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> @@ -1388,11 +1561,45 @@ int &returnNullReference() { // 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> @@ -1424,7 +1631,7 @@ int &returnNullReference() { // 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> @@ -1635,11 +1842,45 @@ int &returnNullReference() { // 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> @@ -1671,7 +1912,7 @@ int &returnNullReference() { // 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> @@ -1916,11 +2157,45 @@ int &returnNullReference() { // 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> @@ -1954,7 +2229,7 @@ int &returnNullReference() { // 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> @@ -2093,40 +2368,6 @@ int &returnNullReference() { // 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> @@ -2267,11 +2508,45 @@ int &returnNullReference() { // 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> @@ -2305,7 +2580,7 @@ int &returnNullReference() { // 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> @@ -2520,11 +2795,45 @@ int &returnNullReference() { // 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> @@ -2556,7 +2865,7 @@ int &returnNullReference() { // 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> @@ -2726,7 +3035,7 @@ int &returnNullReference() { // 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> @@ -2741,40 +3050,6 @@ int &returnNullReference() { // 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> @@ -2788,12 +3063,12 @@ int &returnNullReference() { // 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> @@ -2805,7 +3080,7 @@ int &returnNullReference() { // 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> @@ -2839,7 +3114,7 @@ int &returnNullReference() { // 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> @@ -3106,7 +3381,7 @@ int &returnNullReference() { // 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> @@ -3121,12 +3396,12 @@ int &returnNullReference() { // 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>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>7</integer> +// CHECK-NEXT: <key>col</key><integer>34</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -3134,12 +3409,12 @@ int &returnNullReference() { // 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>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>34</integer> +// CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -3147,6 +3422,81 @@ int &returnNullReference() { // 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>21</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>180</integer> +// CHECK-NEXT: <key>col</key><integer>19</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>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>Division by zero</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Division by zero</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Division by zero</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Division by zero</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>testRef</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>21</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>188</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>188</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>188</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>'x' initialized to a null pointer value</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>'x' 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> @@ -3154,29 +3504,172 @@ int &returnNullReference() { // 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>line</key><integer>188</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>180</integer> -// CHECK-NEXT: <key>col</key><integer>34</integer> +// CHECK-NEXT: <key>line</key><integer>188</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>180</integer> +// CHECK-NEXT: <key>line</key><integer>190</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>190</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>190</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>190</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>190</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>Returning null reference</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Returning null reference</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Returning null reference</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Returning null reference</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>returnNullReference</string> +// CHECK-NEXT: <key>issue_hash</key><string>3</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>190</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>203</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>203</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>203</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>'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>203</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>203</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>205</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>205</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: </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>205</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>180</integer> +// CHECK-NEXT: <key>line</key><integer>205</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: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>205</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>205</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> @@ -3184,42 +3677,262 @@ int &returnNullReference() { // 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>19</integer> +// CHECK-NEXT: <key>line</key><integer>205</integer> +// CHECK-NEXT: <key>col</key><integer>23</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>180</integer> -// CHECK-NEXT: <key>col</key><integer>19</integer> +// CHECK-NEXT: <key>line</key><integer>205</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>36</integer> +// CHECK-NEXT: <key>line</key><integer>205</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>Division by zero</string> +// CHECK-NEXT: <string>Passing null pointer value via 1st parameter 'p'</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Division by zero</string> +// CHECK-NEXT: <string>Passing null pointer value via 1st parameter '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>205</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>205</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>205</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>205</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: </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>205</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> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>205</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>205</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: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling constructor for 'FooWithInitializer'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling constructor for 'FooWithInitializer'</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>196</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 'testPathNoteOnInitializer'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'testPathNoteOnInitializer'</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>196</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>196</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: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>196</integer> +// CHECK-NEXT: <key>col</key><integer>35</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>196</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: </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>196</integer> +// CHECK-NEXT: <key>col</key><integer>35</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>196</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: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>196</integer> +// CHECK-NEXT: <key>col</key><integer>31</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>196</integer> +// CHECK-NEXT: <key>col</key><integer>33</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>196</integer> +// CHECK-NEXT: <key>col</key><integer>31</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>Null pointer value stored to 'f.ptr'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Null pointer value stored to 'f.ptr'</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>196</integer> +// CHECK-NEXT: <key>col</key><integer>31</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>196</integer> +// CHECK-NEXT: <key>col</key><integer>33</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>197</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>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>197</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>197</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>197</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>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from field 'ptr')</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from field 'ptr')</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Division by zero</string> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from field 'ptr')</string> // CHECK-NEXT: <key>category</key><string>Logic error</string> -// CHECK-NEXT: <key>type</key><string>Division by zero</string> -// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> -// CHECK-NEXT: <key>issue_context</key><string>testRef</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</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>19</integer> +// CHECK-NEXT: <key>line</key><integer>197</integer> +// CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -3230,7 +3943,7 @@ int &returnNullReference() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>189</integer> +// 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> @@ -3238,22 +3951,22 @@ int &returnNullReference() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>189</integer> +// 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>189</integer> -// CHECK-NEXT: <key>col</key><integer>8</integer> +// 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>'x' initialized to a null pointer value</string> +// CHECK-NEXT: <string>'y' initialized here</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>'x' initialized to a null pointer value</string> +// CHECK-NEXT: <string>'y' initialized here</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -3263,12 +3976,12 @@ int &returnNullReference() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>189</integer> +// 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>189</integer> +// 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> @@ -3276,13 +3989,13 @@ int &returnNullReference() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>191</integer> +// 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>191</integer> -// CHECK-NEXT: <key>col</key><integer>8</integer> +// 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> @@ -3293,7 +4006,7 @@ int &returnNullReference() { // 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>line</key><integer>211</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -3301,12 +4014,109 @@ int &returnNullReference() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>191</integer> -// CHECK-NEXT: <key>col</key><integer>10</integer> +// 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>191</integer> +// 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> @@ -3314,21 +4124,622 @@ int &returnNullReference() { // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Returning null reference</string> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'y')</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Returning null reference</string> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'y')</string> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Returning null reference</string> +// 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>Returning null reference</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>returnNullReference</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>191</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// 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 f3a7b6cc0f..74f088a382 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/inlining/stl.cpp b/test/Analysis/inlining/stl.cpp index b09a5126bc..6053daaf3a 100644 --- a/test/Analysis/inlining/stl.cpp +++ b/test/Analysis/inlining/stl.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-stdlib-inlining=false -verify %s -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-stdlib-inlining=true -DINLINE=1 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=false -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=true -DINLINE=1 -verify %s #include "../Inputs/system-header-simulator-cxx.h" diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c index bdd50c6be5..c197df4386 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,22 +54,27 @@ 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 } +void af1_d() { + struct stuff mystuff; + mystuff.somefield = my_malloc(12); +} // 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) { *pp = my_malloc(42); // no-warning @@ -234,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 @@ -253,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() { @@ -262,14 +267,3 @@ void testMultipleFreeAnnotations() { my_freeBoth(p, q); } -// ---------------------------------------------------------------------------- - -// False negatives. - -// Pending on removal of the escaping on assignment to struct fields. -void af1_d() { - struct stuff mystuff; - mystuff.somefield = my_malloc(12); -} // missing warning - - diff --git a/test/Analysis/malloc-interprocedural.c b/test/Analysis/malloc-interprocedural.c index 3c7bab6717..c78cc6c6aa 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 ddd09db6ff..41bb8b5793 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 29f5aa69ca..6071d1d435 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() { @@ -531,6 +531,12 @@ int *testMalloc3() { return y; // no-warning } +void testStructLeak() { + StructWithPtr St; + St.memP = malloc(12); + return; // expected-warning {{Potential leak of memory pointed to by 'St.memP'}} +} + void testElemRegion1() { char *x = (void*)malloc(2); int *ix = (int*)x; @@ -578,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() { @@ -592,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__)); @@ -668,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); @@ -676,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) { @@ -929,6 +935,18 @@ int cmpHeapAllocationToUnknown() { return 0; } +void localArrayTest() { + char *p = (char*)malloc(12); + char *ArrayL[12]; + ArrayL[0] = p; +} // expected-warning {{leak}} + +void localStructTest() { + StructWithPtr St; + StructWithPtr *pSt = &St; + pSt->memP = malloc(12); +} // expected-warning{{Potential leak of memory pointed to by}} + #ifdef __INTPTR_TYPE__ // Test double assignment through integers. typedef __INTPTR_TYPE__ intptr_t; @@ -1045,50 +1063,18 @@ void testPassToSystemHeaderFunctionIndirectly() { fakeSystemHeaderCallInt(p); } // expected-warning {{leak}} -// ---------------------------------------------------------------------------- -// False negatives. - -// TODO: This is another false negative. -void testMallocWithParam(int **p) { - *p = (int*) malloc(sizeof(int)); - *p = 0; -} - -void testMallocWithParam_2(int **p) { - *p = (int*) malloc(sizeof(int)); -} - -// Pending on removal of the escaping on assignment to struct fields. -void testStructLeak() { - StructWithPtr St; - St.memP = malloc(12); - return; // missing warning -} - -void localArrayTest() { - char *p = (char*)malloc(12); - char *ArrayL[12]; - ArrayL[0] = p; -} // missing warning - -void localStructTest() { - StructWithPtr St; - StructWithPtr *pSt = &St; - pSt->memP = malloc(12); -} // missing warning - void testPassConstPointerIndirectlyStruct() { struct HasPtr hp; hp.p = malloc(10); memcmp(&hp, &hp, sizeof(hp)); - return; // missing leak + return; // expected-warning {{Potential leak of memory pointed to by 'hp.p'}} } void testPassToSystemHeaderFunctionIndirectlyStruct() { SomeStruct ss; ss.p = malloc(1); fakeSystemHeaderCall(&ss); -} // missing leak +} // expected-warning {{Potential leak of memory pointed to by 'ss.p'}} int *testOffsetAllocate(size_t size) { int *memoryBlock = (int *)malloc(size + sizeof(int)); @@ -1121,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() { @@ -1174,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() { @@ -1191,3 +1177,26 @@ void testOffsetPassedAsConst() { free(string); // expected-warning {{Argument to free() is offset by 1 byte from the start of memory allocated by malloc()}} } +char **_vectorSegments; +int _nVectorSegments; + +void poolFreeC(void* s) { + free(s); // no-warning +} +void freeMemory() { + while (_nVectorSegments) { + poolFreeC(_vectorSegments[_nVectorSegments++]); + } +} + +// ---------------------------------------------------------------------------- +// False negatives. + +void testMallocWithParam(int **p) { + *p = (int*) malloc(sizeof(int)); + *p = 0; // FIXME: should warn here +} + +void testMallocWithParam_2(int **p) { + *p = (int*) malloc(sizeof(int)); // no-warning +} diff --git a/test/Analysis/malloc.cpp b/test/Analysis/malloc.cpp index a7c365289f..75d06d66c2 100644 --- a/test/Analysis/malloc.cpp +++ b/test/Analysis/malloc.cpp @@ -5,7 +5,7 @@ void *malloc(size_t); void free(void *); void *realloc(void *ptr, size_t size); void *calloc(size_t nmemb, size_t size); - +char *strdup(const char *s); void checkThatMallocCheckerIsRunning() { malloc(4); @@ -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*); @@ -67,3 +73,36 @@ struct X get() { result.a = malloc(4); return result; // no-warning } + +// Ensure that regions accessible through a LazyCompoundVal trigger region escape. +// Malloc checker used to report leaks for the following two test cases. +struct Property { + char* getterName; + Property(char* n) + : getterName(n) {} + +}; +void append(Property x); + +void appendWrapper(char *getterName) { + append(Property(getterName)); +} +void foo(const char* name) { + char* getterName = strdup(name); + appendWrapper(getterName); // no-warning +} + +struct NestedProperty { + Property prop; + NestedProperty(Property p) + : prop(p) {} +}; +void appendNested(NestedProperty x); + +void appendWrapperNested(char *getterName) { + appendNested(NestedProperty(Property(getterName))); +} +void fooNested(const char* name) { + char* getterName = strdup(name); + appendWrapperNested(getterName); // no-warning +}
\ No newline at end of file diff --git a/test/Analysis/malloc.mm b/test/Analysis/malloc.mm index 2f583b45fd..c7fe86bf0b 100644 --- a/test/Analysis/malloc.mm +++ b/test/Analysis/malloc.mm @@ -68,7 +68,7 @@ void testNSStringFreeWhenDoneNO2(NSUInteger dataLength) { void testOffsetFree() { int *p = (int *)malloc(sizeof(int)); - NSData *nsdata = [NSData dataWithBytesNoCopy:++p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}} + NSData *nsdata = [NSData dataWithBytesNoCopy:++p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Argument to +dataWithBytesNoCopy:length:freeWhenDone: is offset by 4 bytes from the start of memory allocated by malloc()}} } void testRelinquished1() { @@ -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/method-arg-decay.m b/test/Analysis/method-arg-decay.m index a36d81e82b..0af9e3e883 100644 --- a/test/Analysis/method-arg-decay.m +++ b/test/Analysis/method-arg-decay.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyzer-checker=core -verify %s +// RUN: %clang_cc1 -analyzer-checker=core -verify %s -Wno-incomplete-implementation typedef signed char BOOL; typedef int NSInteger; typedef unsigned int NSUInteger; @@ -70,9 +70,9 @@ extern NSMutableArray *XCFindPossibleKeyModules(PBXModule *module, BOOL useExpos @interface XCPerspectiveModule : PBXProjectModule <PBXSelectionTarget> { // expected-note {{required for direct or indirect protocol 'PBXSelectionTarget'}} XCExtendedTabView *_perspectivesTabView; } -- (PBXModule *) moduleForTab:(NSTabViewItem *)item; // expected-note {{method definition for 'moduleForTab:' not found}} +- (PBXModule *) moduleForTab:(NSTabViewItem *)item; @end -@implementation XCPerspectiveModule // expected-warning {{incomplete implementation}} expected-warning {{method 'performAction:withSelection:' in protocol not implemented}}} +@implementation XCPerspectiveModule // expected-warning {{method 'performAction:withSelection:' in protocol not implemented}}} + (void) openForProjectDocument:(PBXProjectDocument *)projectDocument { } - (PBXModule *) type:(Class)type inPerspective:(id)perspectiveIdentifer matchingFunction:(BOOL (void *, void *))comparator usingData:(void *)data { diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp index 6fbe441b27..902a5e5271 100644 --- a/test/Analysis/misc-ps-region-store.cpp +++ b/test/Analysis/misc-ps-region-store.cpp @@ -721,3 +721,22 @@ void rdar12964481_b(_ComplexT *y) { *y *= x; // no-warning } +// Test case for PR 12921. This previously produced +// a bogus warning. +static const int pr12921_arr[] = { 0, 1 }; +static const int pr12921_arrcount = sizeof(pr12921_arr)/sizeof(int); + +int pr12921(int argc, char **argv) { + int i, retval; + for (i = 0; i < pr12921_arrcount; i++) { + if (argc == i) { + retval = i; + break; + } + } + + // No match + if (i == pr12921_arrcount) return 66; + return pr12921_arr[retval]; +} + diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index bb22c25998..ba88deca5a 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -920,7 +920,7 @@ int rdar_7770737_pos(void) void pr6302(id x, Class y) { // This previously crashed the analyzer (reported in PR 6302) - x->isa = y; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_setClass() and object_getClass()}} + x->isa = y; // expected-warning {{assignment to Objective-C's isa is deprecated in favor of object_setClass()}} } //===----------------------------------------------------------------------===// diff --git a/test/Analysis/misc-ps.c b/test/Analysis/misc-ps.c index 5369ab1061..b302860a2f 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 fdd16da3dc..8d3eee9baa 100644 --- a/test/Analysis/new.cpp +++ b/test/Analysis/new.cpp @@ -1,11 +1,19 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s +#include "Inputs/system-header-simulator-cxx.h" void clang_analyzer_eval(bool); typedef __typeof__(sizeof(int)) size_t; 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; @@ -19,13 +27,6 @@ void testImplicitlyDeclaredGlobalNew() { clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}} } - -// This is the standard placement new. -inline void* operator new(size_t, void* __p) throw() -{ - return __p; -} - void *testPlacementNew() { int *x = (int *)malloc(sizeof(int)); *x = 1; @@ -73,7 +74,6 @@ void testScalarInitialization() { clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}} } - struct PtrWrapper { int *x; @@ -82,9 +82,93 @@ struct PtrWrapper { PtrWrapper *testNewInvalidation() { // Ensure that we don't consider this a leak. - return new PtrWrapper(static_cast<int *>(malloc(4))); + return new PtrWrapper(static_cast<int *>(malloc(4))); // no-warning +} + +void testNewInvalidationPlacement(PtrWrapper *w) { + // Ensure that we don't consider this a leak. + new (w) PtrWrapper(static_cast<int *>(malloc(4))); // no-warning } +int **testNewInvalidationScalar() { + // Ensure that we don't consider this a leak. + return new (int *)(static_cast<int *>(malloc(4))); // no-warning +} + +void testNewInvalidationScalarPlacement(int **p) { + // Ensure that we don't consider this a leak. + new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning +} + +void testCacheOut(PtrWrapper w) { + extern bool coin(); + if (coin()) + w.x = 0; + 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 +// bounded with unix.Malloc +//-------------------------------------------------------------------- + +// new/delete oparators are subjects of cplusplus.NewDelete. +void testNewDeleteNoWarn() { + int i; + delete &i; // no-warning + + int *p1 = new int; + delete ++p1; // no-warning + + int *p2 = new int; + delete p2; + delete p2; // no-warning + + int *p3 = new int; // no-warning +} + +// unix.Malloc does not know about operators new/delete. +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{{Potential leak of memory pointed to by 'x'}} + +void testDeleteOpAfterFree() { + int *p = (int *)malloc(sizeof(int)); + free(p); + operator delete(p); // expected-warning{{Use of memory after it is freed}} +} + +void testDeleteAfterFree() { + int *p = (int *)malloc(sizeof(int)); + free(p); + delete p; // expected-warning{{Use of memory after it is freed}} +} + +void testStandardPlacementNewAfterFree() { + int *p = (int *)malloc(sizeof(int)); + free(p); + p = new(p) int; // expected-warning{{Use of memory after it is freed}} +} + +void testCustomPlacementNewAfterFree() { + int *p = (int *)malloc(sizeof(int)); + free(p); + 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 @@ -95,8 +179,10 @@ int testNoInitialization() { // Should warn that *n is uninitialized. if (*n) { // no-warning + delete n; return 0; } + delete n; return 1; } diff --git a/test/Analysis/null-deref-path-notes.m b/test/Analysis/null-deref-path-notes.m index 66514544dd..e22d520f88 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 16915788d6..98310b52f4 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 1561ef8ddf..ef149c4b14 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 0000000000..c67ab5e891 --- /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 324bf1c785..ae621c9828 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 a6f5ec3f84..6919feaccf 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 4f686e55fd..7461d75f67 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 bc9e1032fc..93d0421d66 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 d563e88747..3dfd6be2e7 100644 --- a/test/Analysis/plist-output.m +++ b/test/Analysis/plist-output.m @@ -155,6 +155,14 @@ void test_loop_diagnostics_3() { *p = 1; } +void test_loop_fast_enumeration(id arr) { + int x; + for (id obj in arr) { + x = 1; + } + x += 1; +} + @interface RDar12114812 { char *p; } @end @@ -176,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> @@ -232,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> @@ -249,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> @@ -283,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> @@ -375,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> @@ -392,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> @@ -426,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> @@ -581,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> @@ -598,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> @@ -632,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> @@ -737,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> @@ -775,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> @@ -930,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> @@ -947,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> @@ -981,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> @@ -1107,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> @@ -1124,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> @@ -1158,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> @@ -1410,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> @@ -1427,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> @@ -1461,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> @@ -1822,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> @@ -1839,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> @@ -1873,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> @@ -2089,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> @@ -2350,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> @@ -2367,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> @@ -2401,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> @@ -2632,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> @@ -2670,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> @@ -2901,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> @@ -2939,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> @@ -3243,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> @@ -3281,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> @@ -3648,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> @@ -3686,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> @@ -4087,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> @@ -4125,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> @@ -4526,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> @@ -4564,7 +4820,7 @@ int RDar13295437() { // 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: </dict> @@ -4584,11 +4840,57 @@ int RDar13295437() { // 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>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> +// 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>159</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>159</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>159</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -4596,9 +4898,72 @@ int RDar13295437() { // 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 'p'</string> +// CHECK-NEXT: <string>'x' declared without an initial value</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Null pointer value stored to 'p'</string> +// CHECK-NEXT: <string>'x' 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>159</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>159</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>160</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>160</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>160</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>160</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>160</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: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Loop body executed 0 times</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Loop body executed 0 times</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -4608,6 +4973,19 @@ int RDar13295437() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>160</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>160</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>163</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> @@ -4618,19 +4996,40 @@ int RDar13295437() { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> +// 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>164</integer> +// 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>164</integer> +// 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> @@ -4638,7 +5037,53 @@ int RDar13295437() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>164</integer> +// 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: <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>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: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Assigned value is garbage or undefined</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>5</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>171</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -4646,12 +5091,75 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>164</integer> +// CHECK-NEXT: <key>line</key><integer>171</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>171</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>Null pointer value stored to 'p'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Null pointer value stored to '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>171</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>171</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>172</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>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>172</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>172</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>164</integer> +// CHECK-NEXT: <key>line</key><integer>172</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -4672,8 +5180,8 @@ int RDar13295437() { // CHECK-NEXT: <key>issue_hash</key><string>2</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>164</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>line</key><integer>172</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> @@ -4684,7 +5192,7 @@ int RDar13295437() { // 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>line</key><integer>182</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -4692,12 +5200,12 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>174</integer> +// CHECK-NEXT: <key>line</key><integer>182</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>174</integer> +// CHECK-NEXT: <key>line</key><integer>182</integer> // CHECK-NEXT: <key>col</key><integer>25</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -4717,12 +5225,12 @@ int RDar13295437() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>174</integer> +// CHECK-NEXT: <key>line</key><integer>182</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>174</integer> +// CHECK-NEXT: <key>line</key><integer>182</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -4730,12 +5238,12 @@ int RDar13295437() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>176</integer> +// CHECK-NEXT: <key>line</key><integer>184</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>176</integer> +// CHECK-NEXT: <key>line</key><integer>184</integer> // CHECK-NEXT: <key>col</key><integer>16</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -4747,7 +5255,7 @@ int RDar13295437() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>176</integer> +// CHECK-NEXT: <key>line</key><integer>184</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -4755,12 +5263,12 @@ int RDar13295437() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>176</integer> +// CHECK-NEXT: <key>line</key><integer>184</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>176</integer> +// CHECK-NEXT: <key>line</key><integer>184</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -4781,9 +5289,249 @@ int RDar13295437() { // CHECK-NEXT: <key>issue_hash</key><string>3</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>176</integer> +// CHECK-NEXT: <key>line</key><integer>184</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>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 84dfe30646..c9150e8ca5 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/pr4209.m b/test/Analysis/pr4209.m index a5e7db51dc..29abe94441 100644 --- a/test/Analysis/pr4209.m +++ b/test/Analysis/pr4209.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple i386-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 -Wno-incomplete-implementation -verify %s // This test case was crashing due to how CFRefCount.cpp resolved the // ObjCInterfaceDecl* and ClassName in EvalObjCMessageExpr. @@ -47,14 +47,14 @@ CMProfileLocation; @interface GBCategoryChooserPanelController : NSWindowController { GSEbayCategory *rootCategory; } -- (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories; // expected-note {{method definition for 'categoryDictionaryForCategoryID:inRootTreeCategories:' not found}} --(NSString*) categoryID; // expected-note {{method definition for 'categoryID' not found}} expected-note {{using}} +- (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories; +-(NSString*) categoryID; // expected-note {{using}} @end @interface GSEbayCategory : NSObject <NSCoding> { } - (int) categoryID; // expected-note {{also found}} - (GSEbayCategory *) parent; - (GSEbayCategory*) subcategoryWithID:(int) inID; -@end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent { // expected-warning {{incomplete implementation}} +@end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent { return 0; } - (void) addCategory:(EBayCategoryType*)inCategory toRootTreeCategory:(NSMutableArray*)inRootTreeCategories { diff --git a/test/Analysis/properties.m b/test/Analysis/properties.m index 4aa91805fd..ddd0068d36 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/ptr-arith.c b/test/Analysis/ptr-arith.c index 9294c1832b..35faff4a17 100644 --- a/test/Analysis/ptr-arith.c +++ b/test/Analysis/ptr-arith.c @@ -167,3 +167,116 @@ void PR7527 (int *p) { if (((int) p) & 1) // not crash return; } + +void use_symbols(int *lhs, int *rhs) { + clang_analyzer_eval(lhs < rhs); // expected-warning{{UNKNOWN}} + if (lhs < rhs) + return; + clang_analyzer_eval(lhs < rhs); // expected-warning{{FALSE}} + + clang_analyzer_eval(lhs - rhs); // expected-warning{{UNKNOWN}} + if ((lhs - rhs) != 5) + return; + clang_analyzer_eval((lhs - rhs) == 5); // expected-warning{{TRUE}} +} + +void equal_implies_zero(int *lhs, int *rhs) { + clang_analyzer_eval(lhs == rhs); // expected-warning{{UNKNOWN}} + if (lhs == rhs) { + clang_analyzer_eval(lhs != rhs); // expected-warning{{FALSE}} + clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{TRUE}} + return; + } + clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}} + clang_analyzer_eval(lhs != rhs); // expected-warning{{TRUE}} + clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}} +} + +void zero_implies_equal(int *lhs, int *rhs) { + clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{UNKNOWN}} + if ((rhs - lhs) == 0) { + clang_analyzer_eval(lhs != rhs); // expected-warning{{FALSE}} + clang_analyzer_eval(lhs == rhs); // expected-warning{{TRUE}} + return; + } + clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}} + clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}} + clang_analyzer_eval(lhs != rhs); // expected-warning{{TRUE}} +} + +void comparisons_imply_size(int *lhs, int *rhs) { + clang_analyzer_eval(lhs <= rhs); // expected-warning{{UNKNOWN}} + + if (lhs > rhs) { + clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}} + return; + } + + clang_analyzer_eval(lhs <= rhs); // expected-warning{{TRUE}} + clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{TRUE}} + clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}} + + if (lhs >= rhs) { + clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{TRUE}} + return; + } + + clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}} + clang_analyzer_eval(lhs < rhs); // expected-warning{{TRUE}} + clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{TRUE}} +} + +void size_implies_comparison(int *lhs, int *rhs) { + clang_analyzer_eval(lhs <= rhs); // expected-warning{{UNKNOWN}} + + if ((rhs - lhs) < 0) { + clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}} + return; + } + + clang_analyzer_eval(lhs <= rhs); // expected-warning{{TRUE}} + clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{TRUE}} + clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}} + + if ((rhs - lhs) <= 0) { + clang_analyzer_eval(lhs == rhs); // expected-warning{{TRUE}} + return; + } + + clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}} + clang_analyzer_eval(lhs < rhs); // expected-warning{{TRUE}} + clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{TRUE}} +} + +//------------------------------- +// False positives +//------------------------------- + +void zero_implies_reversed_equal(int *lhs, int *rhs) { + clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{UNKNOWN}} + if ((rhs - lhs) == 0) { + // FIXME: Should be FALSE. + clang_analyzer_eval(rhs != lhs); // expected-warning{{UNKNOWN}} + // FIXME: Should be TRUE. + clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}} + return; + } + clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}} + // FIXME: Should be FALSE. + clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}} + // FIXME: Should be TRUE. + clang_analyzer_eval(rhs != lhs); // expected-warning{{UNKNOWN}} +} + +void canonical_equal(int *lhs, int *rhs) { + clang_analyzer_eval(lhs == rhs); // expected-warning{{UNKNOWN}} + if (lhs == rhs) { + // FIXME: Should be TRUE. + clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}} + return; + } + clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}} + + // FIXME: Should be FALSE. + clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}} +} diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp index 8dd0baf8c3..1dabe7bc1a 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/reference.mm b/test/Analysis/reference.mm new file mode 100644 index 0000000000..c5546aac5f --- /dev/null +++ b/test/Analysis/reference.mm @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -Wno-null-dereference %s + +@interface Foo +- (int &)ref; +@end + +Foo *getFoo() { return 0; } + +void testNullPointerSuppression() { + getFoo().ref = 1; +} + +void testPositiveNullReference() { + Foo *x = 0; + x.ref = 1; // expected-warning {{The receiver of message 'ref' is nil, which results in forming a null reference}} +} + diff --git a/test/Analysis/region-store.c b/test/Analysis/region-store.c index d620150085..70bda1117b 100644 --- a/test/Analysis/region-store.c +++ b/test/Analysis/region-store.c @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s -// expected-no-diagnostics +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,debug.ExprInspection -verify %s int printf(const char *restrict,...); @@ -22,3 +21,36 @@ int compoundLiteralTest2() { } return 0; } + +int concreteOffsetBindingIsInvalidatedBySymbolicOffsetAssignment(int length, + int i) { + int values[length]; + values[i] = 4; + return values[0]; // no-warning +} + +struct X{ + int mem; +}; +int initStruct(struct X *st); +int structOffsetBindingIsInvalidated(int length, int i){ + struct X l; + initStruct(&l); + return l.mem; // no-warning +} + +void clang_analyzer_eval(int); +void testConstraintOnRegionOffset(int *values, int length, int i){ + if (values[1] == 4) { + values[i] = 5; + clang_analyzer_eval(values[1] == 4);// expected-warning {{UNKNOWN}} + } +} + +int initArray(int *values); +void testConstraintOnRegionOffsetStack(int *values, int length, int i) { + if (values[0] == 4) { + initArray(values); + clang_analyzer_eval(values[0] == 4);// expected-warning {{UNKNOWN}} + } +} diff --git a/test/Analysis/region-store.cpp b/test/Analysis/region-store.cpp new file mode 100644 index 0000000000..5ea5c3f82f --- /dev/null +++ b/test/Analysis/region-store.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s +// expected-no-diagnostics + +class Loc { + int x; +}; +class P1 { +public: + Loc l; + void setLoc(Loc L) { + l = L; + } + +}; +class P2 { +public: + int m; + int accessBase() { + return m; + } +}; +class Derived: public P1, public P2 { +}; +int radar13445834(Derived *Builder, Loc l) { + Builder->setLoc(l); + return Builder->accessBase(); + +}
\ No newline at end of file diff --git a/test/Analysis/retain-release-inline.m b/test/Analysis/retain-release-inline.m index 6ff9e9a552..8809c8c844 100644 --- a/test/Analysis/retain-release-inline.m +++ b/test/Analysis/retain-release-inline.m @@ -361,3 +361,35 @@ CFStringRef testCovariantReturnType() { } return Str; } + +// Test that we reanalyze ObjC methods which have been inlined. When reanalyzing +// them, make sure we inline very small functions. +id returnInputParam(id x) { + return x; +} + +@interface MyClass : NSObject +- (id)test_reanalyze_as_top_level; +- (void)test_inline_tiny_when_reanalyzing; +- (void)inline_test_reanalyze_as_top_level; +@end + +@implementation MyClass +- (void)test_inline_tiny_when_reanalyzing { + id x = [[NSString alloc] init]; // no-warning + x = returnInputParam(x); + [x release]; +} + +- (id)test_reanalyze_as_top_level { + // This method does not follow naming conventions, so a warning will be + // reported when it is reanalyzed at top level. + return [[NSString alloc] init]; // expected-warning {{leak}} +} + +- (void)inline_test_reanalyze_as_top_level { + id x = [self test_reanalyze_as_top_level]; + [x release]; + [self test_inline_tiny_when_reanalyzing]; +} +@end diff --git a/test/Analysis/retain-release-path-notes-gc.m b/test/Analysis/retain-release-path-notes-gc.m index 913714e6cd..f74d61fa9a 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 8809c573dc..a3c681ae37 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 9de6cedaf0..bb4a1d169d 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) {} } @@ -1967,6 +1967,60 @@ void test_drain() { [obj release]; // no-warning } +//===----------------------------------------------------------------------===// +// Allow cf_returns_retained and cf_returns_not_retained to mark a return +// value as tracked, even if the object isn't a known CF type. +//===----------------------------------------------------------------------===// + +MyCFType getCustom() __attribute__((cf_returns_not_retained)); +MyCFType makeCustom() __attribute__((cf_returns_retained)); + +void testCustomReturnsRetained() { + MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}} +} + +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> @@ -8895,9 +8949,9 @@ void test_drain() { // 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> @@ -8970,9 +9024,9 @@ void test_drain() { // 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> @@ -9018,14 +9072,14 @@ void test_drain() { // 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> @@ -9173,9 +9227,9 @@ void test_drain() { // 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> @@ -9248,9 +9302,9 @@ void test_drain() { // 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> @@ -9311,14 +9365,14 @@ void test_drain() { // 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> @@ -9466,9 +9520,9 @@ void test_drain() { // 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> @@ -9541,9 +9595,9 @@ void test_drain() { // 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> @@ -9638,14 +9692,14 @@ void test_drain() { // 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> @@ -13571,9 +13625,9 @@ void test_drain() { // 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> @@ -20093,9 +20147,9 @@ void test_drain() { // 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 d92237b185..3650d88724 100644 --- a/test/Analysis/retain-release.mm +++ b/test/Analysis/retain-release.mm @@ -64,6 +64,8 @@ extern const CFArrayCallBacks kCFTypeArrayCallBacks; typedef const struct __CFArray * CFArrayRef; typedef struct __CFArray * CFMutableArrayRef; extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); +void abort(void) __attribute__((noreturn)); +CFArrayRef CFArrayCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFArrayCallBacks *callBacks); extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); typedef struct { @@ -81,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); @@ -267,7 +270,6 @@ extern void CGContextDrawLinearGradient(CGContextRef context, CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, CGGradientDrawingOptions options); extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); - //===----------------------------------------------------------------------===// // Test cases. //===----------------------------------------------------------------------===// @@ -385,3 +387,77 @@ void testCallback() { val >> process; } +//===----------------------------------------------------------------------===// +// Test handling static initializers. +//===----------------------------------------------------------------------===// + +@interface radar13227740 : NSObject +@end + +@implementation radar13227740 +- (CFArrayRef)test { + static CFArrayRef array = ::CFArrayCreate(0, 0, 0, 0); + do { if (!((0 != array)/1)) { abort(); } } while (false); + return array; +} + +// Previously this reported a bogus leak. +- (void)test2 { + (void)[self test]; + (void)[self test]; +} +@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/simple-stream-checks.c b/test/Analysis/simple-stream-checks.c index 1fb6de3ec1..ce57fa7ac3 100644 --- a/test/Analysis/simple-stream-checks.c +++ b/test/Analysis/simple-stream-checks.c @@ -88,4 +88,4 @@ void testPassToSystemHeaderFunctionIndirectly() { FileStruct fs; fs.p = fopen("myfile.txt", "w"); fakeSystemHeaderCall(&fs); -} // expected leak warning +} // expected-warning {{Opened file is never closed; potential resource leak}} diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp index 7aefea5095..65d757154c 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 10564faff3..4f81f6623e 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 fd836c471b..6cf52f7a55 100644 --- a/test/Analysis/string.c +++ b/test/Analysis/string.c @@ -279,12 +279,16 @@ void strcpy_fn_const(char *x) { strcpy(x, (const char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} } +extern int globalInt; void strcpy_effects(char *x, char *y) { char a = x[0]; + if (globalInt != 42) + return; clang_analyzer_eval(strcpy(x, y) == x); // expected-warning{{TRUE}} clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}} clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}} } void strcpy_overflow(char *y) { @@ -410,12 +414,6 @@ void strcat_symbolic_dst_length(char *dst) { clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} } -void strcat_symbolic_src_length(char *src) { - char dst[8] = "1234"; - strcat(dst, src); - clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} -} - void strcat_symbolic_dst_length_taint(char *dst) { scanf("%s", dst); // Taint data. strcat(dst, "1234"); @@ -521,17 +519,6 @@ void strncpy_exactly_matching_buffer(char *y) { clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}} } -void strncpy_exactly_matching_buffer2(char *y) { - if (strlen(y) >= 4) - return; - - char x[4]; - strncpy(x, y, 4); // no-warning - - // This time, we know that y fits in x anyway. - clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{TRUE}} -} - void strncpy_zero(char *src) { char dst[] = "123"; strncpy(dst, src, 0); // no-warning @@ -1039,3 +1026,81 @@ void strncasecmp_diff_length_6() { void strncasecmp_embedded_null () { clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}} } + +//===----------------------------------------------------------------------=== +// 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 +//===----------------------------------------------------------------------=== + +// The analyzer_eval call below should evaluate to true. We are being too +// aggressive in marking the (length of) src symbol dead. The length of dst +// depends on src. This could be explicitely specified in the checker or the +// logic for handling MetadataSymbol in SymbolManager needs to change. +void strcat_symbolic_src_length(char *src) { + char dst[8] = "1234"; + strcat(dst, src); + clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}} +} + +// The analyzer_eval call below should evaluate to true. Most likely the same +// issue as the test above. +void strncpy_exactly_matching_buffer2(char *y) { + if (strlen(y) >= 4) + return; + + char x[4]; + strncpy(x, y, 4); // no-warning + + // This time, we know that y fits in x anyway. + clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}} +} diff --git a/test/Analysis/svalbuilder-logic.c b/test/Analysis/svalbuilder-logic.c index 41d4fe21c2..9cf3f964bc 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-generic.c b/test/Analysis/taint-generic.c index 696db67713..fe27070026 100644 --- a/test/Analysis/taint-generic.c +++ b/test/Analysis/taint-generic.c @@ -212,3 +212,14 @@ int SymSymExprWithDiffTypes(void* p) { return 5/j; // expected-warning {{Division by a tainted value, possibly zero}} } + +void constraintManagerShouldTreatAsOpaque(int rhs) { + int i; + scanf("%d", &i); + // This comparison used to hit an assertion in the constraint manager, + // which didn't handle NonLoc sym-sym comparisons. + if (i < rhs) + return; + if (i < rhs) + *(volatile int *) 0; // no-warning +} diff --git a/test/Analysis/taint-tester.c b/test/Analysis/taint-tester.c index 7b0ab2a5fd..6287198eda 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 32a4d3bef4..efc0825470 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 09736ef1e3..ad40b15502 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 6813b8ebf8..72b6739800 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; } @@ -73,22 +75,68 @@ void PR14765_test() { free(testObj); } -void PR14765_incorrectBehavior(Circle *testObj) { +void PR14765_argument(Circle *testObj) { int oldSize = testObj->size; - clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}} testObj->origin = makePoint(0.0, 0.0); + clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}} +} + + +typedef struct { + int x; + int y; + int z; +} IntPoint; +typedef struct { + IntPoint origin; + int size; +} IntCircle; + +IntPoint makeIntPoint(int x, int y) { + IntPoint result; + result.x = x; + result.y = y; + result.z = 0; + return result; +} + +void PR14765_test_int() { + IntCircle *testObj = calloc(sizeof(IntCircle), 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}} + clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}} + + testObj->origin = makeIntPoint(1, 2); + if (testObj->size > 0) { ; } // warning occurs here // FIXME: Assigning to 'testObj->origin' kills the default binding for the // whole region, meaning that we've forgotten that testObj->size should also // default to 0. Tracked by <rdar://problem/12701038>. // This should be TRUE. - clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{UNKNOWN}} + 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); } +void PR14765_argument_int(IntCircle *testObj) { + int oldSize = testObj->size; + clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}} + + testObj->origin = makeIntPoint(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}} + clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}} +} + + void rdar13292559(Circle input) { extern void useCircle(Circle); @@ -100,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 cfd5d14e8a..46c10136ed 100644 --- a/test/Analysis/unix-fns.c +++ b/test/Analysis/unix-fns.c @@ -552,7 +552,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: <key>description</key><string>Call to 'dispatch_once' uses the local variable 'pred' for the predicate value. Using such transient memory for the predicate is potentially dangerous. Perhaps you intended to declare the variable as 'static'?</string> -// CHECK-NEXT: <key>category</key><string>Mac OS X API</string> +// CHECK-NEXT: <key>category</key><string>API Misuse (Apple)</string> // CHECK-NEXT: <key>type</key><string>Improper use of 'dispatch_once'</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>test_dispatch_once</string> @@ -1352,7 +1352,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: <key>description</key><string>Call to 'dispatch_once' uses the local variable 'pred' for the predicate value. Using such transient memory for the predicate is potentially dangerous. Perhaps you intended to declare the variable as 'static'?</string> -// CHECK-NEXT: <key>category</key><string>Mac OS X API</string> +// CHECK-NEXT: <key>category</key><string>API Misuse (Apple)</string> // CHECK-NEXT: <key>type</key><string>Improper use of 'dispatch_once'</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>test_dispatch_once_in_macro</string> @@ -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/CMakeLists.txt b/test/CMakeLists.txt index 8da2ba4ab4..a11b83a854 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -29,7 +29,7 @@ endif () set(CLANG_TEST_DEPS clang clang-headers c-index-test diagtool arcmt-test c-arcmt-test - clang-check + clang-check clang-format ) set(CLANG_TEST_PARAMS clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg @@ -44,7 +44,7 @@ endif() if( NOT CLANG_BUILT_STANDALONE ) list(APPEND CLANG_TEST_DEPS - llc opt FileCheck count not + llc opt FileCheck count not llvm-symbolizer ) add_lit_testsuite(check-clang "Running the Clang regression tests" diff --git a/test/CXX/basic/basic.link/p6.cpp b/test/CXX/basic/basic.link/p6.cpp new file mode 100644 index 0000000000..8faec76fb3 --- /dev/null +++ b/test/CXX/basic/basic.link/p6.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++11 [basic.link]p6: +// The name of a function declared in block scope and the name +// of a variable declared by a block scope extern declaration +// have linkage. If there is a visible declaration of an entity +// with linkage having the same name and type, ignoring entities +// declared outside the innermost enclosing namespace scope, the +// block scope declaration declares that same entity and +// receives the linkage of the previous declaration. + +// rdar://13535367 +namespace test0 { + extern "C" int test0_array[]; + void declare() { extern int test0_array[100]; } + extern "C" int test0_array[]; + int value = sizeof(test0_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} +} + +namespace test1 { + extern "C" int test1_array[]; + void test() { + { extern int test1_array[100]; } + extern int test1_array[]; + int x = sizeof(test1_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} + } +} + +namespace test2 { + void declare() { extern int test2_array[100]; } + extern int test2_array[]; + int value = sizeof(test2_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} +} + +namespace test3 { + void test() { + { extern int test3_array[100]; } + extern int test3_array[]; + int x = sizeof(test3_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} + } +} + + diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp index 7ecedd5a6a..1f78a738f3 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s struct X0 { X0 f1(); X0 f2(); @@ -25,3 +26,92 @@ struct X0::X0 X0::f2() { return X0(); } template<typename T> X1<T>::X1<T> X1<T>::f2() { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}} template<typename T> X1<T>::X1<T> (X1<T>::f2)(int) { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}} template<typename T> struct X1<T>::X1<T> (X1<T>::f2)(float) { } + +// We have a special case for lookup within using-declarations that are +// member-declarations: foo::bar::baz::baz always names baz's constructor +// in such a context, even if looking up 'baz' within foo::bar::baz would +// not find the injected-class-name. Likewise foo::bar::baz<T>::baz also +// names the constructor. +namespace InhCtor { + struct A { + A(int); + protected: + int T(); + }; + typedef A T; + struct B : A { + // This is a using-declaration for 'int A::T()' in C++98, but is an + // inheriting constructor declaration in C++11. + using InhCtor::T::T; + }; +#if __cplusplus < 201103L + B b(123); // expected-error {{no matching constructor}} + // expected-note@-7 2{{candidate constructor}} + int n = b.T(); // ok, accessible +#else + B b(123); // ok, inheriting constructor + int n = b.T(); // expected-error {{'T' is a protected member of 'InhCtor::A'}} + // expected-note@-15 {{declared protected here}} + + template<typename T> + struct S : T { + struct U : S { + using S::S; + }; + using T::T; + }; + + S<A>::U ua(0); + S<B>::U ub(0); + + template<typename T> + struct X : T { + using T::Z::U::U; + }; + template<typename T> + struct X2 : T { + using T::Z::template V<int>::V; + }; + struct Y { + struct Z { + typedef Y U; + template<typename T> using V = Y; + }; + Y(int); + }; + X<Y> xy(0); + + namespace Repeat { + struct A { + struct T { + T(int); + }; + }; + struct Z : A { + using A::A::A; + }; + template<typename T> + struct ZT : T::T { + using T::T::T; + }; + } + + namespace NS { + struct NS {}; + } + struct DerivedFromNS : NS::NS { + // No special case unless the NNS names a class. + using InhCtor::NS::NS; // expected-error {{using declaration in class refers into 'InhCtor::NS::', which is not a class}} + + }; + + typedef int I; + struct UsingInt { + using I::I; // expected-error {{expected a class or namespace}} + }; + template<typename T> struct UsingIntTemplate { + using T::T; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} + }; + UsingIntTemplate<int> uit; // expected-note {{here}} +#endif +} 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 4ffe538beb..6fba972989 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp @@ -17,3 +17,56 @@ namespace N { int i = 2; N::S N::j = i; N::S N::j2(i); + +// <rdar://problem/13317030> +namespace M { + class X { }; + inline X operator-(int, X); + + template<typename T> + class Y { }; + + typedef Y<float> YFloat; + + namespace yfloat { + YFloat operator-(YFloat, YFloat); + } + using namespace yfloat; +} + +using namespace M; + +namespace M { + +class Other { + void foo(YFloat a, YFloat b); +}; + +} + +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 6401c29dcf..9d99a77744 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.derived/class.abstract/p16.cpp b/test/CXX/class.derived/class.abstract/p16.cpp index 93f905cd33..c237ed9044 100644 --- a/test/CXX/class.derived/class.abstract/p16.cpp +++ b/test/CXX/class.derived/class.abstract/p16.cpp @@ -14,3 +14,29 @@ struct C: A { virtual void a(); virtual void b() = delete; }; + +struct E; +struct F; +struct G; +struct H; +struct D { + virtual E &operator=(const E &); // expected-note {{here}} + virtual F &operator=(const F &); + virtual G &operator=(G&&); + virtual H &operator=(H&&); // expected-note {{here}} + friend struct F; + +private: + D &operator=(const D&) = default; + D &operator=(D&&) = default; + virtual ~D(); // expected-note 2{{here}} +}; +struct E : D {}; // expected-error {{deleted function '~E' cannot override a non-deleted function}} \ + // expected-error {{deleted function 'operator=' cannot override a non-deleted function}} +struct F : D {}; +// No move ctor here, because it would be deleted. +struct G : D {}; // expected-error {{deleted function '~G' cannot override a non-deleted function}} +struct H : D { + H &operator=(H&&) = default; // expected-error {{deleted function 'operator=' cannot override a non-deleted function}} + ~H(); +}; diff --git a/test/CXX/class/class.friend/p6.cpp b/test/CXX/class/class.friend/p6.cpp index 7d7a06419a..82ca50e485 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/basic.namespace/namespace.def/namespace.memdef/p3.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp index 069ca0a925..11372dd48a 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp @@ -91,3 +91,104 @@ namespace test5 { template void f<int>(int); template void f<long>(long); //expected-note {{instantiation}} } + +// rdar://13393749 +namespace test6 { + class A; + namespace ns { + class B { + static void foo(); // expected-note {{implicitly declared private here}} + friend union A; + }; + + union A { + void test() { + B::foo(); + } + }; + } + + class A { + void test() { + ns::B::foo(); // expected-error {{'foo' is a private member of 'test6::ns::B'}} + } + }; +} + +// We seem to be following a correct interpretation with these, but +// the standard could probably be a bit clearer. +namespace test7a { + namespace ns { + class A; + } + + using namespace ns; + class B { + static void foo(); + friend class A; + }; + + class ns::A { + void test() { + B::foo(); + } + }; +} +namespace test7b { + namespace ns { + class A; + } + + using ns::A; + class B { + static void foo(); + friend class A; + }; + + class ns::A { + void test() { + B::foo(); + } + }; +} +namespace test7c { + namespace ns1 { + class A; + } + + namespace ns2 { + // ns1::A appears as if declared in test7c according to [namespace.udir]p2. + // I think that means we aren't supposed to find it. + using namespace ns1; + class B { + static void foo(); // expected-note {{implicitly declared private here}} + friend class A; + }; + } + + class ns1::A { + void test() { + ns2::B::foo(); // expected-error {{'foo' is a private member of 'test7c::ns2::B'}} + } + }; +} +namespace test7d { + namespace ns1 { + class A; + } + + namespace ns2 { + // Honor the lexical context of a using-declaration, though. + using ns1::A; + class B { + static void foo(); + friend class A; + }; + } + + class ns1::A { + void test() { + ns2::B::foo(); + } + }; +} 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 0000000000..40f61c6445 --- /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 a3a964a1ca..122a400d9b 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 cafdd63551..4393727c19 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 ad156c8ded..8a4fa42f00 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 bca73ee85f..5e40f69d77 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 1a6dc9ecfb..bb7f7ac326 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 344f8ce8c4..40aa600ba1 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 a385aa9132..83b12d4b25 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 0000000000..39c547b9ae --- /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 7499829185..0cdf3c6e05 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 0000000000..66085eda3d --- /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 093bc14d47..1ed93b1375 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 31d49127e7..1f4cdda1a1 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 783aba1823..b9a1bc5288 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 fef3692609..8767678362 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 0000000000..d1fbe766d5 --- /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.list/p3-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp index c7fb24fb44..d61f6e3d19 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp @@ -110,3 +110,13 @@ namespace bullet8 { int j { 1 }; int k { }; } + +namespace rdar13395022 { + struct MoveOnly { + MoveOnly(MoveOnly&&); // expected-note{{copy constructor is implicitly deleted because 'MoveOnly' has a user-declared move constructor}} + }; + + void test(MoveOnly mo) { + auto &&list = {mo}; // expected-error{{call to implicitly-deleted copy constructor of 'rdar13395022::MoveOnly'}} + } +} 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 adbdff6efe..fdfa6781fe 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 @@ -192,3 +192,45 @@ namespace PR11003 { Value y(Move(0)); } } + +namespace rdar13278115 { + struct X { }; + struct Y : X { }; + X &&f0(X &x) { return x; } // expected-error{{rvalue reference to type 'rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::X'}} + 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 51d61a52a6..263f661208 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 e184ec4ffa..a32f37d552 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 99ed2fdee1..dda69e9aad 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 206c82c985..ecc6d2c3d5 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 065a12b3f2..634dee3782 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 6ddd11bcee..047e238190 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 bdb2b23ec7..0a4ac22d06 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 be898761fa..76ea96fe14 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.general/p3-0x.cpp b/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp index b84cec61c3..66579915c7 100644 --- a/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp @@ -61,9 +61,26 @@ namespace PR10036 { } } +namespace PR15290 { + template<typename T> + class A { + T v_; + friend int add_to_v(A &t) noexcept(noexcept(v_ + 42)) + { + return t.v_ + 42; + } + }; + void f() + { + A<int> t; + add_to_v(t); + } +} + namespace Static { struct X1 { int m; + // FIXME: This should be accepted. static auto f() -> decltype(m); // expected-error{{'this' cannot be implicitly used in a static member function declaration}} static auto g() -> decltype(this->m); // expected-error{{'this' cannot be used in a static member function declaration}} @@ -99,3 +116,23 @@ namespace PR12564 { void foo(Derived& d) noexcept(noexcept(d.bar(d))) {} // expected-error {{cannot bind to a value of unrelated type}} }; } + +namespace rdar13473493 { + template <typename F> + class wrap + { + public: + template <typename... Args> + auto operator()(Args&&... args) const -> decltype(wrapped(args...)) // expected-note{{candidate template ignored: substitution failure [with Args = <int>]: use of undeclared identifier 'wrapped'}} + { + return wrapped(args...); + } + + private: + F wrapped; + }; + + void test(wrap<int (*)(int)> w) { + w(5); // expected-error{{no matching function for call to object of type 'wrap<int (*)(int)>'}} + } +} 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 5dac886d4d..38d5d0a6cd 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 9dffc1ff26..dc2c209af2 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 0000000000..6a59e3d7ae --- /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 c012104314..00466fb311 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.dtor/p5-0x.cpp b/test/CXX/special/class.dtor/p5-0x.cpp index 0d073cea52..e32279ef12 100644 --- a/test/CXX/special/class.dtor/p5-0x.cpp +++ b/test/CXX/special/class.dtor/p5-0x.cpp @@ -88,9 +88,10 @@ struct C4 : virtual InaccessibleDtor { C4(); } c4; // expected-error {{deleted f class D1 { void operator delete(void*); public: - virtual ~D1() = default; + virtual ~D1() = default; // expected-note {{here}} } d1; // ok -struct D2 : D1 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}} +struct D2 : D1 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}} \ + // expected-error {{deleted function '~D2' cannot override a non-deleted}} // implicitly-virtual destructor } d2; // expected-error {{deleted function}} struct D3 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}} diff --git a/test/CXX/special/class.inhctor/elsewhere.cpp b/test/CXX/special/class.inhctor/elsewhere.cpp index 09fd3d50dc..b986f65824 100644 --- a/test/CXX/special/class.inhctor/elsewhere.cpp +++ b/test/CXX/special/class.inhctor/elsewhere.cpp @@ -9,49 +9,56 @@ struct B1 { B1(int); }; -using B1::B1; // expected-error {{using declaration can not refer to class member}} expected-error {{not supported}} +using B1::B1; // expected-error {{using declaration can not refer to class member}} -// C++0x [namespace.udecl]p10: +// C++11 [namespace.udecl]p10: // A using-declaration is a declaration and can therefore be used repeatedly // where (and only where) multiple declarations are allowed. struct I1 : B1 { - using B1::B1; // expected-note {{previous using declaration}} expected-error {{not supported}} - using B1::B1; // expected-error {{redeclaration of using decl}} expected-error {{not supported}} + using B1::B1; // expected-note {{previous using declaration}} + using B1::B1; // expected-error {{redeclaration of using decl}} }; -// C++0x [namespace.udecl]p3: +// C++11 [namespace.udecl]p3: // In a using declaration used as a member-declaration, the nested-name- // specifier shall name a base class of the class being defined. // If such a using-declaration names a constructor, the nested-name-specifier // shall name a direct base class of the class being defined. struct D1 : I1 { - using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}} expected-error {{not supported}} + using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}} }; template<typename T> struct A {}; template<typename T> struct B : A<bool>, A<char> { - using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}} expected-error {{not supported}} + using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}} }; B<bool> bb; B<char> bc; B<double> bd; // expected-note {{here}} template<typename T> struct C : A<T> { - using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}} expected-error {{not supported}} + using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}} }; C<bool> cb; C<char> cc; // expected-note {{here}} template<typename T> struct D : A<T> {}; template<typename T> struct E : D<T> { - using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}} expected-error {{not supported}} + using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}} }; E<bool> eb; // expected-note {{here}} template<typename T> struct F : D<bool> { - using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}} expected-error {{not supported}} + 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 new file mode 100644 index 0000000000..8721dec1b4 --- /dev/null +++ b/test/CXX/special/class.inhctor/p1.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s +// 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 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 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@-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 +// expected-error@-2 {{call to implicitly-deleted function of 'B'}} + +B b2{1,2}; +// expected-error@-1 {{call to implicitly-deleted function of 'B'}} + +B b3{1,2,3}; +// ok + +B b4{1,2,3,4}; +// ok + +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 new file mode 100644 index 0000000000..e6abd6840e --- /dev/null +++ b/test/CXX/special/class.inhctor/p2.cpp @@ -0,0 +1,121 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +template<int> struct X {}; + +// Constructor characteristics are: +// - the template parameter list +// - the parameter-type-list +// - absence or presence of explicit +// - absence or presence of constexpr +struct A { + A(X<0>) {} // expected-note 2{{here}} + constexpr A(X<1>) {} + explicit A(X<2>) {} // expected-note 3{{here}} + explicit constexpr A(X<3>) {} // expected-note 2{{here}} +}; + +A a0 { X<0>{} }; +A a0i = { X<0>{} }; +constexpr A a0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} +constexpr A a0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} + +A a1 { X<1>{} }; +A a1i = { X<1>{} }; +constexpr A a1c { X<1>{} }; +constexpr A a1ic = { X<1>{} }; + +A a2 { X<2>{} }; +A a2i = { X<2>{} }; // expected-error {{constructor is explicit}} +constexpr A a2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} +constexpr A a2ic = { X<2>{} }; // expected-error {{constructor is explicit}} + +A a3 { X<3>{} }; +A a3i = { X<3>{} }; // expected-error {{constructor is explicit}} +constexpr A a3c { X<3>{} }; +constexpr A a3ic = { X<3>{} }; // expected-error {{constructor is explicit}} + + +struct B : A { + using A::A; // expected-note 7{{here}} +}; + +B b0 { X<0>{} }; +B b0i = { X<0>{} }; +constexpr B b0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} +constexpr B b0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} + +B b1 { X<1>{} }; +B b1i = { X<1>{} }; +constexpr B b1c { X<1>{} }; +constexpr B b1ic = { X<1>{} }; + +B b2 { X<2>{} }; +B b2i = { X<2>{} }; // expected-error {{constructor is explicit}} +constexpr B b2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} +constexpr B b2ic = { X<2>{} }; // expected-error {{constructor is explicit}} + +B b3 { X<3>{} }; +B b3i = { X<3>{} }; // expected-error {{constructor is explicit}} +constexpr B b3c { X<3>{} }; +constexpr B b3ic = { X<3>{} }; // expected-error {{constructor is explicit}} + + +// 'constexpr' is OK even if the constructor doesn't obey the constraints. +struct NonLiteral { NonLiteral(); }; +struct NonConstexpr { NonConstexpr(); constexpr NonConstexpr(int); }; // expected-note {{here}} +struct Constexpr { constexpr Constexpr(int) {} }; + +struct BothNonLiteral : NonLiteral, Constexpr { using Constexpr::Constexpr; }; // expected-note {{base class 'NonLiteral' of non-literal type}} +constexpr BothNonLiteral bothNL{42}; // expected-error {{constexpr variable cannot have non-literal type 'const BothNonLiteral'}} + +struct BothNonConstexpr : NonConstexpr, Constexpr { using Constexpr::Constexpr; }; // expected-note {{non-constexpr constructor 'NonConstexpr}} +constexpr BothNonConstexpr bothNC{42}; // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'BothNonConstexpr(42)'}} + + +struct ConstexprEval { + constexpr ConstexprEval(int a, const char *p) : k(p[a]) {} + char k; +}; +struct ConstexprEval2 { + char k2 = 'x'; +}; +struct ConstexprEval3 : ConstexprEval, ConstexprEval2 { + using ConstexprEval::ConstexprEval; +}; +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 d7093fb369..7aaaa7a6f0 100644 --- a/test/CXX/special/class.inhctor/p3.cpp +++ b/test/CXX/special/class.inhctor/p3.cpp @@ -5,7 +5,7 @@ struct B1 { B1(int, int); }; struct D1 : B1 { - using B1::B1; // expected-error {{not supported}} + using B1::B1; }; D1 d1a(1), d1b(1, 1); @@ -15,7 +15,7 @@ struct B2 { explicit B2(int, int = 0, int = 0); }; struct D2 : B2 { // expected-note 2 {{candidate constructor}} - using B2::B2; // expected-error {{not supported}} + using B2::B2; }; D2 d2a(1), d2b(1, 1), d2c(1, 1, 1); @@ -25,18 +25,18 @@ struct B3 { B3(void*); // expected-note {{inherited from here}} }; struct D3 : B3 { // expected-note 2 {{candidate constructor}} - using B3::B3; // expected-note {{candidate constructor (inherited)}} expected-error {{not supported}} + using B3::B3; // expected-note {{candidate constructor (inherited)}} }; D3 fd3() { return 1; } // expected-error {{no viable conversion}} template<typename T> struct T1 : B1 { - using B1::B1; // expected-error {{not supported}} + using B1::B1; }; template<typename T> struct T2 : T1<T> { - using T1<int>::T1; // expected-error {{not supported}} + using T1<int>::T1; }; template<typename T> struct T3 : T1<int> { - using T1<T>::T1; // expected-error {{not supported}} + using T1<T>::T1; }; struct U { friend T1<int>::T1(int); @@ -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 new file mode 100644 index 0000000000..512705e4dd --- /dev/null +++ b/test/CXX/special/class.inhctor/p4.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +template<int> struct X {}; + +// A[n inheriting] constructor [...] has the same access as the corresponding +// constructor [in the base class]. +struct A { +public: + A(X<0>) {} +protected: + A(X<1>) {} +private: + A(X<2>) {} // expected-note {{declared private here}} + friend class FA; +}; + +struct B : A { + using A::A; // expected-error {{private constructor}} expected-note {{implicitly declared protected here}} + friend class FB; +}; + +B b0{X<0>{}}; +B b1{X<1>{}}; // expected-error {{calling a protected constructor}} +B b2{X<2>{}}; // expected-note {{first required here}} + +struct C : B { + C(X<0> x) : B(x) {} + C(X<1> x) : B(x) {} +}; + +struct FB { + B b0{X<0>{}}; + B b1{X<1>{}}; +}; + +struct FA : A { + using A::A; // expected-note 2{{here}} +}; +FA fa0{X<0>{}}; +FA fa1{X<1>{}}; // expected-error {{calling a protected constructor}} +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 2{{marked deleted here}} +}; +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 +// same signature. +namespace DRnnnn { + struct A { + constexpr A(int, float = 0) {} + explicit A(int, int = 0) {} + + A(int, int, int = 0) = delete; + }; + struct B : A { + // FIXME: produce notes indicating why it was deleted + using A::A; // expected-note {{here}} + }; + + constexpr B b0(0, 0.0f); // ok, constexpr + B b1(0, 1); // expected-error {{call to implicitly-deleted}} +} diff --git a/test/CXX/special/class.inhctor/p7.cpp b/test/CXX/special/class.inhctor/p7.cpp index bfaa3ac359..a57e8558f5 100644 --- a/test/CXX/special/class.inhctor/p7.cpp +++ b/test/CXX/special/class.inhctor/p7.cpp @@ -8,12 +8,12 @@ struct B2 { B2(int); // expected-note {{conflicting constructor}} }; struct D1 : B1, B2 { - using B1::B1; // expected-note {{inherited here}} expected-error {{not supported}} - using B2::B2; // expected-error {{already inherited constructor with the same signature}} expected-error {{not supported}} + using B1::B1; // expected-note {{inherited here}} + using B2::B2; // expected-error {{already inherited constructor with the same signature}} }; struct D2 : B1, B2 { - using B1::B1; // expected-error {{not supported}} - using B2::B2; // expected-error {{not supported}} + using B1::B1; + using B2::B2; D2(int); }; @@ -22,8 +22,26 @@ template<typename T> struct B3 { }; template<typename T> struct B4 : B3<T>, B1 { B4(); - using B3<T>::B3; // expected-note {{inherited here}} expected-error {{not supported}} - using B1::B1; // expected-error {{already inherited}} expected-error {{not supported}} + using B3<T>::B3; // expected-note {{inherited here}} + using B1::B1; // expected-error {{already inherited}} }; 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 new file mode 100644 index 0000000000..0c857382e3 --- /dev/null +++ b/test/CXX/special/class.inhctor/p8.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +// expected-no-diagnostics +struct A { + constexpr A(const int&) : rval(false) {} + constexpr A(const int&&) : rval(true) {} + bool rval; +}; +struct B : A { + using A::A; +}; + +constexpr int k = 0; +constexpr A a0{0}; +constexpr A a1{k}; +constexpr B b0{0}; +// This performs static_cast<(const int&)&&>(k), so calls the A(const int&) +// constructor. +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 3952afdeff..b159a15b8d 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 d0f15d4d3d..fda0c5cff1 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 59ce8b68b7..3f65466dfc 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 e0ffef5007..82114cfa9d 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 e0c7b35a79..f804d4db12 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 2837de4b8b..2321c01c6f 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 0000000000..eea7920b10 --- /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 0000000000..8a93cb41fa --- /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 1021010a6d..60a6b01912 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/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c index 3e180a445b..ebe39feea4 100644 --- a/test/CodeGen/catch-undef-behavior.c +++ b/test/CodeGen/catch-undef-behavior.c @@ -285,13 +285,16 @@ void int_fp16_overflow(int n, __fp16 *p) { // CHECK: @float_int_overflow // CHECK-TRAP: @float_int_overflow int float_int_overflow(float f) { - // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0xC1E0000000000000 - // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 0x41DFFFFFE0000000 + // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000 + // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000 // CHECK: and i1 %[[GE]], %[[LE]] - // CHECK: call void @__ubsan_handle_float_cast_overflow( - // CHECK-TRAP: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0xC1E0000000000000 - // CHECK-TRAP: %[[LE:.*]] = fcmp ole float %[[F]], 0x41DFFFFFE0000000 + // CHECK: %[[CAST:.*]] = bitcast float %[[F]] to i32 + // CHECK: %[[ARG:.*]] = zext i32 %[[CAST]] to i64 + // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]] + + // CHECK-TRAP: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000 + // CHECK-TRAP: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000 // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]] // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]] @@ -300,16 +303,38 @@ int float_int_overflow(float f) { return f; } +// CHECK: @long_double_int_overflow +// CHECK-TRAP: @long_double_int_overflow +int long_double_int_overflow(long double ld) { + // CHECK: alloca x86_fp80 + // CHECK: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E8000000100000000 + // CHECK: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E8000000000000000 + // CHECK: and i1 %[[GE]], %[[LE]] + + // CHECK: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]] + // CHECK: %[[ARG:.*]] = ptrtoint x86_fp80* %[[ALLOCA]] to i64 + // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]] + + // CHECK-TRAP: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E800000010000000 + // CHECK-TRAP: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E800000000000000 + // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]] + // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]] + + // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] + // CHECK-TRAP-NEXT: unreachable + return ld; +} + // CHECK: @float_uint_overflow // CHECK-TRAP: @float_uint_overflow unsigned float_uint_overflow(float f) { - // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0.{{0*}}e+00 - // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 0x41EFFFFFE0000000 + // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.{{0*}}e+00 + // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 0x41F0000000000000 // CHECK: and i1 %[[GE]], %[[LE]] // CHECK: call void @__ubsan_handle_float_cast_overflow( - // CHECK-TRAP: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0.{{0*}}e+00 - // CHECK-TRAP: %[[LE:.*]] = fcmp ole float %[[F]], 0x41EFFFFFE0000000 + // CHECK-TRAP: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.{{0*}}e+00 + // CHECK-TRAP: %[[LE:.*]] = fcmp olt float %[[F]], 0x41F0000000000000 // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]] // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]] @@ -321,13 +346,13 @@ unsigned float_uint_overflow(float f) { // CHECK: @fp16_char_overflow // CHECK-TRAP: @fp16_char_overflow signed char fp16_char_overflow(__fp16 *p) { - // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], -1.28{{0*}}e+02 - // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 1.27{{0*}}e+02 + // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.29{{0*}}e+02 + // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 1.28{{0*}}e+02 // CHECK: and i1 %[[GE]], %[[LE]] // CHECK: call void @__ubsan_handle_float_cast_overflow( - // CHECK-TRAP: %[[GE:.*]] = fcmp oge float %[[F:.*]], -1.28{{0*}}e+02 - // CHECK-TRAP: %[[LE:.*]] = fcmp ole float %[[F]], 1.27{{0*}}e+02 + // CHECK-TRAP: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.29{{0*}}e+02 + // CHECK-TRAP: %[[LE:.*]] = fcmp olt float %[[F]], 1.28{{0*}}e+02 // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]] // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]] @@ -339,14 +364,17 @@ signed char fp16_char_overflow(__fp16 *p) { // CHECK: @float_float_overflow // CHECK-TRAP: @float_float_overflow float float_float_overflow(double f) { - // CHECK: %[[GE:.*]] = fcmp oge double %[[F:.*]], 0xC7EFFFFFE0000000 - // CHECK: %[[LE:.*]] = fcmp ole double %[[F]], 0x47EFFFFFE0000000 + // CHECK: %[[F:.*]] = call double @llvm.fabs.f64( + // CHECK: %[[GE:.*]] = fcmp ogt double %[[F]], 0x47EFFFFFE0000000 + // CHECK: %[[LE:.*]] = fcmp olt double %[[F]], 0x7FF0000000000000 // CHECK: and i1 %[[GE]], %[[LE]] // CHECK: call void @__ubsan_handle_float_cast_overflow( - // CHECK-TRAP: %[[GE:.*]] = fcmp oge double %[[F:.*]], 0xC7EFFFFFE0000000 - // CHECK-TRAP: %[[LE:.*]] = fcmp ole double %[[F]], 0x47EFFFFFE0000000 - // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]] + // CHECK-TRAP: %[[F:.*]] = call double @llvm.fabs.f64( + // CHECK-TRAP: %[[GE:.*]] = fcmp ogt double %[[F]], 0x47EFFFFFE0000000 + // CHECK-TRAP: %[[LE:.*]] = fcmp olt double %[[F]], 0x7FF0000000000000 + // CHECK-TRAP: %[[OUTOFBOUNDS:.*]] = and i1 %[[GE]], %[[LE]] + // CHECK-TRAP: %[[INBOUNDS:.*]] = xor i1 %[[OUTOFBOUNDS]], true // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]] // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] diff --git a/test/CodeGen/code-coverage.c b/test/CodeGen/code-coverage.c index f165e30e6f..1b87d649dd 100644 --- a/test/CodeGen/code-coverage.c +++ b/test/CodeGen/code-coverage.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data -coverage-no-function-names-in-data %s -o - | FileCheck %s --check-prefix WITHOUTNAMES // <rdar://problem/12843084> @@ -15,8 +16,15 @@ int test1(int a) { // Check that the noredzone flag is set on the generated functions. // CHECK: void @__llvm_gcov_indirect_counter_increment(i32* %{{.*}}, i64** %{{.*}}) unnamed_addr [[NRZ:#[0-9]+]] + +// Inside llvm_gcov_writeout, check that -coverage-no-function-names-in-data +// passes null as the function name. // CHECK: void @__llvm_gcov_writeout() unnamed_addr [[NRZ]] +// CHECK: call void @llvm_gcda_emit_function({{.*}}, i8* getelementptr {{.*}}, {{.*}}) +// WITHOUTNAMES: void @__llvm_gcov_writeout() unnamed_addr +// WITHOUTNAMES: call void @llvm_gcda_emit_function({{.*}}, i8* null, {{.*}}) + +// CHECK: void @__llvm_gcov_flush() unnamed_addr [[NRZ]] // CHECK: void @__llvm_gcov_init() unnamed_addr [[NRZ]] -// CHECK: void @__gcov_flush() unnamed_addr [[NRZ]] // CHECK: attributes [[NRZ]] = { {{.*}}noredzone{{.*}} } diff --git a/test/CodeGen/frame-pointer-elim.c b/test/CodeGen/frame-pointer-elim.c deleted file mode 100644 index b105a199f1..0000000000 --- a/test/CodeGen/frame-pointer-elim.c +++ /dev/null @@ -1,40 +0,0 @@ -// REQUIRES: x86-registered-target - -// RUN: %clang -target i386-apple-darwin -S -o - %s | \ -// RUN: FileCheck --check-prefix=DARWIN %s -// DARWIN: f0: -// DARWIN: pushl %ebp -// DARWIN: ret -// DARWIN: f1: -// DARWIN: pushl %ebp -// DARWIN: ret - -// RUN: %clang -target i386-pc-linux-gnu -S -o - %s | \ -// RUN: FileCheck --check-prefix=LINUX %s -// LINUX: f0: -// LINUX-NOT: pushl %ebp -// LINUX: ret -// LINUX: f1: -// LINUX: pushl %ebp -// LINUX: ret - -// RUN: %clang -target i386-darwin -S -o - -fomit-frame-pointer %s | \ -// RUN: FileCheck --check-prefix=OMIT_ALL %s -// OMIT_ALL: f0: -// OMIT_ALL-NOT: pushl %ebp -// OMIT_ALL: ret -// OMIT_ALL: f1: -// OMIT_ALL-NOT: pushl %ebp -// OMIT_ALL: ret - -// RUN: %clang -target i386-darwin -S -o - -momit-leaf-frame-pointer %s | \ -// RUN: FileCheck --check-prefix=OMIT_LEAF %s -// OMIT_LEAF: f0: -// OMIT_LEAF-NOT: pushl %ebp -// OMIT_LEAF: ret -// OMIT_LEAF: f1: -// OMIT_LEAF: pushl %ebp -// OMIT_LEAF: ret - -void f0() {} -void f1() { f0(); } diff --git a/test/CodeGen/global-blocks-lines.c b/test/CodeGen/global-blocks-lines.c new file mode 100644 index 0000000000..36e4618dde --- /dev/null +++ b/test/CodeGen/global-blocks-lines.c @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -fblocks -g -emit-llvm %s -o - | FileCheck %s +// Make sure we do not generate line info for debugging-related frame setup. +// CHECK: define {{.*}}block_invoke +// CHECK-NOT: store {{.*}}%struct.__block_descriptor*{{.*}}dbg +// CHECK: store {{.*}}%struct.__block_descriptor*{{.*}}, align +// CHECK: ret +// CHECK: define {{.*}}block_invoke +// CHECK-NOT: store {{.*}}%struct.__block_descriptor*{{.*}}dbg +// CHECK: store {{.*}}%struct.__block_descriptor*{{.*}}, align +// CHECK: ret +// CHECK: define {{.*}}block_invoke +// CHECK-NOT: store {{.*}}%struct.__block_descriptor*{{.*}}dbg +// CHECK: store {{.*}}%struct.__block_descriptor*{{.*}}, align +// CHECK: ret +int printf(const char*, ...); + +static void* _NSConcreteGlobalBlock; + + +typedef void (^ HelloBlock_t)(const char * name); + + /* Breakpoint for first Block function. */ +HelloBlock_t helloBlock = ^(const char * name) { + printf("Hello there, %s!\n", name); +}; + + /* Breakpoint for second Block function. */ +static HelloBlock_t s_helloBlock = ^(const char * name) { + printf("Hello there, %s!\n", name); +}; + +/* Breakpoint for third Block function. */ +int X = 1234; +int (^CP)(void) = ^{ X = X+1; return X; }; + +int +main(int argc, char * argv[]) +{ + helloBlock("world"); + s_helloBlock("world"); + + CP(); + printf ("X = %d\n", X); + return X - 1235; +} diff --git a/test/CodeGen/le32-regparm.c b/test/CodeGen/le32-regparm.c index 8c1ae5eb45..c8f70694c4 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/lifetime2.c b/test/CodeGen/lifetime2.c new file mode 100644 index 0000000000..ffff5cca12 --- /dev/null +++ b/test/CodeGen/lifetime2.c @@ -0,0 +1,17 @@ +// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefix=O2 +// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefix=O0 + +extern int bar(char *A, int n); + +// O0-NOT: @llvm.lifetime.start +int foo (int n) { + if (n) { +// O2: @llvm.lifetime.start + char A[100]; + return bar(A, 1); + } else { +// O2: @llvm.lifetime.start + char A[100]; + return bar(A, 2); + } +} diff --git a/test/CodeGen/linetable-endscope.c b/test/CodeGen/linetable-endscope.c new file mode 100644 index 0000000000..236f605d7e --- /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 0000000000..c7ce1d228b --- /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 b73ee15f87..c76724444b 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 0000000000..7c4ca2ce14 --- /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/mips16-attr.c b/test/CodeGen/mips16-attr.c new file mode 100644 index 0000000000..18799be6f0 --- /dev/null +++ b/test/CodeGen/mips16-attr.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple mipsel-linux-gnu -emit-llvm -o - %s | FileCheck %s +void __attribute__((mips16)) foo (void) { + +} + +// CHECK: define void @foo() [[MIPS16:#[0-9]+]] + +void __attribute__((nomips16)) nofoo (void) { + +} + +// CHECK: define void @nofoo() [[NOMIPS16:#[0-9]+]] + +// CHECK: attributes [[MIPS16]] = { nounwind {{.*}} "mips16" {{.*}} } + +// CHECK: attributes [[NOMIPS16]] = { nounwind {{.*}} "nomips16" {{.*}} } + diff --git a/test/CodeGen/ms-inline-asm-64.c b/test/CodeGen/ms-inline-asm-64.c index 8d2940d4e0..dd7b9b3349 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 7f130d697b..c71a8df0ec 100644 --- a/test/CodeGen/ms-inline-asm.c +++ b/test/CodeGen/ms-inline-asm.c @@ -3,16 +3,16 @@ void t1() { // CHECK: @t1 -// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() [[NUW:#[0-9]+]] +// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() // CHECK: ret void __asm {} } void t2() { // CHECK: @t2 -// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() // CHECK: ret void __asm nop __asm nop @@ -21,15 +21,15 @@ void t2() { void t3() { // CHECK: @t3 -// CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"() // CHECK: ret void __asm nop __asm nop __asm nop } void t4(void) { // CHECK: @t4 -// CHECK: call void asm sideeffect inteldialect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"() // CHECK: ret void __asm mov ebx, eax __asm mov ecx, ebx @@ -37,7 +37,7 @@ void t4(void) { void t5(void) { // CHECK: @t5 -// CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"() // CHECK: ret void __asm mov ebx, eax __asm mov ecx, ebx } @@ -45,7 +45,7 @@ void t5(void) { void t6(void) { __asm int 0x2c // CHECK: t6 -// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() } void t7() { @@ -54,8 +54,8 @@ void t7() { } __asm {} // CHECK: t7 -// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() } int t8() { @@ -64,9 +64,9 @@ int t8() { __asm int 4 return 10; // CHECK: t8 -// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"() // CHECK: ret i32 10 } @@ -77,7 +77,7 @@ void t9() { pop ebx } // CHECK: t9 -// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() } unsigned t10(void) { @@ -91,7 +91,7 @@ unsigned t10(void) { // CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4 // CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4 // CHECK: store i32 1, i32* [[I]], align 4 -// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}) [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}) // CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4 // CHECK: ret i32 [[RET]] } @@ -99,7 +99,7 @@ unsigned t10(void) { void t11(void) { __asm mov eax, 1 // CHECK: t11 -// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() } unsigned t12(void) { @@ -112,7 +112,7 @@ unsigned t12(void) { } return j + m; // CHECK: t12 -// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $2\0A\09mov dword ptr $0, eax\0A\09mov eax, dword ptr $3\0A\09mov dword ptr $1, eax", "=*m,=*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $2\0A\09mov dword ptr $0, eax\0A\09mov eax, dword ptr $3\0A\09mov dword ptr $1, eax", "=*m,=*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) } void t13() { @@ -121,8 +121,8 @@ void t13() { __asm movzx eax, i __asm movzx eax, j // CHECK: t13 -// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}) [[NUW]] -// CHECK: call void asm sideeffect inteldialect "movzx eax, word ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i16* %{{.*}}) [[NUW]] +// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "movzx eax, word ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i16* %{{.*}}) } void t14() { @@ -135,7 +135,7 @@ void t14() { .endif } // CHECK: t14 -// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, dword ptr $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]] +// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, dword ptr $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) } int gvar = 10; @@ -145,16 +145,16 @@ void t15() { __asm mov eax, offset lvar ; eax = address of lvar __asm mov eax, offset gvar ; eax = address of gvar // CHECK: t15 -// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @{{.*}}) [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @{{.*}}) } void t16() { int var = 10; __asm mov [eax], offset var // CHECK: t16 -// 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* %{{.*}}) } void t17() { @@ -163,40 +163,10 @@ void t17() { __asm _emit 0x4B __asm _EMIT 0x4B // CHECK: t17 -// CHECK: call void asm sideeffect inteldialect ".byte 0x4A", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect ".byte 0x43", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -} - -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, foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -} - -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, foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect ".byte 0x4A", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect ".byte 0x43", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"() } void t20() { @@ -210,28 +180,28 @@ void t20() { __asm mov eax, LENGTH _foo __asm mov eax, LENGTH _bar // CHECK: t20 -// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"() __asm mov eax, TYPE foo __asm mov eax, TYPE bar __asm mov eax, TYPE _foo __asm mov eax, TYPE _bar -// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() __asm mov eax, SIZE foo __asm mov eax, SIZE bar __asm mov eax, SIZE _foo __asm mov eax, SIZE _bar -// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"() } void t21() { @@ -241,7 +211,7 @@ void t21() { __asm pop ebx } // CHECK: t21 -// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() } extern void t22_helper(int x); @@ -257,9 +227,9 @@ void t22() { __asm pop ebx } // CHECK: t22 -// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, esp", "~{ebx},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, esp", "~{ebx},~{dirflag},~{fpsr},~{flags}"() // CHECK: call void @t22_helper -// CHECK: call void asm sideeffect inteldialect "mov esp, ebx\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov esp, ebx\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() } void t23() { @@ -267,14 +237,14 @@ void t23() { the_label: } // CHECK: t23 -// CHECK: call void asm sideeffect inteldialect "the_label:", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "the_label:", "~{dirflag},~{fpsr},~{flags}"() } void t24_helper(void) {} void t24() { __asm call t24_helper // CHECK: t24 -// CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(void ()* @t24_helper) [[NUW]] +// CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(void ()* @t24_helper) } void t25() { @@ -284,11 +254,11 @@ 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}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$0fh", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$0a2h", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2h", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// 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}"() } void t26() { @@ -299,18 +269,18 @@ void t26() { __asm __EMIT 0a2h __asm popad // CHECK: t26 -// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov eax, $$0", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect ".byte 0fh", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "mov eax, $$0", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect ".byte 0fh", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"() } void t27() { __asm mov eax, fs:[0h] // CHECK: t27 -// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[0h]", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0h]", "~{eax},~{dirflag},~{fpsr},~{flags}"() } void t28() { @@ -319,10 +289,10 @@ void t28() { __asm align 128; __asm ALIGN 256; // CHECK: t28 -// CHECK: call void asm sideeffect inteldialect ".align 3", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect ".align 4", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect ".align 7", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect ".align 8", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect ".align 3", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect ".align 4", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect ".align 7", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect ".align 8", "~{dirflag},~{fpsr},~{flags}"() } void t29() { @@ -332,9 +302,9 @@ void t29() { __asm mov osize, SIZE arr __asm mov otype, TYPE arr // CHECK: t29 -// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$2", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$8", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$4", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]] +// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$2", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$8", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$4", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) } int results[2] = {13, 37}; @@ -345,16 +315,126 @@ int *t30() __asm mov res, edi return res; // CHECK: t30 -// CHECK: call void asm sideeffect inteldialect "lea edi, dword ptr $0", "*m,~{edi},~{dirflag},~{fpsr},~{flags}"([2 x i32]* @{{.*}}) [[NUW]] -// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, edi", "=*m,~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}}) [[NUW]] +// CHECK: call void asm sideeffect inteldialect "lea edi, dword ptr $0", "*m,~{edi},~{dirflag},~{fpsr},~{flags}"([2 x i32]* @{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, edi", "=*m,~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}}) } void t31() { __asm pushad __asm popad // CHECK: t31 -// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] -// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"() [[NUW]] +// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"() +} + +void t32() { + int i; + __asm mov eax, i + __asm mov eax, dword ptr i + __asm mov ax, word ptr i + __asm mov al, byte ptr i +// CHECK: t32 +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov ax, word ptr $0", "*m,~{ax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov al, byte ptr $0", "*m,~{al},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) } -// CHECK: attributes [[NUW]] = { nounwind } +void t33() { + int i; + __asm mov eax, [i] + __asm mov eax, dword ptr [i] + __asm mov ax, word ptr [i] + __asm mov al, byte ptr [i] +// CHECK: t33 +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov ax, word ptr $0", "*m,~{ax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov al, byte ptr $0", "*m,~{al},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +} + +void t34() { + __asm prefetchnta 64[eax] + __asm mov eax, dword ptr 4[eax] +// CHECK: 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 new file mode 100644 index 0000000000..8f824f9947 --- /dev/null +++ b/test/CodeGen/ms-inline-asm.cpp @@ -0,0 +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] +// CHECK: @_Z2t1v +// 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 6cf6f0a270..111679e3a9 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/nvptx-cpus.c b/test/CodeGen/nvptx-cpus.c new file mode 100644 index 0000000000..c9c7680d67 --- /dev/null +++ b/test/CodeGen/nvptx-cpus.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_20 -O3 -S -o %t %s -emit-llvm +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_21 -O3 -S -o %t %s -emit-llvm +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_30 -O3 -S -o %t %s -emit-llvm +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_35 -O3 -S -o %t %s -emit-llvm + +// Make sure clang accepts all supported architectures. + +void foo(float* a, + float* b) { + a[0] = b[0]; +} diff --git a/test/CodeGen/pragma-pack-1.c b/test/CodeGen/pragma-pack-1.c index c30a62ac3c..2a71c8f79b 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/prefetchw-builtins.c b/test/CodeGen/prefetchw-builtins.c new file mode 100644 index 0000000000..9c5fdc7233 --- /dev/null +++ b/test/CodeGen/prefetchw-builtins.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +prfchw -emit-llvm -o - %s | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +void prefetch_w(void *p) { + return _m_prefetchw(p); +// CHECK: @prefetch_w +// CHECK: call void @llvm.prefetch({{.*}}, i32 1, i32 3, i32 1) +} diff --git a/test/CodeGen/rdrand-builtins.c b/test/CodeGen/rdrand-builtins.c index b7970f4dd4..15414a3345 100644 --- a/test/CodeGen/rdrand-builtins.c +++ b/test/CodeGen/rdrand-builtins.c @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +rdrnd -emit-llvm -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +rdrnd -target-feature +rdseed -emit-llvm -o - %s | FileCheck %s // Don't include mm_malloc.h, it's system specific. #define __MM_MALLOC_H -#include <immintrin.h> +#include <x86intrin.h> int rdrand16(unsigned short *p) { return _rdrand16_step(p); @@ -25,3 +25,24 @@ int rdrand64(unsigned long long *p) { // CHECK: call { i64, i32 } @llvm.x86.rdrand.64 // CHECK: store i64 } + +int rdseed16(unsigned short *p) { + return _rdseed16_step(p); +// CHECK: @rdseed16 +// CHECK: call { i16, i32 } @llvm.x86.rdseed.16 +// CHECK: store i16 +} + +int rdseed32(unsigned *p) { + return _rdseed32_step(p); +// CHECK: @rdseed32 +// CHECK: call { i32, i32 } @llvm.x86.rdseed.32 +// CHECK: store i32 +} + +int rdseed64(unsigned long long *p) { + return _rdseed64_step(p); +// CHECK: @rdseed64 +// CHECK: call { i64, i32 } @llvm.x86.rdseed.64 +// CHECK: store i64 +} diff --git a/test/CodeGen/rtm-builtins.c b/test/CodeGen/rtm-builtins.c index c4939a9a3d..5660d8e241 100644 --- a/test/CodeGen/rtm-builtins.c +++ b/test/CodeGen/rtm-builtins.c @@ -21,3 +21,8 @@ test_xabort(void) { // CHECK: void @llvm.x86.xabort(i8 2) _xabort(2); } + +unsigned int test_xtest(void) { + // CHECK: i32 @llvm.x86.xtest() + return _xtest(); +} diff --git a/test/CodeGen/sanitize-init-order.cpp b/test/CodeGen/sanitize-init-order.cpp new file mode 100644 index 0000000000..3e94620193 --- /dev/null +++ b/test/CodeGen/sanitize-init-order.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsanitize=address,init-order -emit-llvm -o - %s | FileCheck %s + +struct PODStruct { + int x; +}; +PODStruct s1; + +struct PODWithDtor { + ~PODWithDtor() { } + int x; +}; +PODWithDtor s2; + +struct PODWithCtorAndDtor { + PODWithCtorAndDtor() { } + ~PODWithCtorAndDtor() { } + int x; +}; +PODWithCtorAndDtor s3; + +// Check that ASan init-order checking ignores structs with trivial default +// constructor. +// CHECK: !llvm.asan.dynamically_initialized_globals = !{[[GLOB:![0-9]+]]} +// CHECK: [[GLOB]] = metadata !{%struct.PODWithCtorAndDtor diff --git a/test/CodeGen/sanitize-use-after-scope.c b/test/CodeGen/sanitize-use-after-scope.c new file mode 100644 index 0000000000..8f920385bc --- /dev/null +++ b/test/CodeGen/sanitize-use-after-scope.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -S -emit-llvm -o - -fsanitize=address,use-after-scope %s \ +// RUN: | FileCheck %s -check-prefix=USE-AFTER-SCOPE +// RUN: %clang_cc1 -S -emit-llvm -o - -fsanitize=address %s \ +// RUN: | FileCheck %s -check-prefix=ADDRESS-ONLY + +extern int bar(char *A, int n); + +// ADDRESS-ONLY-NOT: @llvm.lifetime.start +int foo (int n) { + if (n) { + // USE-AFTER-SCOPE: @llvm.lifetime.start(i64 10, i8* {{.*}}) + char A[10]; + return bar(A, 1); + // USE-AFTER-SCOPE: @llvm.lifetime.end(i64 10, i8* {{.*}}) + } else { + // USE-AFTER-SCOPE: @llvm.lifetime.start(i64 20, i8* {{.*}}) + char A[20]; + return bar(A, 2); + // USE-AFTER-SCOPE: @llvm.lifetime.end(i64 20, i8* {{.*}}) + } +} + diff --git a/test/CodeGen/sparc-target-data.c b/test/CodeGen/sparc-target-data.c new file mode 100644 index 0000000000..bb32a2196a --- /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 0000000000..8e5854f1bb --- /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 0000000000..967ba19a04 --- /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 8b30aa0a49..6d593a3c1b 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 { @@ -14,4 +14,61 @@ void copy(struct A *a, struct A *b) { // CHECK: target datalayout = "{{.*}}p:[[P:64|32]] // CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 16, i32 4, i1 false), !tbaa.struct [[TS:!.*]] + +struct B { + char c1; + struct A a; + int ii; +}; + +void copy2(struct B *a, struct B *b) { + *a = *b; +} + +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 24, i32 4, i1 false), !tbaa.struct [[TS2:!.*]] + +typedef _Complex int T2; +typedef _Complex char T5; +typedef _Complex int T7; +typedef struct T4 { T5 field0; T7 field1; } T4; +typedef union T1 { T2 field0; T4 field1; } T1; + +void copy3 (T1 *a, T1 *b) { + *a = *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 new file mode 100644 index 0000000000..afb8893d3e --- /dev/null +++ b/test/CodeGen/tbaa.cpp @@ -0,0 +1,255 @@ +// 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; +typedef struct +{ + uint16_t f16; + uint32_t f32; + uint16_t f16_2; + uint32_t f32_2; +} StructA; +typedef struct +{ + uint16_t f16; + StructA a; + uint32_t f32; +} StructB; +typedef struct +{ + uint16_t f16; + StructB b; + uint32_t f32; +} StructC; +typedef struct +{ + uint16_t f16; + StructB b; + uint32_t f32; + uint8_t f8; +} StructD; + +typedef struct +{ + uint16_t f16; + uint32_t f32; +} StructS; +typedef struct +{ + uint16_t f16; + uint32_t f32; +} StructS2; + +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_S2_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 i16 4, i16* %{{.*}}, align 2, !tbaa !5 +// PATH: define i32 @{{.*}}( +// 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; +} + +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; +} + +// 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: [[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 a2d3e62c8c..8e21651cd8 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-darwin.c b/test/CodeGen/x86_32-arguments-darwin.c index 917ba72e0b..4aa4295ffd 100644 --- a/test/CodeGen/x86_32-arguments-darwin.c +++ b/test/CodeGen/x86_32-arguments-darwin.c @@ -229,7 +229,7 @@ v4i32 f55(v4i32 arg) { return arg+arg; } // CHECK: define void @f56( // CHECK: i8 signext %a0, %struct.s56_0* byval align 4 %a1, -// CHECK: x86_mmx %a2.coerce, %struct.s56_1* byval align 4, +// CHECK: i64 %a2.coerce, %struct.s56_1* byval align 4, // CHECK: i64 %a4.coerce, %struct.s56_2* byval align 4, // CHECK: <4 x i32> %a6, %struct.s56_3* byval align 16 %a7, // CHECK: <2 x double> %a8, %struct.s56_4* byval align 16 %a9, @@ -238,7 +238,7 @@ v4i32 f55(v4i32 arg) { return arg+arg; } // CHECK: call void (i32, ...)* @f56_0(i32 1, // CHECK: i32 %{{[^ ]*}}, %struct.s56_0* byval align 4 %{{[^ ]*}}, -// CHECK: x86_mmx %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}}, +// CHECK: i64 %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}}, // CHECK: i64 %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}}, // CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval align 16 %{{[^ ]*}}, // CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 16 %{{[^ ]*}}, diff --git a/test/CodeGen/x86_32-arguments-linux.c b/test/CodeGen/x86_32-arguments-linux.c index 81dcaf6af5..e93f9dccbf 100644 --- a/test/CodeGen/x86_32-arguments-linux.c +++ b/test/CodeGen/x86_32-arguments-linux.c @@ -3,7 +3,7 @@ // CHECK: define void @f56( // CHECK: i8 signext %a0, %struct.s56_0* byval align 4 %a1, -// CHECK: x86_mmx %a2.coerce, %struct.s56_1* byval align 4, +// CHECK: i64 %a2.coerce, %struct.s56_1* byval align 4, // CHECK: <1 x double> %a4, %struct.s56_2* byval align 4, // CHECK: <4 x i32> %a6, %struct.s56_3* byval align 4, // CHECK: <2 x double> %a8, %struct.s56_4* byval align 4, @@ -12,7 +12,7 @@ // CHECK: call void (i32, ...)* @f56_0(i32 1, // CHECK: i32 %{{.*}}, %struct.s56_0* byval align 4 %{{[^ ]*}}, -// CHECK: x86_mmx %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}}, +// CHECK: i64 %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}}, // CHECK: <1 x double> %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}}, // CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval align 4 %{{[^ ]*}}, // CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 4 %{{[^ ]*}}, diff --git a/test/CodeGen/x86_32-arguments-win32.c b/test/CodeGen/x86_32-arguments-win32.c index f18bb30fa4..77ff9e2ff3 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/CodeGen/x86_32-inline-asm.c b/test/CodeGen/x86_32-inline-asm.c index 527ad85581..473f78ebca 100644 --- a/test/CodeGen/x86_32-inline-asm.c +++ b/test/CodeGen/x86_32-inline-asm.c @@ -7,7 +7,7 @@ typedef u_int32_t uint32_t; typedef unsigned long long u_int64_t; typedef u_int64_t uint64_t; -int func() { +int func1() { // Error out if size is > 32-bits. uint32_t msr = 0x8b; uint64_t val = 0; diff --git a/test/CodeGenCUDA/ptx-kernels.cu b/test/CodeGenCUDA/ptx-kernels.cu index f0bf2952a1..8d34f4f3a6 100644 --- a/test/CodeGenCUDA/ptx-kernels.cu +++ b/test/CodeGenCUDA/ptx-kernels.cu @@ -2,11 +2,15 @@ #include "../SemaCUDA/cuda.h" -// CHECK: define ptx_device{{.*}}device_function +// CHECK: define void @device_function +extern "C" __device__ void device_function() {} -// CHECK: define ptx_kernel{{.*}}global_function +// CHECK: define void @global_function +extern "C" __global__ void global_function() { - // CHECK: call ptx_device{{.*}}device_function + // CHECK: call void @device_function device_function(); } + +// CHECK: !{{[0-9]+}} = metadata !{void ()* @global_function, metadata !"kernel", i32 1} diff --git a/test/CodeGenCXX/2010-07-23-DeclLoc.cpp b/test/CodeGenCXX/2010-07-23-DeclLoc.cpp index 74054481cd..4c689029b8 100644 --- a/test/CodeGenCXX/2010-07-23-DeclLoc.cpp +++ b/test/CodeGenCXX/2010-07-23-DeclLoc.cpp @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck %s // Require the template function declaration refer to the correct filename. // First, locate the function decl in metadata, and pluck out the file handle: -// CHECK: {{extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*[^ ]+", metadata !}}[[filehandle:[0-9]+]], +// CHECK: metadata [[filehandle:![0-9]+]], {{[^,]*}}, {{.*extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*[^ ]+", }} // Second: Require that filehandle refer to the correct filename: -// CHECK: {{^!}}[[filehandle]] = metadata {{![{].*}} metadata !"decl_should_be_here.hpp", +// CHECK: [[filehandle]] = {{.*}}decl_should_be_here.hpp" typedef long unsigned int __darwin_size_t; typedef __darwin_size_t size_t; typedef unsigned char uint8_t; diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp index 3d3b147aa1..48f2f00840 100644 --- a/test/CodeGenCXX/arm.cpp +++ b/test/CodeGenCXX/arm.cpp @@ -56,15 +56,15 @@ namespace test1 { // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]] // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]] - // CHECK: call [[A]]* @_ZN5test11AC2Ei( - // CHECK: ret [[A]]* [[THIS1]] + // CHECK: [[THIS2:%.*]] = call [[A]]* @_ZN5test11AC2Ei( + // CHECK: ret [[A]]* [[THIS2]] // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* %this) unnamed_addr // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]] // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]] - // CHECK: call [[A]]* @_ZN5test11AD2Ev( - // CHECK: ret [[A]]* [[THIS1]] + // CHECK: [[THIS2:%.*]] = call [[A]]* @_ZN5test11AD2Ev( + // CHECK: ret [[A]]* [[THIS2]] } // Awkward virtual cases. diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp index 1500c0d698..81eef0e028 100644 --- a/test/CodeGenCXX/blocks.cpp +++ b/test/CodeGenCXX/blocks.cpp @@ -120,9 +120,11 @@ namespace test4 { } // CHECK: define void @_ZN5test44testEv() // CHECK: define internal void @___ZN5test44testEv_block_invoke - // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1 - // CHECK-NEXT: bitcast i8* - // CHECK-NEXT: call void @_ZN5test41AC1Ev([[A]]* [[TMP]]) + // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1 + // CHECK-NEXT: store i8* [[BLOCKDESC:%.*]], i8** {{.*}}, align 8 + // CHECK-NEXT: load i8* + // CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>* + // CHECK: call void @_ZN5test41AC1Ev([[A]]* [[TMP]]) // CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]]) // CHECK-NEXT: call void @_ZN5test41AD1Ev([[A]]* [[TMP]]) // CHECK-NEXT: ret void @@ -226,3 +228,28 @@ namespace test8 { template int X::foo<int>(); } + +// rdar://13459289 +namespace test9 { + struct B { + void *p; + B(); + B(const B&); + ~B(); + }; + + void use_block(void (^)()); + void use_block_2(void (^)(), const B &a); + + // Ensuring that creating a non-trivial capture copy expression + // doesn't end up stealing the block registration for the block we + // just parsed. That block must have captures or else it won't + // force registration. Must occur within a block for some reason. + void test() { + B x; + use_block(^{ + int y; + use_block_2(^{ (void)y; }, x); + }); + } +} diff --git a/test/CodeGenCXX/constructor-alias.cpp b/test/CodeGenCXX/constructor-alias.cpp new file mode 100644 index 0000000000..18a4777501 --- /dev/null +++ b/test/CodeGenCXX/constructor-alias.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm -triple mipsel--linux-gnu -mconstructor-aliases -o - %s | FileCheck %s + +// The target attribute code used to get confused with aliases. Make sure +// we don't crash when an alias is used. + +struct B { + B(); +}; +B::B() { +} + +// CHECK: @_ZN1BC1Ev = alias void (%struct.B*)* @_ZN1BC2Ev diff --git a/test/CodeGenCXX/constructor-destructor-return-this.cpp b/test/CodeGenCXX/constructor-destructor-return-this.cpp new file mode 100644 index 0000000000..1ff922de60 --- /dev/null +++ b/test/CodeGenCXX/constructor-destructor-return-this.cpp @@ -0,0 +1,60 @@ +//RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-apple-ios3.0 -target-abi apcs-gnu | FileCheck %s + +// For constructors/desctructors that return 'this', if there exists a callsite +// that returns 'this' and is immediately before the return instruction, make +// sure we are using the return value from the callsite. +// rdar://12818789 + +// CHECK: define linkonce_odr [[A:%.*]] @_ZN11ObjectCacheC1Ev([[A]] %this) unnamed_addr +// CHECK: [[THIS1:%.*]] = call [[A]] @_ZN11ObjectCacheC2Ev( +// CHECK-NEXT: ret [[A]] [[THIS1]] + +// CHECK: define linkonce_odr [[A:%.*]] @_ZN5TimerI11ObjectCacheEC1EPS0_MS0_FvPS1_E([[A]] %this +// CHECK: [[THIS1:%.*]] = call [[A]] @_ZN5TimerI11ObjectCacheEC2EPS0_MS0_FvPS1_E( +// CHECK-NEXT: ret [[A]] [[THIS1]] + +// CHECK: define linkonce_odr [[A:%.*]] @_ZN5TimerI11ObjectCacheED1Ev([[A]] %this) unnamed_addr +// CHECK: [[THIS1:%.*]] = call [[A]] @_ZN5TimerI11ObjectCacheED2Ev( +// CHECK-NEXT: ret [[A]] [[THIS1]] + +// CHECK: define linkonce_odr [[A:%.*]] @_ZN5TimerI11ObjectCacheED2Ev([[A]] %this) unnamed_addr +// CHECK: [[THIS1:%.*]] = call [[B:%.*]] @_ZN9TimerBaseD2Ev( +// CHECK-NEXT: [[THIS2:%.*]] = bitcast [[B]] [[THIS1]] to [[A]] +// CHECK-NEXT: ret [[A]] [[THIS2]] + +class TimerBase { +public: + TimerBase(); + virtual ~TimerBase(); +}; + +template <typename TimerFiredClass> class Timer : public TimerBase { +public: + typedef void (TimerFiredClass::*TimerFiredFunction)(Timer*); + + Timer(TimerFiredClass* o, TimerFiredFunction f) + : m_object(o), m_function(f) { } + +private: + virtual void fired() { (m_object->*m_function)(this); } + + TimerFiredClass* m_object; + TimerFiredFunction m_function; +}; + +class ObjectCache { +public: + explicit ObjectCache(); + ~ObjectCache(); + +private: + Timer<ObjectCache> m_notificationPostTimer; +}; + +inline ObjectCache::ObjectCache() : m_notificationPostTimer(this, 0) { } +inline ObjectCache::~ObjectCache() { } + +ObjectCache *test() { + ObjectCache *dd = new ObjectCache(); + return dd; +} diff --git a/test/CodeGenCXX/coverage.cpp b/test/CodeGenCXX/coverage.cpp new file mode 100644 index 0000000000..1f1611bd8f --- /dev/null +++ b/test/CodeGenCXX/coverage.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -test-coverage -femit-coverage-notes | FileCheck %s + +extern "C" void test_name1() {} +void test_name2() {} + +// CHECK: metadata !"test_name1", metadata !"test_name1", metadata !"",{{.*}}DW_TAG_subprogram +// CHECK: metadata !"test_name2", metadata !"test_name2", metadata !"_Z10test_name2v",{{.*}}DW_TAG_subprogram diff --git a/test/CodeGenCXX/cp-blocks-linetables.cpp b/test/CodeGenCXX/cp-blocks-linetables.cpp new file mode 100644 index 0000000000..d5dd46cbe0 --- /dev/null +++ b/test/CodeGenCXX/cp-blocks-linetables.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -fblocks -g -emit-llvm %s -o - | FileCheck %s +// Ensure that we generate a line table entry for the block cleanup. +// CHECK: define {{.*}} @__main_block_invoke +// CHECK: _NSConcreteStackBlock +// CHECK: = bitcast {{.*}}, !dbg ![[L1:[0-9]+]] +// CHECK-NOT: call {{.*}} @_Block_object_dispose{{.*}}, !dbg ![[L1]] +// CHECK: ret + +void * _NSConcreteStackBlock; +#ifdef __cplusplus +extern "C" void exit(int); +#else +extern void exit(int); +#endif + +enum numbers { + zero, one, two, three, four +}; + +typedef enum numbers (^myblock)(enum numbers); + + +double test(myblock I) { + return I(three); +} + +int main() { + __block enum numbers x = one; + __block enum numbers y = two; + + /* Breakpoint for first Block function. */ + myblock CL = ^(enum numbers z) + { enum numbers savex = x; + { __block enum numbers x = savex; + y = z; + if (y != three) + exit (6); + test ( + /* Breakpoint for second Block function. */ + ^ (enum numbers z) { + if (y != three) { + exit(1); + } + if (x != one) + exit(2); + x = z; + if (x != three) + exit(3); + if (y != three) + exit(4); + return (enum numbers) four; + });} + return x; + }; + + enum numbers res = (enum numbers)test(CL); + + if (res != one) + exit (5); + return 0; +} diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp index 8d9fce040f..d683493a83 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 0000000000..2ea9acda48 --- /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 0000000000..a7141d133b --- /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 0000000000..ef78c434e3 --- /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-artificial-arg.cpp b/test/CodeGenCXX/debug-info-artificial-arg.cpp index e9d8a4d28e..ff0f6638f6 100644 --- a/test/CodeGenCXX/debug-info-artificial-arg.cpp +++ b/test/CodeGenCXX/debug-info-artificial-arg.cpp @@ -22,9 +22,8 @@ int main(int argc, char **argv) { A reallyA (500); } -// FIXME: The numbers are truly awful. -// CHECK: ![[ARTARG:.*]] = metadata !{i32 786447, i32 0, metadata !"", i32 0, i32 0, i64 64, i64 64, i64 0, i32 1088, metadata ![[CLASSTYPE:.*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from A] -// CHECK: ![[CLASSTYPE]] = metadata !{i32 {{.*}}, null, metadata !"A", metadata !{{.*}}, i32 8, i64 128, i64 64, i32 0, i32 0, null, metadata !{{.*}}, i32 0, metadata ![[CLASSTYPE]], null} ; [ DW_TAG_class_type ] -// CHECK: metadata ![[CLASSTYPE]], metadata !"A", metadata !"A", metadata !"", metadata !{{.*}}, i32 12, metadata !{{.*}}, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !{{.*}}, i32 12} ; [ DW_TAG_subprogram ] -// CHECK: metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata ![[FUNCTYPE:.*]], i32 0, i32 0} ; [ DW_TAG_subroutine_type ] -// CHECK: ![[FUNCTYPE]] = metadata !{null, metadata ![[ARTARG]], metadata !{{.*}}, metadata !{{.*}}} +// CHECK: ![[ARTARG:.*]] = {{.*}} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from A] +// CHECK: ![[CLASSTYPE:.*]] = {{.*}} ; [ DW_TAG_class_type ] [A] +// CHECK: metadata ![[CLASSTYPE]], {{.*}} ; [ DW_TAG_subprogram ] [line 12] [A] +// CHECK: metadata [[FUNCTYPE:![0-9]*]], i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +// CHECK: [[FUNCTYPE]] = metadata !{null, metadata ![[ARTARG]], metadata !{{.*}}, metadata !{{.*}}} diff --git a/test/CodeGenCXX/debug-info-byval.cpp b/test/CodeGenCXX/debug-info-byval.cpp index 56ffe13237..e6317fc2de 100644 --- a/test/CodeGenCXX/debug-info-byval.cpp +++ b/test/CodeGenCXX/debug-info-byval.cpp @@ -23,7 +23,7 @@ void foo(EVT e); EVT bar(); void get(int *i, unsigned dl, VAL v, VAL *p, unsigned n, EVT missing_arg) { -//CHECK: .asciz "missing_arg" +//CHECK: .{{asciz|string}} "missing_arg" EVT e = bar(); if (dl == n) foo(missing_arg); diff --git a/test/CodeGenCXX/debug-info-char16.cpp b/test/CodeGenCXX/debug-info-char16.cpp index 34cfb29192..06a05b31dd 100644 --- a/test/CodeGenCXX/debug-info-char16.cpp +++ b/test/CodeGenCXX/debug-info-char16.cpp @@ -3,4 +3,4 @@ // 16 is DW_ATE_UTF (0x10) encoding attribute. char16_t char_a = u'h'; -// CHECK: !{{.*}} = metadata !{i32 {{.*}}, null, metadata !"char16_t", null, i32 0, i64 16, i64 16, i64 0, i32 0, i32 16} ; [ DW_TAG_base_type ] +// CHECK: !{{.*}} = {{.*}} ; [ DW_TAG_base_type ] [char16_t] diff --git a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp index 5d1b3a5c28..04fe7a03e1 100644 --- a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp +++ b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp @@ -19,6 +19,6 @@ protected: Test t; -// CHECK: metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata {{.*}} [ DW_TAG_pointer_type ] -// CHECK: metadata !"data", metadata !{{.*}}, i32 14, i64 32, i64 32, i32 0, i32 0 -// CHECK-NOT: metadata !"data", metadata {{.*}}, i32 14, i64 0, i64 0, i32 0, i32 4, +// CHECK: ; [ DW_TAG_pointer_type ] +// CHECK: ; [ DW_TAG_structure_type ] [data] +// CHECK-NOT: ; [ DW_TAG_structure_type ] [data] diff --git a/test/CodeGenCXX/debug-info-enum-class.cpp b/test/CodeGenCXX/debug-info-enum-class.cpp index 7bbaa749f9..929327b798 100644 --- a/test/CodeGenCXX/debug-info-enum-class.cpp +++ b/test/CodeGenCXX/debug-info-enum-class.cpp @@ -9,10 +9,10 @@ B b; C c; D d; -// CHECK: metadata !{i32 {{.*}}, null, metadata !"A", metadata ![[FILE:.*]], i32 3, i64 32, i64 32, i32 0, i32 0, metadata !{{.*}}, metadata !{{.*}}, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] -// CHECK: metadata !{i32 {{.*}}, null, metadata !"B", metadata ![[FILE]], i32 4, i64 64, i64 64, i32 0, i32 0, metadata !{{.*}}, metadata !{{.*}}, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] -// CHECK: metadata !{i32 {{.*}}, null, metadata !"C", metadata ![[FILE]], i32 5, i64 32, i64 32, i32 0, i32 0, null, metadata !{{.*}}, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] -// CHECK: metadata !{i32 {{.*}}, null, metadata !"D", metadata ![[FILE]], i32 6, i64 16, i64 16, i32 0, i32 4, null, null, i32 0} ; [ DW_TAG_enumeration_type ] +// CHECK: ; [ DW_TAG_enumeration_type ] [A] [line 3, size 32, align 32, offset 0] [from int] +// CHECK: ; [ DW_TAG_enumeration_type ] [B] [line 4, size 64, align 64, offset 0] [from long unsigned int] +// CHECK: ; [ DW_TAG_enumeration_type ] [C] [line 5, size 32, align 32, offset 0] [from ] +// CHECK: ; [ DW_TAG_enumeration_type ] [D] [line 6, size 16, align 16, offset 0] [fwd] [from ] namespace PR14029 { // Make sure this doesn't crash/assert. diff --git a/test/CodeGenCXX/debug-info-fwd-ref.cpp b/test/CodeGenCXX/debug-info-fwd-ref.cpp index 69dd192bd9..c479506c61 100644 --- a/test/CodeGenCXX/debug-info-fwd-ref.cpp +++ b/test/CodeGenCXX/debug-info-fwd-ref.cpp @@ -18,8 +18,7 @@ int main(int argc, char** argv) { // Make sure we have two DW_TAG_structure_types for baz and bar and no forward // references. -// CHECK: metadata !{i32 {{.*}}, null, metadata !"bar", metadata ![[FILE:.*]], i32 8, i64 128, i64 64, i32 0, i32 0, null, metadata !{{.*}}, i32 0, null, null} ; [ DW_TAG_structure_type ] -// CHECK: metadata !{i32 {{.*}}, null, metadata !"baz", metadata ![[FILE]], i32 3, i64 32, i64 32, i32 0, i32 0, null, metadata !{{.*}}, i32 0, null, null} ; [ DW_TAG_structure_type ] -// CHECK-NOT: metadata !{i32 {{.*}}, null, metadata !"bar", metadata ![[FILE]], i32 8, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 0, i32 0} ; [ DW_TAG_structure_type ] -// CHECK-NOT: metadata !{i32 {{.*}}, null, metadata !"baz", metadata ![[FILE]], i32 3, i64 0, i64 0, i32 0, i32 4, null, null, i32 0, null, null} ; [ DW_TAG_structure_type ] - +// CHECK-NOT: [fwd] +// CHECK: [ DW_TAG_structure_type ] [bar] +// CHECK: [ DW_TAG_structure_type ] [baz] +// CHECK-NOT: [fwd] diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp index 27f5eae978..13a7914b7b 100644 --- a/test/CodeGenCXX/debug-info-namespace.cpp +++ b/test/CodeGenCXX/debug-info-namespace.cpp @@ -1,12 +1,37 @@ -// RUN: %clang -g -S -fverbose-asm %s -o - | FileCheck %s +// RUN: %clang -g -S -emit-llvm %s -o - | FileCheck %s -// CHECK: TAG_namespace namespace A { - enum numbers { - ZERO, - ONE - }; +#line 1 "foo.cpp" +namespace B { +int i; +} +using namespace B; } using namespace A; -numbers n; + +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]], metadata [[CTXT:![0-9]*]], {{.*}} ; [ DW_TAG_namespace ] [B] [line 1] +// CHECK: [[CTXT]] = {{.*}}, metadata [[FILE]], null, {{.*}} ; [ DW_TAG_namespace ] [A] [line 3] +// 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/debug-info-nullptr.cpp b/test/CodeGenCXX/debug-info-nullptr.cpp index 4cc7e546d8..42e9741d19 100644 --- a/test/CodeGenCXX/debug-info-nullptr.cpp +++ b/test/CodeGenCXX/debug-info-nullptr.cpp @@ -4,4 +4,4 @@ void foo() { decltype(nullptr) t = 0; } -// CHECK: metadata !{i32 {{.*}}, null, metadata !"nullptr_t", null, i32 0, i64 0, i64 0, i64 0, i32 0, i32 0} ; [ DW_TAG_unspecified_type ] +// CHECK: [ DW_TAG_unspecified_type ] [nullptr_t] diff --git a/test/CodeGenCXX/debug-info-same-line.cpp b/test/CodeGenCXX/debug-info-same-line.cpp new file mode 100644 index 0000000000..ad245031ab --- /dev/null +++ b/test/CodeGenCXX/debug-info-same-line.cpp @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -g -emit-llvm -o - %s | FileCheck %s + +// Make sure that clang outputs distinct debug info for a function +// that is inlined twice on the same line. Otherwise it would appear +// as if the function was only inlined once. + +#define INLINE inline __attribute__((always_inline)) + +INLINE int +product (int x, int y) +{ + int result = x * y; + return result; +} + +INLINE int +sum (int a, int b) +{ + int result = a + b; + return result; +} + +int +strange_max (int m, int n) +{ + if (m > n) + return m; + else if (n > m) + return n; + else + return 0; +} + +int +foo (int i, int j) +{ + if (strange_max (i, j) == i) + return product (i, j); + else if (strange_max (i, j) == j) + return sum (i, j); + else + return product (sum (i, i), sum (j, j)); +} + +int +main(int argc, char const *argv[]) +{ + + int array[3]; + int n; + + array[0] = foo (1238, 78392); + array[1] = foo (379265, 23674); + array[2] = foo (872934, 234); + + n = strange_max(array[0], strange_max(array[1], array[2])); + + return n & 0xf; +} + +// CHECK: define {{.*}} @_Z3fooii +// i +// CHECK: call void @llvm.dbg.declare +// j +// CHECK: call void @llvm.dbg.declare +// x +// CHECK: call void @llvm.dbg.declare +// y +// CHECK: call void @llvm.dbg.declare +// result +// CHECK: call void @llvm.dbg.declare + +// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD:[0-9]+]]), !dbg ![[A_DI:[0-9]+]] +// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD:[0-9]+]]), !dbg ![[B_DI:[0-9]+]] +// result +// CHECK: call void @llvm.dbg.declare + +// We want to see a distinct !dbg node. +// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg ![[A_DI]] +// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg !{{.*}} +// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg ![[B_DI]] +// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg !{{.*}} +// result +// CHECK: call void @llvm.dbg.declare + +// CHECK: define {{.*}} @main +// CHECK: call {{.*}} @_Z3fooii +// CHECK: call {{.*}} @_Z3fooii +// CHECK: call {{.*}} @_Z3fooii +// CHECK: store +// CHECK: getelementptr +// We want to see the same !dbg node for non-inlined functions. +// Needed for GDB compatibility. +// CHECK: load {{.*}} !dbg ![[DBG:.*]] +// CHECK: load {{.*}} !dbg ![[DBG]] +// CHECK: load {{.*}} !dbg ![[DBG]] +// CHECK: call {{.*}} @_Z11strange_maxii(i32 {{.*}}, i32 {{.*}}), !dbg ![[DBG]] +// CHECK: call {{.*}} @_Z11strange_maxii(i32 {{.*}}, i32 {{.*}}), !dbg ![[DBG]] diff --git a/test/CodeGenCXX/debug-info-static-fns.cpp b/test/CodeGenCXX/debug-info-static-fns.cpp index 376f28825b..136261cdbc 100644 --- a/test/CodeGenCXX/debug-info-static-fns.cpp +++ b/test/CodeGenCXX/debug-info-static-fns.cpp @@ -7,4 +7,4 @@ namespace A { } // Verify that a is present and mangled. -// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"a", metadata !"a", metadata !"_ZN1AL1aEi", metadata !{{.*}}, i32 4, metadata !{{.*}}, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_ZN1AL1aEi, null, null, metadata !{{.*}}, i32 4} ; [ DW_TAG_subprogram ] +// CHECK: metadata !"_ZN1AL1aEi", {{.*}}, i32 (i32)* @_ZN1AL1aEi, {{.*}} ; [ DW_TAG_subprogram ] [line 4] [local] [def] [a] diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp index 6208c80aeb..6be7f9bd24 100644 --- a/test/CodeGenCXX/debug-info-template-member.cpp +++ b/test/CodeGenCXX/debug-info-template-member.cpp @@ -16,6 +16,6 @@ private: MyClass m; -// CHECK: metadata !{i32 {{.*}}, null, metadata !"MyClass", metadata {{.*}}, i32 {{.*}}, i64 8, i64 8, i32 0, i32 0, null, metadata [[C_MEM:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] -// CHECK: [[C_MEM]] = metadata !{metadata {{.*}}, metadata [[C_TEMP:.*]], metadata {{.*}}} -// CHECK: [[C_TEMP]] = metadata !{i32 {{.*}}, i32 0, metadata {{.*}}, metadata !"add<2>", metadata !"add<2>", metadata !"_ZN7MyClass3addILi2EEEii", metadata {{.*}} +// CHECK: metadata [[C_MEM:![0-9]*]], i32 0, null, null} ; [ DW_TAG_class_type ] [MyClass] +// CHECK: [[C_MEM]] = metadata !{metadata {{.*}}, metadata [[C_TEMP:![0-9]*]], metadata {{.*}}} +// CHECK: [[C_TEMP]] = {{.*}} ; [ DW_TAG_subprogram ] [line 11] [private] [add<2>] diff --git a/test/CodeGenCXX/debug-info-template-quals.cpp b/test/CodeGenCXX/debug-info-template-quals.cpp index 283874abbc..335c8abb11 100644 --- a/test/CodeGenCXX/debug-info-template-quals.cpp +++ b/test/CodeGenCXX/debug-info-template-quals.cpp @@ -15,12 +15,13 @@ void foo (const char *c) { str.assign(c, str); } -// CHECK: [[P:.*]] = metadata !{i32 {{.*}}, metadata [[CON:.*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ] -// CHECK: [[CON]] = metadata !{i32 {{.*}}, metadata [[CH:.*]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from char] -// CHECK: [[CH]] = metadata !{i32 {{.*}}, metadata !"char", {{.*}}} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char] -// CHECK: metadata !{i32 {{.*}}, metadata !"_ZN12basic_stringIcE6assignEPKcRKS0_", metadata ![[FILE:.*]], i32 7, metadata [[TYPE:.*]], i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, %struct.basic_string* (%struct.basic_string*, i8*, %struct.basic_string*)* @_ZN12basic_stringIcE6assignEPKcRKS0_, null, metadata !{{.*}}, metadata !{{.*}}, i32 8} ; [ DW_TAG_subprogram ] [line 7] [def] [scope 8] [assign] -// CHECK: [[TYPE]] = metadata !{i32 {{.*}}, null, metadata [[ARGS:.*]], i32 0, i32 0} +// CHECK: [[P:.*]] = {{.*}}, metadata [[CON:![0-9]*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ] +// CHECK: [[CON]] = {{.*}}, metadata [[CH:![0-9]*]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from char] +// CHECK: [[CH]] = {{.*}} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char] + +// CHECK: {{.*}} metadata [[TYPE:![0-9]*]], {{.*}}, metadata !{{[0-9]*}}, metadata !{{[0-9]*}}, i32 8} ; [ DW_TAG_subprogram ] [line 7] [def] [scope 8] [assign] +// CHECK: [[TYPE]] = metadata !{i32 {{.*}}, metadata [[ARGS:.*]], i32 0, i32 0} ; [ DW_TAG_subroutine_type ] // CHECK: [[ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata [[P]], metadata [[R:.*]]} -// CHECK: [[BS:.*]] = metadata !{i32 {{.*}}, null, metadata !"basic_string<char>", metadata ![[FILE]], i32 4, i64 8, i64 8, i32 0, i32 0, null, metadata !{{.*}}, i32 0, null, metadata !{{.*}}} ; [ DW_TAG_structure_type ] [basic_string<char>] [line 4, size 8, align 8, offset 0] [from ] -// CHECK: [[R]] = metadata !{i32 {{.*}}, null, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata [[CON2:.*]]} ; [ DW_TAG_reference_type ] [line 0, size 0, align 0, offset 0] [from ] -// CHECK: [[CON2]] = metadata !{i32 {{.*}}, metadata [[BS]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from basic_string<char>] +// CHECK: [[BS:.*]] = {{.*}} ; [ DW_TAG_structure_type ] [basic_string<char>] [line 4, size 8, align 8, offset 0] [from ] +// CHECK: [[R]] = {{.*}}, metadata [[CON2:![0-9]*]]} ; [ DW_TAG_reference_type ] [line 0, size 0, align 0, offset 0] [from ] +// CHECK: [[CON2]] = {{.*}}, metadata [[BS]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from basic_string<char>] diff --git a/test/CodeGenCXX/debug-info-union-template.cpp b/test/CodeGenCXX/debug-info-union-template.cpp new file mode 100644 index 0000000000..f5e6e14a71 --- /dev/null +++ b/test/CodeGenCXX/debug-info-union-template.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-linux-gnu %s -o - | FileCheck %s + +// Make sure that the union type has template parameters. + +namespace PR15637 { + template <typename T> union Value { int a; }; + void g(float value) { + Value<float> tempValue; + } + Value<float> f; +} + +// CHECK: {{.*}}, metadata !"Value<float>", {{.*}}, null, metadata [[TTPARAM:.*]]} ; [ DW_TAG_union_type ] [Value<float>] +// CHECK: [[TTPARAM]] = metadata !{metadata [[PARAMS:.*]]} +// CHECK: [[PARAMS]] = metadata !{{{.*}}metadata !"T",{{.*}}} ; [ DW_TAG_template_type_parameter ] diff --git a/test/CodeGenCXX/debug-info-union.cpp b/test/CodeGenCXX/debug-info-union.cpp index 588fa20336..0aa48dc8a5 100644 --- a/test/CodeGenCXX/debug-info-union.cpp +++ b/test/CodeGenCXX/debug-info-union.cpp @@ -10,7 +10,7 @@ union E { E e; -// CHECK: metadata !{i32 {{.*}}, null, metadata !"E", metadata !{{.*}}, i32 3, i64 32, i64 32, i64 0, i32 0, null, metadata !{{.*}}, i32 0, null} ; [ DW_TAG_union_type ] -// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"bb", metadata !"bb", metadata !"_ZN1E2bbEv", metadata !{{.*}}, i32 6, metadata !{{.*}}, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !{{.*}}, i32 6} ; [ DW_TAG_subprogram ] -// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"aa", metadata !"aa", metadata !"_ZN1E2aaEv", metadata !{{.*}}, i32 7, metadata !{{.*}}, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !{{.*}}, i32 7} ; [ DW_TAG_subprogram ] -// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"E", metadata !"E", metadata !"", metadata !{{.*}}, i32 8, metadata !{{.*}}, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !{{.*}}, i32 8} ; [ DW_TAG_subprogram ] +// CHECK: {{.*}} ; [ DW_TAG_union_type ] [E] [line 3, size 32, align 32, offset 0] +// CHECK: {{.*}} ; [ DW_TAG_subprogram ] [line 6] [bb] +// CHECK: {{.*}} ; [ DW_TAG_subprogram ] [line 7] [aa] +// CHECK: {{.*}} ; [ DW_TAG_subprogram ] [line 8] [E] diff --git a/test/CodeGenCXX/debug-info-use-after-free.cpp b/test/CodeGenCXX/debug-info-use-after-free.cpp index 9757ca4d37..852e148956 100644 --- a/test/CodeGenCXX/debug-info-use-after-free.cpp +++ b/test/CodeGenCXX/debug-info-use-after-free.cpp @@ -192,6 +192,7 @@ __gnu_cxx { public: typedef _EqualKey key_equal; + typedef void key_type; }; using std::equal_to; @@ -217,7 +218,7 @@ __gnu_cxx { _Alloc > _Ht; public: - typename _Ht::key_type; + typedef typename _Ht::key_type key_type; typedef typename _Ht::key_equal key_equal; diff --git a/test/CodeGenCXX/debug-info-zero-length-arrays.cpp b/test/CodeGenCXX/debug-info-zero-length-arrays.cpp index 4faed5f87d..fb47022b64 100644 --- a/test/CodeGenCXX/debug-info-zero-length-arrays.cpp +++ b/test/CodeGenCXX/debug-info-zero-length-arrays.cpp @@ -6,8 +6,7 @@ class A { }; A a; -// CHECK: !{{.*}} = metadata !{i32 {{.*}}, metadata {{.*}}, metadata !"x", metadata {{.*}}, i32 5, i64 0, i64 0, i64 0, i32 1, metadata [[ARRAY_TYPE:.*]]} ; [ DW_TAG_member ] -// CHECK: [[ARRAY_TYPE]] = metadata !{i32 {{.*}}, null, metadata !"", null, i32 0, i64 0, i64 32, i32 0, i32 0, metadata [[BASE_TYPE:.*]], metadata [[ELEM_TYPE:.*]], i32 0, i32 0} ; [ DW_TAG_array_type ] -// CHECK: [[BASE_TYPE]] = metadata !{i32 {{.*}}, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +// CHECK: metadata [[ARRAY_TYPE:![0-9]*]]} ; [ DW_TAG_member ] [x] +// CHECK: metadata [[ELEM_TYPE:![0-9]*]], i32 0, i32 0} ; [ DW_TAG_array_type ] [line 0, size 0, align 32, offset 0] [from int] // CHECK: [[ELEM_TYPE]] = metadata !{metadata [[SUBRANGE:.*]]} // CHECK: [[SUBRANGE]] = metadata !{i32 786465, i64 0, i64 -1} ; [ DW_TAG_subrange_type ] [unbounded] diff --git a/test/CodeGenCXX/debug-lambda-expressions.cpp b/test/CodeGenCXX/debug-lambda-expressions.cpp index 05ec523c88..39c9a445c4 100644 --- a/test/CodeGenCXX/debug-lambda-expressions.cpp +++ b/test/CodeGenCXX/debug-lambda-expressions.cpp @@ -15,57 +15,57 @@ struct D { D(); D(const D&); int x; }; int d(int x) { D y[10]; [x,y] { return y[x].x; }(); } // Randomness for file. -- 6 -// CHECK: [[FILE:.*]] = metadata !{i32 {{.*}}, metadata !{{.*}}debug-lambda-expressions.cpp{{.*}}; [ DW_TAG_file_type ] +// CHECK: [[FILE:.*]] = {{.*}} [ DW_TAG_file_type ] [{{.*}}debug-lambda-expressions.cpp] // A: 10 -// CHECK: [[A_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], metadata !"a", metadata !"a", metadata !"_Z1av", metadata {{.*}}, i32 [[A_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @_Z1av, null, null, {{.*}} [ DW_TAG_subprogram ] +// CHECK: [[A_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[A_LINE:.*]]] [def] [a] // B: 14 -// CHECK: [[B_FUNC:.*]] = metadata !{i32 786478, i32 0, metadata [[FILE]], metadata !"b", metadata !"b", metadata !"_Z1bi", metadata [[FILE]], i32 [[B_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1bi, null, null, {{.*}} ; [ DW_TAG_subprogram ] +// CHECK: [[B_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[B_LINE:.*]]] [def] [b] // C: 17 -// CHECK: [[C_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], metadata !"c", metadata !"c", metadata !"_Z1ci", metadata [[FILE]], i32 [[C_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1ci, null, null, metadata {{.*}} ; [ DW_TAG_subprogram ] +// CHECK: [[C_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[C_LINE:.*]]] [def] [c] // D: 18 -// CHECK: [[D_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], metadata !"d", metadata !"d", metadata !"_Z1di", metadata [[FILE]], i32 [[D_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1di, null, null, metadata {{.*}} ; [ DW_TAG_subprogram ] +// CHECK: [[D_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[D_LINE:.*]]] [def] [d] // Back to D. -- 24 -// CHECK: [[LAM_D:.*]] = metadata !{i32 {{.*}}, metadata [[D_FUNC]], metadata !"", metadata [[FILE]], i32 [[D_LINE]], i64 352, i64 32, i32 0, i32 0, null, metadata [[LAM_D_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] +// CHECK: [[LAM_D:.*]] = {{.*}}, metadata [[D_FUNC]], {{.*}}, metadata [[LAM_D_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[D_LINE]], // CHECK: [[LAM_D_ARGS]] = metadata !{metadata [[CAP_D_X:.*]], metadata [[CAP_D_Y:.*]], metadata [[CON_LAM_D:.*]], metadata [[DES_LAM_D:.*]]} -// CHECK: [[CAP_D_X]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"x", metadata [[FILE]], i32 [[D_LINE]], i64 32, i64 32, i64 0, i32 1, metadata {{.*}} ; [ DW_TAG_member ] -// CHECK: [[CAP_D_Y]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"y", metadata [[FILE]], i32 [[D_LINE]], i64 320, i64 32, i64 32, i32 1, metadata {{.*}} ; [ DW_TAG_member ] -// CHECK: [[CON_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ] -// CHECK: [[DES_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ] +// CHECK: [[CAP_D_X]] = {{.*}}, metadata [[LAM_D]], {{.*}} [ DW_TAG_member ] [x] [line [[D_LINE]], +// CHECK: [[CAP_D_Y]] = {{.*}}, metadata [[LAM_D]], {{.*}} [ DW_TAG_member ] [y] [line [[D_LINE]], +// CHECK: [[CON_LAM_D]] = {{.*}}, metadata [[LAM_D]], {{.*}} [ DW_TAG_subprogram ] [line [[D_LINE]]] [operator()] +// CHECK: [[DES_LAM_D]] = {{.*}}, metadata [[LAM_D]], {{.*}} [ DW_TAG_subprogram ] [line [[D_LINE]]] [~] // Back to C. -- 55 -// CHECK: [[LAM_C:.*]] = metadata !{i32 {{.*}}, metadata [[C_FUNC]], metadata !"", metadata [[FILE]], i32 [[C_LINE]], i64 64, i64 64, i32 0, i32 0, null, metadata [[LAM_C_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] +// CHECK: [[LAM_C:.*]] = {{.*}}, metadata [[C_FUNC]], {{.*}}, metadata [[LAM_C_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[C_LINE]], // CHECK: [[LAM_C_ARGS]] = metadata !{metadata [[CAP_C:.*]], metadata [[CON_LAM_C:.*]], metadata [[DES_LAM_C:.*]]} // Ignoring the member type for now. -// CHECK: [[CAP_C]] = metadata !{i32 {{.*}}, metadata [[LAM_C]], metadata !"x", metadata [[FILE]], i32 [[C_LINE]], i64 64, i64 64, i64 0, i32 1, metadata {{.*}}} ; [ DW_TAG_member ] -// CHECK: [[CON_LAM_C]] = metadata {{.*}}[[LAM_C]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ] -// CHECK: [[DES_LAM_C]] = metadata {{.*}}[[LAM_C]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ] +// CHECK: [[CAP_C]] = {{.*}}, metadata [[LAM_C]], {{.*}}} ; [ DW_TAG_member ] [x] [line [[C_LINE]], +// CHECK: [[CON_LAM_C]] = {{.*}}, metadata [[LAM_C]], {{.*}} [ DW_TAG_subprogram ] [line [[C_LINE]]] [operator()] +// CHECK: [[DES_LAM_C]] = {{.*}}, metadata [[LAM_C]], {{.*}} [ DW_TAG_subprogram ] [line [[C_LINE]]] [~] // Back to B. -- 67 -// CHECK: [[LAM_B:.*]] = metadata !{i32 {{.*}}, metadata [[B_FUNC]], metadata !"", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i32 0, i32 0, null, metadata [[LAM_B_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] +// CHECK: [[LAM_B:.*]] = {{.*}}, metadata [[B_FUNC]], {{.*}}, metadata [[LAM_B_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[B_LINE]], // CHECK: [[LAM_B_ARGS]] = metadata !{metadata [[CAP_B:.*]], metadata [[CON_LAM_B:.*]], metadata [[DES_LAM_B:.*]]} -// CHECK: [[CAP_B]] = metadata !{i32 {{.*}}, metadata [[LAM_B]], metadata !"x", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i64 0, i32 1, metadata {{.*}}} ; [ DW_TAG_member ] -// CHECK: [[CON_LAM_B]] = metadata {{.*}}[[LAM_B]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ] -// CHECK: [[DES_LAM_B]] = metadata {{.*}}[[LAM_B]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ] +// CHECK: [[CAP_B]] = {{.*}}, metadata [[LAM_B]], {{.*}}} ; [ DW_TAG_member ] [x] [line [[B_LINE]], +// CHECK: [[CON_LAM_B]] = {{.*}}, metadata [[LAM_B]], {{.*}} [ DW_TAG_subprogram ] [line [[B_LINE]]] [operator()] +// CHECK: [[DES_LAM_B]] = {{.*}}, metadata [[LAM_B]], {{.*}} [ DW_TAG_subprogram ] [line [[B_LINE]]] [~] // Back to A. -- 78 -// CHECK: [[LAM_A:.*]] = metadata !{i32 {{.*}}, metadata [[A_FUNC]], metadata !"", metadata [[FILE]], i32 [[A_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata [[LAM_A_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] +// CHECK: [[LAM_A:.*]] = {{.*}}, metadata [[A_FUNC]], {{.*}}, metadata [[LAM_A_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[A_LINE]], // CHECK: [[LAM_A_ARGS]] = metadata !{metadata [[CON_LAM_A:.*]], metadata [[DES_LAM_A:.*]]} -// CHECK: [[CON_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ] -// CHECK: [[DES_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ] +// CHECK: [[CON_LAM_A]] = {{.*}}, metadata [[LAM_A]], {{.*}} [ DW_TAG_subprogram ] [line [[A_LINE]]] [operator()] +// CHECK: [[DES_LAM_A]] = {{.*}}, metadata [[LAM_A]], {{.*}} [ DW_TAG_subprogram ] [line [[A_LINE]]] [~] // CVAR: -// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"cvar", metadata !"cvar", metadata !"", metadata [[FILE]], i32 [[CVAR_LINE:.*]], metadata ![[CVAR_T:.*]], i32 0, i32 1, %class.anon.0* @cvar, null} ; [ DW_TAG_variable ] -// CHECK: [[CVAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata [[FILE]], i32 [[CVAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata ![[CVAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] +// CHECK: {{.*}} metadata [[CVAR_T:![0-9]*]], {{.*}} ; [ DW_TAG_variable ] [cvar] [line [[CVAR_LINE:[0-9]*]]] +// CHECK: [[CVAR_T]] = {{.*}}, metadata ![[CVAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[CVAR_LINE]], // CHECK: [[CVAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata !{{.*}}} // VAR: -// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"var", metadata !"var", metadata !"", metadata [[FILE]], i32 [[VAR_LINE:.*]], metadata ![[VAR_T:.*]], i32 1, i32 1, %class.anon* @var, null} ; [ DW_TAG_variable ] -// CHECK: [[VAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata [[FILE]], i32 [[VAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata ![[VAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] +// CHECK: {{.*}} metadata [[VAR_T:![0-9]*]], {{.*}} ; [ DW_TAG_variable ] [var] [line [[VAR_LINE:[0-9]*]]] +// CHECK: [[VAR_T]] = {{.*}}, metadata [[VAR_ARGS:![0-9]*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[VAR_LINE]], // CHECK: [[VAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata !{{.*}}} diff --git a/test/CodeGenCXX/debug-lambda-this.cpp b/test/CodeGenCXX/debug-lambda-this.cpp index 0844da0a81..e7155e76a1 100644 --- a/test/CodeGenCXX/debug-lambda-this.cpp +++ b/test/CodeGenCXX/debug-lambda-this.cpp @@ -12,4 +12,4 @@ int D::d(int x) { }(); } -// CHECK: metadata !{i32 {{.*}}, metadata !"this", metadata !{{.*}}, i32 11, i64 64, i64 64, i64 0, i32 1, metadata !{{.*}}} ; [ DW_TAG_member ] [this] [line 11, size 64, align 64, offset 0] [private] [from ] +// CHECK: {{.*}} [ DW_TAG_member ] [this] [line 11, size 64, align 64, offset 0] [private] [from ] diff --git a/test/CodeGenCXX/extern-c.cpp b/test/CodeGenCXX/extern-c.cpp index a8c4f0cdbd..5899b9348c 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 a99840290a..0f39784929 100644 --- a/test/CodeGenCXX/inheriting-constructor.cpp +++ b/test/CodeGenCXX/inheriting-constructor.cpp @@ -1,11 +1,28 @@ // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s -// XFAIL: * - // PR12219 struct A { A(int); virtual ~A(); }; struct B : A { using A::A; ~B(); }; 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 + +// 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 0000000000..4077af6d8e --- /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 0ac9b3f121..d03ba52649 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 63bc4a9eb3..87e04c645e 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 e16fe936bc..10e68248dc 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" @@ -78,3 +96,16 @@ namespace space { void use() { space::foo(42); } + +// PR13455 +typedef void (*FunctionPointer)(void); + +template <FunctionPointer function> +void FunctionPointerTemplate() { + function(); +} + +void spam() { + FunctionPointerTemplate<spam>(); +// CHECK: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ" +} diff --git a/test/CodeGenCXX/mangle-ms-vector-types.cpp b/test/CodeGenCXX/mangle-ms-vector-types.cpp new file mode 100644 index 0000000000..64cb7250a4 --- /dev/null +++ b/test/CodeGenCXX/mangle-ms-vector-types.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fms-extensions -ffreestanding -target-feature +avx -emit-llvm %s -o - -cxx-abi microsoft -triple=i686-pc-win32 | FileCheck %s + +#include <xmmintrin.h> +#include <emmintrin.h> +#include <immintrin.h> + +void foo64(__m64) {} +// CHECK: define void @"\01?foo64@@YAXT__m64@@@Z" + +void foo128(__m128) {} +// CHECK: define void @"\01?foo128@@YAXT__m128@@@Z" + +void foo128d(__m128d) {} +// CHECK: define void @"\01?foo128d@@YAXU__m128d@@@Z" + +void foo128i(__m128i) {} +// CHECK: define void @"\01?foo128i@@YAXT__m128i@@@Z" + +void foo256(__m256) {} +// CHECK: define void @"\01?foo256@@YAXT__m256@@@Z" + +void foo256d(__m256d) {} +// CHECK: define void @"\01?foo256d@@YAXU__m256d@@@Z" + +void foo256i(__m256i) {} +// CHECK: define void @"\01?foo256i@@YAXT__m256i@@@Z" + +// We have a custom mangling for vector types not standardized by Intel. +void foov8hi(__v8hi) {} +// CHECK: define void @"\01?foov8hi@@YAXT__clang_vec8_F@@@Z" + +// Clang does not support vectors of complex types, so we can't test the +// mangling of them. diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp index 6441d67a75..1b98a84823 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 new file mode 100644 index 0000000000..3fffc9d72c --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp @@ -0,0 +1,363 @@ +// 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; + memptr = &POD::b; + if (memptr) + memptr = 0; +// Check that member pointers use the right offsets and that null is -1. +// CHECK: define void @"\01?podMemPtrs@@YAXXZ"() #0 { +// CHECK: %[[memptr:.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 0, i32* %[[memptr]], align 4 +// CHECK-NEXT: store i32 4, i32* %[[memptr]], align 4 +// CHECK-NEXT: %[[memptr_val:.*]] = load i32* %[[memptr]], align 4 +// CHECK-NEXT: %{{.*}} = icmp ne i32 %[[memptr_val]], -1 +// CHECK-NEXT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} +// CHECK: store i32 -1, i32* %[[memptr]], align 4 +// CHECK: ret void +// CHECK: } +} + +void polymorphicMemPtrs() { + int Polymorphic::*memptr; + memptr = &Polymorphic::a; + memptr = &Polymorphic::b; + if (memptr) + memptr = 0; +// Member pointers for polymorphic classes include the vtable slot in their +// offset and use 0 to represent null. +// CHECK: define void @"\01?polymorphicMemPtrs@@YAXXZ"() #0 { +// CHECK: %[[memptr:.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 4, i32* %[[memptr]], align 4 +// CHECK-NEXT: store i32 8, i32* %[[memptr]], align 4 +// CHECK-NEXT: %[[memptr_val:.*]] = load i32* %[[memptr]], align 4 +// CHECK-NEXT: %{{.*}} = icmp ne i32 %[[memptr_val]], 0 +// CHECK-NEXT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} +// CHECK: store i32 0, i32* %[[memptr]], align 4 +// 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 0000000000..060c172858 --- /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 0000000000..fd2000be6e --- /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 0000000000..d3ef9f7068 --- /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 fca0509892..c20faaaf2e 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 f04185b23f..ba8a86881a 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 0000000000..17299dcb7b --- /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 9294d20e72..8710c76e0b 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 503c7d2a1f..c9ba2f6153 100644 --- a/test/CodeGenObjC/arc-blocks.m +++ b/test/CodeGenObjC/arc-blocks.m @@ -80,13 +80,14 @@ void test3(void (^sink)(id*)) { // CHECK-NEXT: bitcast // CHECK-NEXT: getelementptr // CHECK-NEXT: [[BLOCK:%.*]] = bitcast - // CHECK-NEXT: [[T0:%.*]] = load i8** [[STRONG]] - // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP]] + // CHECK-NEXT: [[V:%.*]] = load i8** [[STRONG]] + // CHECK-NEXT: store i8* [[V]], i8** [[TEMP]] // CHECK-NEXT: [[F0:%.*]] = load i8** // CHECK-NEXT: [[F1:%.*]] = bitcast i8* [[F0]] to void (i8*, i8**)* // CHECK-NEXT: call void [[F1]](i8* [[BLOCK]], i8** [[TEMP]]) // CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]] // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) + // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V]]) [[NUW]] // CHECK-NEXT: [[T2:%.*]] = load i8** [[STRONG]] // CHECK-NEXT: store i8* [[T1]], i8** [[STRONG]] // CHECK-NEXT: call void @objc_release(i8* [[T2]]) @@ -127,7 +128,7 @@ void test4(void) { // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8) // CHECK-NEXT: [[T0:%.*]] = load i8** [[SLOT]] // CHECK-NEXT: call void @objc_release(i8* [[T0]]) - // CHECK-NEXT: ret void + // CHECK: ret void // CHECK: define internal void @__Block_byref_object_copy_ // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6 @@ -206,7 +207,7 @@ void test6(void) { // CHECK: [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8* // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8) // CHECK-NEXT: call void @objc_destroyWeak(i8** [[SLOT]]) - // CHECK-NEXT: ret void + // CHECK: ret void // CHECK: define internal void @__Block_byref_object_copy_ // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6 @@ -255,14 +256,14 @@ void test7(void) { // CHECK: call void @test7_helper( // CHECK-NEXT: call void @objc_destroyWeak(i8** {{%.*}}) // CHECK-NEXT: call void @objc_destroyWeak(i8** [[VAR]]) - // CHECK-NEXT: ret void + // CHECK: ret void // CHECK: define internal void @__test7_block_invoke // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* {{%.*}}, i32 0, i32 5 // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[SLOT]]) // CHECK-NEXT: call void @test7_consume(i8* [[T0]]) // CHECK-NEXT: call void @objc_release(i8* [[T0]]) - // CHECK-NEXT: ret void + // CHECK: ret void // CHECK: define internal void @__copy_helper_block_ // CHECK: getelementptr @@ -295,7 +296,7 @@ void test7(void) { // CHECK-NEXT: [[T1:%.*]] = load [[TEST8]]** [[D0]] // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST8]]* [[T1]] to i8* // CHECK-NEXT: call void @objc_release(i8* [[T2]]) -// CHECK-NEXT: ret void +// CHECK: ret void extern void test8_helper(void (^)(void)); test8_helper(^{ (void) self; }); @@ -353,7 +354,7 @@ void test10a(void) { // CHECK-NEXT: [[T1:%.*]] = load void ()** [[SLOT]] // CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8* // CHECK-NEXT: call void @objc_release(i8* [[T2]]) - // CHECK-NEXT: ret void + // CHECK: ret void } // <rdar://problem/10402698>: do this copy and dispose with @@ -373,7 +374,7 @@ void test10a(void) { // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* // CHECK-NEXT: store void ()* [[T3]], void ()** [[D2]], align 8 -// CHECK-NEXT: ret void +// CHECK: ret void // CHECK: define internal void @__Block_byref_object_dispose // CHECK: [[T0:%.*]] = load i8** {{%.*}} @@ -417,7 +418,7 @@ void test10b(void) { // CHECK-NEXT: [[T1:%.*]] = load void ()** [[SLOT]] // CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8* // CHECK-NEXT: call void @objc_release(i8* [[T2]]) - // CHECK-NEXT: ret void + // CHECK: ret void } // rdar://problem/10088932 @@ -437,7 +438,7 @@ void test11a(void) { // CHECK-NEXT: call void @test11_helper(i8* [[T4]]) // CHECK-NEXT: [[T5:%.*]] = bitcast void ()* [[T3]] to i8* // CHECK-NEXT: call void @objc_release(i8* [[T5]]) - // CHECK-NEXT: ret void + // CHECK: ret void } void test11b(void) { int x; @@ -455,7 +456,7 @@ void test11b(void) { // CHECK-NEXT: store i8* [[T4]], i8** [[B]], align 8 // CHECK-NEXT: [[T5:%.*]] = load i8** [[B]] // CHECK-NEXT: call void @objc_release(i8* [[T5]]) - // CHECK-NEXT: ret void + // CHECK: ret void } // rdar://problem/9979150 @@ -649,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-foreach.m b/test/CodeGenObjC/arc-foreach.m index b81cbbd74a..176b28d3a2 100644 --- a/test/CodeGenObjC/arc-foreach.m +++ b/test/CodeGenObjC/arc-foreach.m @@ -84,7 +84,8 @@ void test0(NSArray *array) { // CHECK-LP64: define internal void @__test0_block_invoke // CHECK-LP64: [[BLOCK:%.*]] = bitcast i8* {{%.*}} to [[BLOCK_T]]* -// CHECK-LP64-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 +// CHECK-LP64-NOT: ret +// CHECK-LP64: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK-LP64-NEXT: [[T2:%.*]] = load i8** [[T0]], align 8 // CHECK-LP64-NEXT: call void @use(i8* [[T2]]) diff --git a/test/CodeGenObjC/arc-linetable.m b/test/CodeGenObjC/arc-linetable.m new file mode 100644 index 0000000000..eac91f1889 --- /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/arc-literals.m b/test/CodeGenObjC/arc-literals.m index 203c2ad1ee..78c5d9d237 100644 --- a/test/CodeGenObjC/arc-literals.m +++ b/test/CodeGenObjC/arc-literals.m @@ -35,18 +35,28 @@ void test_numeric() { // CHECK: define void @test_array void test_array(id a, id b) { + // CHECK: [[A:%.*]] = alloca i8*, + // CHECK: [[B:%.*]] = alloca i8*, + // Retaining parameters // CHECK: call i8* @objc_retain(i8* // CHECK: call i8* @objc_retain(i8* // Constructing the array - // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0 - // CHECK: store i8* - // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1 - // CHECK: store i8* - - // CHECK: {{call i8*.*objc_msgSend.*i64 2}} - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0 + // CHECK-NEXT: [[V0:%.*]] = load i8** [[A]], + // CHECK-NEXT: store i8* [[V0]], i8** [[T0]] + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1 + // CHECK-NEXT: [[V1:%.*]] = load i8** [[B]], + // CHECK-NEXT: store i8* [[V1]], i8** [[T0]] + + // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T:%.*]]** @"\01L_OBJC_CLASSLIST + // CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES + // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8* + // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8** + // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2) + // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]]) + // CHECK: call void (...)* @clang.arc.use(i8* [[V0]], i8* [[V1]]) id arr = @[a, b]; // CHECK: call void @objc_release @@ -57,6 +67,11 @@ void test_array(id a, id b) { // CHECK: define void @test_dictionary void test_dictionary(id k1, id o1, id k2, id o2) { + // CHECK: [[K1:%.*]] = alloca i8*, + // CHECK: [[O1:%.*]] = alloca i8*, + // CHECK: [[K2:%.*]] = alloca i8*, + // CHECK: [[O2:%.*]] = alloca i8*, + // Retaining parameters // CHECK: call i8* @objc_retain(i8* // CHECK: call i8* @objc_retain(i8* @@ -64,18 +79,29 @@ void test_dictionary(id k1, id o1, id k2, id o2) { // CHECK: call i8* @objc_retain(i8* // Constructing the arrays - // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS:%[A-Za-z0-9]+]], i32 0, i32 0 - // CHECK: store i8* - // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0 - // CHECK: store i8* - // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS]], i32 0, i32 1 - // CHECK: store i8* - // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1 - // CHECK: store i8* + // CHECK: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[KEYS:%[A-Za-z0-9]+]], i32 0, i32 0 + // CHECK-NEXT: [[V0:%.*]] = load i8** [[K1]], + // CHECK-NEXT: store i8* [[V0]], i8** [[T0]] + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0 + // CHECK-NEXT: [[V1:%.*]] = load i8** [[O1]], + // CHECK-NEXT: store i8* [[V1]], i8** [[T0]] + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[KEYS]], i32 0, i32 1 + // CHECK-NEXT: [[V2:%.*]] = load i8** [[K2]], + // CHECK-NEXT: store i8* [[V2]], i8** [[T0]] + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1 + // CHECK-NEXT: [[V3:%.*]] = load i8** [[O2]], + // CHECK-NEXT: store i8* [[V3]], i8** [[T0]] // Constructing the dictionary - // CHECK: {{call i8.*@objc_msgSend}} - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T:%.*]]** @"\01L_OBJC_CLASSLIST + // CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES + // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8* + // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8** + // CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8** + // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2) + // CHECK-NEXT: [[T5:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T4]]) + // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]]) + id dict = @{ k1 : o1, k2 : o2 }; // CHECK: call void @objc_release @@ -98,19 +124,36 @@ void test_property(B *b) { // Retain parameter // CHECK: call i8* @objc_retain + // CHECK: [[T0:%.*]] = getelementptr inbounds [1 x i8*]* [[OBJECTS:%.*]], i32 0, i32 0 + // Invoke 'prop' - // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES - // CHECK: {{call.*@objc_msgSend}} - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES + // CHECK-NEXT: [[T1:%.*]] = bitcast + // CHECK-NEXT: [[T2:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]]) + // CHECK-NEXT: [[T3:%.*]] = bitcast [[B]]* [[T2]] to i8* + // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]]) + // CHECK-NEXT: [[V0:%.*]] = bitcast i8* [[T4]] to [[B]]* + // CHECK-NEXT: [[V1:%.*]] = bitcast [[B]]* [[V0]] to i8* + + // Store to array. + // CHECK-NEXT: store i8* [[V1]], i8** [[T0]] // Invoke arrayWithObjects:count: - // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES - // CHECK: {{call.*objc_msgSend}} - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T]]** @"\01L_OBJC_CLASSLIST + // CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES + // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8* + // CHECK-NEXT: [[T2:%.*]] = bitcast [1 x i8*]* [[OBJECTS]] to i8** + // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1) + // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]]) + // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V1]]) + // CHECK-NEXT: bitcast + // CHECK-NEXT: bitcast + // CHECK-NEXT: store id arr = @[ b.prop ]; // Release b.prop - // CHECK: call void @objc_release + // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[V0]] to i8* + // CHECK-NEXT: call void @objc_release(i8* [[T0]]) // Destroy arr // CHECK: call void @objc_release diff --git a/test/CodeGenObjC/arc-precise-lifetime.m b/test/CodeGenObjC/arc-precise-lifetime.m new file mode 100644 index 0000000000..595a4f9fdf --- /dev/null +++ b/test/CodeGenObjC/arc-precise-lifetime.m @@ -0,0 +1,120 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s + +#define PRECISE_LIFETIME __attribute__((objc_precise_lifetime)) + +id test0_helper(void) __attribute__((ns_returns_retained)); +void test0() { + PRECISE_LIFETIME id x = test0_helper(); + x = 0; + // CHECK: [[X:%.*]] = alloca i8* + // CHECK-NEXT: [[CALL:%.*]] = call i8* @test0_helper() + // CHECK-NEXT: store i8* [[CALL]], i8** [[X]] + + // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] + // CHECK-NEXT: store i8* null, i8** [[X]] + // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]] + // CHECK-NOT: clang.imprecise_release + + // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] + // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]] + // CHECK-NOT: clang.imprecise_release + + // CHECK-NEXT: ret void +} + +// rdar://problem/9821110 +@interface Test1 +- (char*) interior __attribute__((objc_returns_inner_pointer)); +// Should we allow this on properties? +@end +extern Test1 *test1_helper(void); + +// CHECK: define void @test1a() +void test1a(void) { + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* + // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* + // CHECK-NEXT: store [[TEST1]]* [[T3]] + // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]** + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* + // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) + // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* + // CHECK-NEXT: [[T4:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ + // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8* + // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast + // CHECK-NEXT: store i8* [[T6]], i8** + // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]** + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* + // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: ret void + Test1 *ptr = test1_helper(); + char *c = [(ptr) interior]; +} + +// CHECK: define void @test1b() +void test1b(void) { + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* + // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* + // CHECK-NEXT: store [[TEST1]]* [[T3]] + // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]** + // CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ + // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* + // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast + // CHECK-NEXT: store i8* [[T3]], i8** + // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]** + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* + // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]] + // CHECK-NOT: clang.imprecise_release + // CHECK-NEXT: ret void + __attribute__((objc_precise_lifetime)) Test1 *ptr = test1_helper(); + char *c = [ptr interior]; +} + +@interface Test2 { +@public + id ivar; +} +@end +// CHECK: define void @test2( +void test2(Test2 *x) { + x->ivar = 0; + // CHECK: [[X:%.*]] = alloca [[TEST2:%.*]]* + // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST2]]* {{%.*}} to i8* + // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) [[NUW]] + // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST2]]* + // CHECK-NEXT: store [[TEST2]]* [[T2]], [[TEST2]]** [[X]], + + // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]** [[X]], + // CHECK-NEXT: [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test2.ivar" + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8* + // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8* [[T1]], i64 [[OFFSET]] + // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8** + // CHECK-NEXT: [[T4:%.*]] = load i8** [[T3]], + // CHECK-NEXT: store i8* null, i8** [[T3]], + // CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]] + // CHECK-NOT: imprecise + + // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]** [[X]] + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8* + // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release + + // CHECK-NEXT: ret void +} + +// CHECK: define void @test3(i8* +void test3(PRECISE_LIFETIME id x) { + // CHECK: [[X:%.*]] = alloca i8*, + // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}}) [[NUW]] + // CHECK-NEXT: store i8* [[T0]], i8** [[X]], + + // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]] + // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]] + // CHECK-NOT: imprecise_release + + // CHECK-NEXT: ret void +} + +// CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/CodeGenObjC/arc-property.m b/test/CodeGenObjC/arc-property.m index 0e01fb7eda..dde02d7dd7 100644 --- a/test/CodeGenObjC/arc-property.m +++ b/test/CodeGenObjC/arc-property.m @@ -86,4 +86,49 @@ static Class theGlobalClass; // CHECK-NEXT: call void @objc_storeStrong(i8** [[T3]], i8* null) [[NUW]] // CHECK-NEXT: ret void +// rdar://13115896 +@interface Test3 +@property id copyMachine; +@end + +void test3(Test3 *t) { + id x = t.copyMachine; + x = [t copyMachine]; +} +// CHECK: define void @test3([[TEST3:%.*]]* +// Prologue. +// CHECK: [[T:%.*]] = alloca [[TEST3]]*, +// CHECK-NEXT: [[X:%.*]] = alloca i8*, +// Property access. +// CHECK: [[T0:%.*]] = load [[TEST3]]** [[T]], +// CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES +// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8* +// CHECK-NEXT: [[T2:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]]) +// CHECK-NEXT: store i8* [[T2]], i8** [[X]], +// Message send. +// CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]** [[T]], +// CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES +// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8* +// CHECK-NEXT: [[T2:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]]) +// CHECK-NEXT: [[T3:%.*]] = load i8** [[X]], +// CHECK-NEXT: store i8* [[T2]], i8** [[X]], +// CHECK-NEXT: call void @objc_release(i8* [[T3]]) +// Epilogue. +// CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) +// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST3]]** [[T]] to i8** +// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) +// CHECK-NEXT: ret void + +@implementation Test3 +- (id) copyMachine { + extern id test3_helper(void); + return test3_helper(); +} +// CHECK: define internal i8* @"\01-[Test3 copyMachine]"( +// CHECK: [[T0:%.*]] = call i8* @test3_helper() +// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) +// CHECK-NEXT: ret i8* [[T1]] +- (void) setCopyMachine: (id) x {} +@end + // CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/CodeGenObjC/arc-ternary-op.m b/test/CodeGenObjC/arc-ternary-op.m index ed14e9d9df..f70e8864a0 100644 --- a/test/CodeGenObjC/arc-ternary-op.m +++ b/test/CodeGenObjC/arc-ternary-op.m @@ -61,11 +61,13 @@ void test1(int cond) { // CHECK: [[T0:%.*]] = load i8** [[ARG]] // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]] // CHECK-NEXT: br label - // CHECK: call void @test1_sink(i8** [[T1]]) + // CHECK: [[W:%.*]] = phi i8* [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ] + // CHECK-NEXT: call void @test1_sink(i8** [[T1]]) // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = load i8** [[TEMP1]] // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) + // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W]]) [[NUW]] // CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]] // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]] // CHECK-NEXT: call void @objc_release(i8* [[T2]]) diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m index 48f012a42b..7262dc8d7b 100644 --- a/test/CodeGenObjC/arc.m +++ b/test/CodeGenObjC/arc.m @@ -273,27 +273,7 @@ void test8() { // CHECK: [[X:%.*]] = alloca i8* // CHECK-NEXT: [[T0:%.*]] = call i8* @test8_helper() // CHECK-NEXT: store i8* [[T0]], i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]] - // CHECK-NOT: imprecise_release - // CHECK-NEXT: ret void -} - -id test9_helper(void) __attribute__((ns_returns_retained)); -void test9() { - id x __attribute__((objc_precise_lifetime)) = test9_helper(); - x = 0; - // CHECK: [[X:%.*]] = alloca i8* - // CHECK-NEXT: [[CALL:%.*]] = call i8* @test9_helper() - // CHECK-NEXT: store i8* [[CALL]], i8** [[X]] - - // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] - // CHECK-NEXT: store i8* null, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release - - // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]] - // CHECK-NOT: clang.imprecise_release - + // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: ret void } @@ -373,7 +353,7 @@ void test12(void) { // CHECK-NEXT: [[T4:%.*]] = load i8** [[Y]] // CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]]) - // CHECK-NEXT: ret void + // CHECK: ret void } // Indirect consuming calls. @@ -480,8 +460,9 @@ void test13(void) { void test19() { // CHECK: define void @test19() // CHECK: [[X:%.*]] = alloca [5 x i8*], align 16 + // CHECK: call void @llvm.lifetime.start // CHECK-NEXT: [[T0:%.*]] = bitcast [5 x i8*]* [[X]] to i8* - // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 40, i32 16, i1 false) + // CHECK: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 40, i32 16, i1 false) id x[5]; extern id test19_helper(void); @@ -641,7 +622,9 @@ void test21(unsigned n) { // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]] // CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8* -// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST27]]* +// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST27]]* [[T3]] to i8* // CHECK-NEXT: store i32 {{[0-9]+}}, i32* [[DEST]] // CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8* @@ -705,7 +688,9 @@ static id _test29_allocator = 0; // Return statement. // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[CALL]] // CHECK-NEXT: [[CALL:%.*]] = bitcast -// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[CALL]]) [[NUW]] +// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[CALL]]) [[NUW]] +// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]* +// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8* // CHECK-NEXT: store i32 1, i32* [[CLEANUP]] // Cleanup. @@ -759,7 +744,9 @@ static id _test29_allocator = 0; // Return statement. // CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* -// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]] +// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]] +// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]* +// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8* // CHECK-NEXT: store i32 1, i32* [[CLEANUP]] // Cleanup. @@ -814,7 +801,9 @@ char *helper; // Return. // CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]** [[SELF]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8* -// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST30]]* +// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST30]]* [[T1]] to i8* // CHECK-NEXT: store i32 1 // Cleanup. @@ -877,8 +866,8 @@ void test33(Test33 *ptr) { // CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[A]] // CHECK-NEXT: load [[TEST33]]** [[PTR]] - // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]] - // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP0]] + // CHECK-NEXT: [[W0:%.*]] = load [[A_T]]** [[A]] + // CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP0]] // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: bitcast // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP0]]) @@ -886,14 +875,15 @@ void test33(Test33 *ptr) { // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* + // CHECK-NEXT: call void (...)* @clang.arc.use([[A_T]]* [[W0]]) [[NUW]] // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]] // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* // CHECK-NEXT: call void @objc_release(i8* [[T5]]) // CHECK-NEXT: load [[TEST33]]** [[PTR]] - // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]] - // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP1]] + // CHECK-NEXT: [[W0:%.*]] = load [[A_T]]** [[A]] + // CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP1]] // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: bitcast // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP1]]) @@ -901,6 +891,7 @@ void test33(Test33 *ptr) { // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* + // CHECK-NEXT: call void (...)* @clang.arc.use([[A_T]]* [[W0]]) [[NUW]] // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]] // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* @@ -974,15 +965,16 @@ void test37(void) { // CHECK-NEXT: [[TEMP:%.*]] = alloca i8* // CHECK-NEXT: store [[TEST37]]* null, [[TEST37]]** [[VAR]] - // CHECK-NEXT: [[T0:%.*]] = load [[TEST37]]** [[VAR]] - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST37]]* [[T0]] to i8* - // CHECK-NEXT: store i8* [[T1]], i8** [[TEMP]] + // CHECK-NEXT: [[W0:%.*]] = load [[TEST37]]** [[VAR]] + // CHECK-NEXT: [[W1:%.*]] = bitcast [[TEST37]]* [[W0]] to i8* + // CHECK-NEXT: store i8* [[W1]], i8** [[TEMP]] // CHECK-NEXT: call void @test37_helper(i8** [[TEMP]]) // CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]] // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST37]]* // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST37]]* [[T1]] to i8* // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST37]]* + // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W1]]) [[NUW]] // CHECK-NEXT: [[T5:%.*]] = load [[TEST37]]** [[VAR]] // CHECK-NEXT: store [[TEST37]]* [[T4]], [[TEST37]]** [[VAR]] // CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST37]]* [[T5]] to i8* @@ -1239,57 +1231,6 @@ void test56_test(void) { // CHECK-NEXT: [[T5:%.*]] = load i8** [[T4]] // CHECK-NEXT: ret i8* [[T5]] -// rdar://problem/9821110 -@interface Test58 -- (char*) interior __attribute__((objc_returns_inner_pointer)); -// Should we allow this on properties? -@end -extern Test58 *test58_helper(void); - -// CHECK: define void @test58a() -void test58a(void) { - // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper() - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]* - // CHECK-NEXT: store [[TEST58]]* [[T3]] - // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]** - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]* - // CHECK-NEXT: [[T4:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ - // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST58]]* [[T3]] to i8* - // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast - // CHECK-NEXT: store i8* [[T6]], i8** - // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]** - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release - // CHECK-NEXT: ret void - Test58 *ptr = test58_helper(); - char *c = [(ptr) interior]; -} - -// CHECK: define void @test58b() -void test58b(void) { - // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper() - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]* - // CHECK-NEXT: store [[TEST58]]* [[T3]] - // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]** - // CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ - // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* - // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast - // CHECK-NEXT: store i8* [[T3]], i8** - // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]** - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]] - // CHECK-NOT: clang.imprecise_release - // CHECK-NEXT: ret void - __attribute__((objc_precise_lifetime)) Test58 *ptr = test58_helper(); - char *c = [ptr interior]; -} - // rdar://problem/9842343 void test59(void) { extern id test59_getlock(void); diff --git a/test/CodeGenObjC/autorelease.m b/test/CodeGenObjC/autorelease.m index 830929afb2..f89b81a8ac 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/blocks.m b/test/CodeGenObjC/blocks.m index f072c48669..3718ad590a 100644 --- a/test/CodeGenObjC/blocks.m +++ b/test/CodeGenObjC/blocks.m @@ -93,7 +93,8 @@ void test2(Test2 *x) { // doesn't require a read barrier. // CHECK: define internal void @__test2_block_invoke // CHECK: [[BLOCK:%.*]] = bitcast i8* {{%.*}} to [[BLOCK_T]]* -// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 +// CHECK-NOT: bitcast +// CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK-NEXT: [[T1:%.*]] = load i8** [[T0]] // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[WEAK_T]]{{.*}}* // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]]{{.*}}* [[T2]], i32 0, i32 1 diff --git a/test/CodeGenObjC/debug-info-block-captured-self.m b/test/CodeGenObjC/debug-info-block-captured-self.m new file mode 100644 index 0000000000..183e91b6ec --- /dev/null +++ b/test/CodeGenObjC/debug-info-block-captured-self.m @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -fblocks -g -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s +// +// Test that debug location is generated for a captured "self" inside +// a block. +// +// This test is split into two parts, this one for the frontend, and +// then llvm/test/DebugInfo/debug-info-block-captured-self.ll to +// ensure that DW_AT_location is generated for the captured self. +@class T; +@interface S +@end +@interface Mode +-(int) count; +@end +@interface Context +@end +@interface ViewController +@property (nonatomic, readwrite, strong) Context *context; +@end +typedef enum { + Unknown = 0, +} State; +@interface Main : ViewController +{ + T * t1; + T * t2; +} +@property(readwrite, nonatomic) State state; +@end +@implementation Main +- (id) initWithContext:(Context *) context +{ + t1 = [self.context withBlock:^(id obj){ + id *mode1; + t2 = [mode1 withBlock:^(id object){ + Mode *mode2 = object; + if ([mode2 count] != 0) { + self.state = 0; + } + }]; + }]; +} +@end +// The important part of this test is that there is a dbg.value +// intrinsic associated with the implicit .block_descriptor argument +// of the block. We also test that this value gets alloca'd, so the +// register llocator won't accidentally kill it. + +// outer block: +// CHECK: define internal void {{.*}}_block_invoke{{.*}} + +// inner block: +// CHECK: define internal void {{.*}}_block_invoke{{.*}} +// CHECK: %[[MEM1:.*]] = alloca i8*, align 8 +// CHECK-NEXT: %[[MEM2:.*]] = alloca i8*, align 8 +// CHECK: store i8* [[BLOCK_DESC:%.*]], i8** %[[MEM1]], align 8 +// CHECK: %[[TMP0:.*]] = load i8** %[[MEM1]] +// CHECK: call void @llvm.dbg.value(metadata !{i8* %[[TMP0]]}, i64 0, metadata ![[BDMD:[0-9]+]]) +// CHECK: call void @llvm.dbg.declare(metadata !{i8* [[BLOCK_DESC]]}, metadata ![[BDMD:[0-9]+]]) +// CHECK: %[[TMP1:.*]] = bitcast +// CHECK-NEXT: store +// 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_ +// Metadata +// CHECK: ![[MAIN:.*]] = {{.*}}!"Main"{{.*}}DW_TAG_structure_type{{.*}}line 23 +// CHECK: ![[PMAIN:.*]] = {{.*}}![[MAIN]]} ; [ DW_TAG_pointer_type ]{{.*}}from Main +// CHECK: ![[BDMD]] = metadata {{.*}}.block_descriptor +// CHECK: ![[SELF]] = {{.*}}![[PMAIN]]{{.*}}[ DW_TAG_auto_variable ] [self] [line 40] diff --git a/test/CodeGenObjC/debug-info-block-helper.m b/test/CodeGenObjC/debug-info-block-helper.m index 5f4a87a565..49c8c5daea 100644 --- a/test/CodeGenObjC/debug-info-block-helper.m +++ b/test/CodeGenObjC/debug-info-block-helper.m @@ -2,7 +2,7 @@ // RUN: %clang_cc1 -emit-llvm -fblocks -g -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s -o - | FileCheck %s extern void foo(void(^)(void)); -// CHECK: metadata !{i32 786478, i32 0, metadata ![[FILE:.*]], metadata !"__destroy_helper_block_", metadata !"__destroy_helper_block_", metadata !"", metadata ![[FILE]], i32 24, metadata !{{.*}}, i1 true, i1 true, i32 0, i32 0, null, i32 0, i1 false, void (i8*)* @__destroy_helper_block_, null, null, metadata !{{.*}}, i32 24} ; [ DW_TAG_subprogram ] +// CHECK: [ DW_TAG_subprogram ] {{.*}} [__destroy_helper_block_] @interface NSObject { struct objc_object *isa; diff --git a/test/CodeGenObjC/debug-info-block-line.m b/test/CodeGenObjC/debug-info-block-line.m index c913a972e1..2192575bb7 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 71ae8a610e..3d91c9ea5c 100644 --- a/test/CodeGenObjC/debug-info-blocks.m +++ b/test/CodeGenObjC/debug-info-blocks.m @@ -1,9 +1,16 @@ -// REQUIRES: x86-64-registered-target -// RUN: %clang_cc1 -masm-verbose -S -fblocks -g -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed %s -o - | FileCheck %s - -//Radar 9279956 -//CHECK: ## DW_OP_deref -//CHECK-NEXT: ## DW_OP_plus_uconst +// RUN: %clang_cc1 -emit-llvm -fblocks -g -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed %s -o - | FileCheck %s + +// rdar://problem/9279956 +// Test that we generate the proper debug location for a captured self. +// The second half of this patch is in llvm/tests/DebugInfo/debug-info-blocks.ll + +// 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: 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 51] +// CHECK: ![[D]] = {{.*}} [d] [line 49] typedef unsigned int NSUInteger; diff --git a/test/CodeGenObjC/debug-info-fwddecl.m b/test/CodeGenObjC/debug-info-fwddecl.m index 8f2860c7d8..b41c485e19 100644 --- a/test/CodeGenObjC/debug-info-fwddecl.m +++ b/test/CodeGenObjC/debug-info-fwddecl.m @@ -2,4 +2,4 @@ @class ForwardObjcClass; ForwardObjcClass *ptr = 0; -// CHECK: metadata !{i32 {{.*}}, null, metadata !"ForwardObjcClass", metadata !{{.*}}, i32 2, i64 0, i64 0, i32 0, i32 4, null, null, i32 16} ; [ DW_TAG_structure_type ] +// CHECK: {{.*}} [ DW_TAG_structure_type ] [ForwardObjcClass] [line 2, size 0, align 0, offset 0] [fwd] diff --git a/test/CodeGenObjC/debug-info-impl.m b/test/CodeGenObjC/debug-info-impl.m index 51d111454f..8991a88962 100644 --- a/test/CodeGenObjC/debug-info-impl.m +++ b/test/CodeGenObjC/debug-info-impl.m @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -g -S -emit-llvm %s -o - | FileCheck %s -// CHECK: metadata !{i32 {{.*}}, metadata {{.*}}, metadata !"Circle", metadata {{.*}}, i32 11, i64 64, i64 64, i32 0, i32 512, null, metadata {{.*}}, i32 16, null, null} ; [ DW_TAG_structure_type ] +// CHECK: {{.*}} [ DW_TAG_structure_type ] [Circle] [line 11, @interface NSObject { struct objc_object *isa; } diff --git a/test/CodeGenObjC/debug-info-ivars-extension.m b/test/CodeGenObjC/debug-info-ivars-extension.m index 733d146875..e43b598f70 100644 --- a/test/CodeGenObjC/debug-info-ivars-extension.m +++ b/test/CodeGenObjC/debug-info-ivars-extension.m @@ -24,10 +24,10 @@ void gorf (I* pg) { int _b = pg->b; } -// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"I", {{.*}}} ; [ DW_TAG_structure_type ] +// CHECK: {{.*}} [ DW_TAG_structure_type ] [I] // Check for "a". -// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"a", metadata !{{[0-9]*}}, i32 7, i64 32, i64 32, i64 0, i32 0, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [a] [line 7, size 32, align 32, offset 0] [from int] +// CHECK: {{.*}} [ DW_TAG_member ] [a] [line 7, size 32, align 32, offset 0] [from int] // Make sure we don't output the same type twice. -// CHECK-NOT: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"I", {{.*}}} ; [ DW_TAG_structure_type ] +// CHECK-NOT: {{.*}} [ DW_TAG_structure_type ] [I] // Check for "b". -// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"b", metadata !{{[0-9]*}}, i32 18, i64 32, i64 32, i64 0, i32 0, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [b] [line 18, size 32, align 32, offset 0] [from int] +// CHECK: {{.*}} [ DW_TAG_member ] [b] [line 18, size 32, align 32, offset 0] [from int] diff --git a/test/CodeGenObjC/debug-info-ivars-indirect.m b/test/CodeGenObjC/debug-info-ivars-indirect.m index 9f7f940133..1548ddd0bb 100644 --- a/test/CodeGenObjC/debug-info-ivars-indirect.m +++ b/test/CodeGenObjC/debug-info-ivars-indirect.m @@ -29,4 +29,4 @@ void gorf (struct S* s) { int _b = s->i->b; } -// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"b", metadata !{{[0-9]*}}, i32 24, i64 32, i64 32, i64 0, i32 0, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [b] [line 24, size 32, align 32, offset 0] [from int] +// CHECK: {{.*}} [ DW_TAG_member ] [b] [line 24, size 32, align 32, offset 0] [from int] diff --git a/test/CodeGenObjC/debug-info-ivars-private.m b/test/CodeGenObjC/debug-info-ivars-private.m index 0a555c2a8b..8505da17bb 100644 --- a/test/CodeGenObjC/debug-info-ivars-private.m +++ b/test/CodeGenObjC/debug-info-ivars-private.m @@ -32,5 +32,5 @@ __attribute((objc_root_class)) @interface NSObject { } @end -// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"foo", metadata !{{[0-9]*}}, i32 14, i64 32, i64 32, i64 0, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [foo] [line 14, size 32, align 32, offset 0] [protected] [from int] -// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"bar", metadata !{{[0-9]*}}, i32 27, i64 32, i64 32, i64 0, i32 1, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [bar] [line 27, size 32, align 32, offset 0] [private] [from int] +// CHECK: {{.*}} [ DW_TAG_member ] [foo] [line 14, size 32, align 32, offset 0] [protected] [from int] +// CHECK: {{.*}} [ DW_TAG_member ] [bar] [line 27, size 32, align 32, offset 0] [private] [from int] diff --git a/test/CodeGenObjC/debug-info-ivars.m b/test/CodeGenObjC/debug-info-ivars.m index 24705e1ad6..a0f2963f5d 100644 --- a/test/CodeGenObjC/debug-info-ivars.m +++ b/test/CodeGenObjC/debug-info-ivars.m @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -g %s -o - | FileCheck %s __attribute((objc_root_class)) @interface NSObject { - id isa; + id isa; } @end @@ -10,15 +10,15 @@ __attribute((objc_root_class)) @interface NSObject { int i; unsigned flag_1 : 9; unsigned flag_2 : 9; - unsigned : 1; - unsigned flag_3 : 9; + unsigned : 1; + unsigned flag_3 : 9; } @end @implementation BaseClass @end -// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"i", metadata !{{[0-9]*}}, i32 10, i64 32, i64 32, i64 0, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [i] [line 10, size 32, align 32, offset 0] [protected] [from int] -// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"flag_1", metadata !{{[0-9]*}}, i32 11, i64 9, i64 32, i64 0, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [flag_1] [line 11, size 9, align 32, offset 0] [protected] [from unsigned int] -// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"flag_2", metadata !{{[0-9]*}}, i32 12, i64 9, i64 32, i64 1, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [flag_2] [line 12, size 9, align 32, offset 1] [protected] [from unsigned int] -// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"flag_3", metadata !{{[0-9]*}}, i32 14, i64 9, i64 32, i64 3, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [flag_3] [line 14, size 9, align 32, offset 3] [protected] [from unsigned int]
\ No newline at end of file +// CHECK: {{.*}} [ DW_TAG_member ] [i] [line 10, size 32, align 32, offset 0] [protected] [from int] +// CHECK: {{.*}} [ DW_TAG_member ] [flag_1] [line 11, size 9, align 32, offset 0] [protected] [from unsigned int] +// CHECK: {{.*}} [ DW_TAG_member ] [flag_2] [line 12, size 9, align 32, offset 1] [protected] [from unsigned int] +// CHECK: {{.*}} [ DW_TAG_member ] [flag_3] [line 14, size 9, align 32, offset 3] [protected] [from unsigned int] diff --git a/test/CodeGenObjC/debug-info-pubtypes.m b/test/CodeGenObjC/debug-info-pubtypes.m index ebe87d40f7..8b7dfadfd9 100644 --- a/test/CodeGenObjC/debug-info-pubtypes.m +++ b/test/CodeGenObjC/debug-info-pubtypes.m @@ -1,7 +1,7 @@ // REQUIRES: x86-64-registered-target // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -g -emit-llvm %s -o - | FileCheck %s -// CHECK: !{{.*}} = metadata !{i32 {{.*}}, metadata ![[FILE:.*]], metadata !"H", metadata ![[FILE]], i32 6, i64 0, i64 8, i32 0, i32 512, null, metadata !{{.*}}, i32 16, null, null} ; [ DW_TAG_structure_type ] +// CHECK: {{.*}} [ DW_TAG_structure_type ] [H] [line 6, @interface H -(void) foo; diff --git a/test/CodeGenObjC/debug-info-synthesis.m b/test/CodeGenObjC/debug-info-synthesis.m index fac9eca4a1..1bf7576d88 100644 --- a/test/CodeGenObjC/debug-info-synthesis.m +++ b/test/CodeGenObjC/debug-info-synthesis.m @@ -30,5 +30,5 @@ int main(int argc, char *argv[]) { } } -// CHECK: ![[FILE:.*]] = metadata !{i32 {{.*}}, metadata !"./foo.h" -// CHECK: !{{.*}} = metadata !{i32 {{.*}}, i32 0, metadata ![[FILE]], metadata !"-[Foo dict]", metadata !"-[Foo dict]", metadata !"", metadata ![[FILE]], i32 8, metadata !{{.*}}, i1 true, i1 true, i32 0, i32 0, null, i32 320, i1 false, %1* (%0*, i8*)* @"\01-[Foo dict]", null, null, metadata !{{.*}}, i32 8} ; [ DW_TAG_subprogram ] +// CHECK: ![[FILE:.*]] = {{.*}}[ DW_TAG_file_type ] [{{.*}}/foo.h] +// CHECK: metadata ![[FILE]], {{.*}} ; [ DW_TAG_subprogram ] [line 8] [local] [def] [-[Foo dict]] diff --git a/test/CodeGenObjC/encode-test-3.m b/test/CodeGenObjC/encode-test-3.m index 4b39cd718e..b76063ffd3 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/exceptions.m b/test/CodeGenObjC/exceptions.m index 551e67c2e6..408b94d385 100644 --- a/test/CodeGenObjC/exceptions.m +++ b/test/CodeGenObjC/exceptions.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fexceptions -fobjc-exceptions -O2 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fobjc-exceptions -O2 -o - %s | FileCheck %s // // <rdar://problem/7471679> [irgen] [eh] Exception code built with clang (x86_64) crashes @@ -28,7 +28,7 @@ void f1() { // CHECK: call void asm sideeffect "", "*m" // CHECK-NEXT: call void @foo() foo(); - // CHECK-NEXT: call void @objc_exception_try_exit + // CHECK: call void @objc_exception_try_exit // CHECK: call void asm sideeffect "", "=*m" } @finally { diff --git a/test/CodeGenObjC/metadata-symbols-32.m b/test/CodeGenObjC/metadata-symbols-32.m index e8d25129a7..fda909ca74 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 27017b76a8..a89fec56de 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 576a55b136..eedcf16627 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 1a9e882a13..1a96f34c5d 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 0000000000..55c2a7c103 --- /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 9822702331..393ec3650c 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 0000000000..b7e1c4601f --- /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 aa40f930ca..e3e86a0b0d 100644 --- a/test/CodeGenObjCXX/arc.mm +++ b/test/CodeGenObjCXX/arc.mm @@ -76,11 +76,13 @@ void test34(int cond) { // CHECK: [[T0:%.*]] = load i8** [[ARG]] // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]] // CHECK-NEXT: br label + // CHECK: [[W0:%.*]] = phi i8* [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ] // CHECK: call void @_Z11test34_sinkPU15__autoreleasingP11objc_object(i8** [[T1]]) // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = load i8** [[TEMP1]] // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) + // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W0]]) // CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]] // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]] // CHECK-NEXT: call void @objc_release(i8* [[T2]]) @@ -273,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/exceptions-legacy.mm b/test/CodeGenObjCXX/exceptions-legacy.mm new file mode 100644 index 0000000000..a31ba36660 --- /dev/null +++ b/test/CodeGenObjCXX/exceptions-legacy.mm @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fexceptions -fobjc-exceptions -O2 -o - %s | FileCheck %s + +// Test we maintain at least a basic amount of interoperation between +// ObjC and C++ exceptions in the legacy runtime. + +// rdar://12364847 + +void foo(void); + +void test0(id obj) { + @synchronized(obj) { + foo(); + } +} +// CHECK: define void @_Z5test0P11objc_object( +// Enter the @synchronized block. +// CHECK: call i32 @objc_sync_enter(i8* [[OBJ:%.*]]) +// CHECK: call void @objc_exception_try_enter([[BUF_T:%.*]]* [[BUF:%.*]]) +// CHECK-NEXT: [[T0:%.*]] = getelementptr [[BUF_T]]* [[BUF]], i32 0, i32 0, i32 0 +// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(i32* [[T0]]) +// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 +// CHECK-NEXT: br i1 [[T2]], + +// Body. +// CHECK: invoke void @_Z3foov() + +// Leave the @synchronized. The reload of obj here is unnecessary. +// CHECK: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]]) +// CHECK-NEXT: [[T0:%.*]] = load i8** +// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]]) +// CHECK-NEXT: ret void + +// Real EH cleanup. +// CHECK: [[T0:%.*]] = landingpad +// CHECK-NEXT: cleanup +// CHECK-NEXT: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]]) +// CHECK-NEXT: [[T0:%.*]] = load i8** +// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]]) +// CHECK-NEXT: resume + +// ObjC EH "cleanup". +// CHECK: [[T0:%.*]] = load i8** +// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]]) +// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_exception_extract([[BUF_T]]* [[BUF]]) +// CHECK-NEXT: call void @objc_exception_throw(i8* [[T0]]) +// CHECK-NEXT: unreachable + +void test1(id obj, bool *failed) { + @try { + foo(); + } @catch (...) { + *failed = true; + } +} +// CHECK: define void @_Z5test1P11objc_objectPb( +// Enter the @try block. +// CHECK: call void @objc_exception_try_enter([[BUF_T]]* [[BUF:%.*]]) +// CHECK-NEXT: [[T0:%.*]] = getelementptr [[BUF_T]]* [[BUF]], i32 0, i32 0, i32 0 +// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(i32* [[T0]]) +// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 +// CHECK-NEXT: br i1 [[T2]], + +// Body. +// CHECK: invoke void @_Z3foov() + +// Leave the @try. +// CHECK: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]]) +// CHECK-NEXT: br label +// CHECK: ret void + +// Real EH cleanup. +// CHECK: [[T0:%.*]] = landingpad +// CHECK-NEXT: cleanup +// CHECK-NEXT: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]]) +// CHECK-NEXT: resume + +// Catch handler. Reload of 'failed' address is unnecessary. +// CHECK: [[T0:%.*]] = load i8** +// CHECK-NEXT: store i8 1, i8* [[T0]], +// CHECK-NEXT: br label diff --git a/test/CodeGenObjCXX/lambda-expressions.mm b/test/CodeGenObjCXX/lambda-expressions.mm index 7c1e2e4f57..c73e1727d6 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 2521c6076a..45a93a196d 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/CodeGenOpenCL/kernel-arg-info.cl b/test/CodeGenOpenCL/kernel-arg-info.cl index 7e35a33564..c7e20491a9 100644 --- a/test/CodeGenOpenCL/kernel-arg-info.cl +++ b/test/CodeGenOpenCL/kernel-arg-info.cl @@ -1,7 +1,20 @@ -// RUN: %clang_cc1 %s -cl-kernel-arg-info -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -cl-kernel-arg-info -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s -kernel void foo(global int *X, int Y, int anotherArg) { +kernel void foo(__global int * restrict X, const int Y, + volatile int anotherArg, __constant float * restrict Z) { *X = Y + anotherArg; } -// CHECK: metadata !{metadata !"kernel_arg_name", metadata !"X", metadata !"Y", metadata !"anotherArg"} +// CHECK: metadata !{metadata !"kernel_arg_addr_space", i32 1, i32 0, i32 0, i32 2} +// CHECK: metadata !{metadata !"kernel_arg_access_qual", metadata !"none", metadata !"none", metadata !"none", metadata !"none"} +// CHECK: metadata !{metadata !"kernel_arg_type", metadata !"int*", metadata !"int", metadata !"int", metadata !"float*"} +// CHECK: metadata !{metadata !"kernel_arg_type_qual", metadata !"restrict", metadata !"const", metadata !"volatile", metadata !"restrict const"} +// CHECK: metadata !{metadata !"kernel_arg_name", metadata !"X", metadata !"Y", metadata !"anotherArg", metadata !"Z"} + +kernel void foo2(read_only image1d_t img1, image2d_t img2, write_only image2d_array_t img3) { +} +// CHECK: metadata !{metadata !"kernel_arg_addr_space", i32 0, i32 0, i32 0} +// CHECK: metadata !{metadata !"kernel_arg_access_qual", metadata !"read_only", metadata !"read_only", metadata !"write_only"} +// CHECK: metadata !{metadata !"kernel_arg_type", metadata !"image1d_t", metadata !"image2d_t", metadata !"image2d_array_t"} +// CHECK: metadata !{metadata !"kernel_arg_type_qual", metadata !"", metadata !"", metadata !""} +// CHECK: metadata !{metadata !"kernel_arg_name", metadata !"img1", metadata !"img2", metadata !"img3"} diff --git a/test/CodeGenOpenCL/ptx-calls.cl b/test/CodeGenOpenCL/ptx-calls.cl index 34a21c6c1d..d9904513e5 100644 --- a/test/CodeGenOpenCL/ptx-calls.cl +++ b/test/CodeGenOpenCL/ptx-calls.cl @@ -2,11 +2,12 @@ void device_function() { } -// CHECK: define ptx_device void @device_function() +// CHECK: define void @device_function() __kernel void kernel_function() { device_function(); } -// CHECK: define ptx_kernel void @kernel_function() -// CHECK: call ptx_device void @device_function() +// CHECK: define void @kernel_function() +// CHECK: call void @device_function() +// CHECK: !{{[0-9]+}} = metadata !{void ()* @kernel_function, metadata !"kernel", i32 1} diff --git a/test/CodeGenOpenCL/ptx-kernels.cl b/test/CodeGenOpenCL/ptx-kernels.cl index 1d7e497b7c..07648e4015 100644 --- a/test/CodeGenOpenCL/ptx-kernels.cl +++ b/test/CodeGenOpenCL/ptx-kernels.cl @@ -2,9 +2,10 @@ void device_function() { } -// CHECK: define ptx_device void @device_function() +// CHECK: define void @device_function() __kernel void kernel_function() { } -// CHECK: define ptx_kernel void @kernel_function() +// CHECK: define void @kernel_function() +// CHECK: !{{[0-9]+}} = metadata !{void ()* @kernel_function, metadata !"kernel", i32 1} 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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /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 0000000000..e69de29bb2 --- /dev/null +++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crtn.o diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-i386.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-i386.a.syms new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-i386.a.syms diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-x86_64.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-x86_64.a.syms new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-x86_64.a.syms diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.msan-x86_64.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.msan-x86_64.a.syms new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.msan-x86_64.a.syms diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.tsan-x86_64.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.tsan-x86_64.a.syms new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.tsan-x86_64.a.syms diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-i386.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-i386.a.syms new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-i386.a.syms diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-x86_64.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-x86_64.a.syms new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-x86_64.a.syms diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-i386.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-i386.a.syms new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-i386.a.syms diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-x86_64.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-x86_64.a.syms new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-x86_64.a.syms diff --git a/test/Driver/Ofast.c b/test/Driver/Ofast.c new file mode 100644 index 0000000000..1f9fc78ec1 --- /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 0000000000..f1e710222a --- /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 79b2f55131..bf31800566 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 1bd2e140b2..5451945515 100644 --- a/test/Driver/clang_f_opts.c +++ b/test/Driver/clang_f_opts.c @@ -1,6 +1,7 @@ -// RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS1 %s +// RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fsplit-stack %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS1 %s // RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-asm -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-enums -fshort-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS2 %s +// CHECK-OPTIONS1: -split-stacks // CHECK-OPTIONS1: -fgnu-keywords // CHECK-OPTIONS1: -fblocks // CHECK-OPTIONS1: -fpascal-strings @@ -55,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 0000000000..deff5119a0 --- /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 ca1ca30ae6..daf895c18a 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 ca1ca30ae6..daf895c18a 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 8a629da817..4be2aadd7a 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 27862316f8..ff60caf2e0 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 0000000000..5f825d0429 --- /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/frame-pointer-elim.c b/test/Driver/frame-pointer-elim.c new file mode 100644 index 0000000000..286cd6e61f --- /dev/null +++ b/test/Driver/frame-pointer-elim.c @@ -0,0 +1,30 @@ +// For these next two tests when optimized we should omit the leaf frame +// pointer, for unoptimized we should have a leaf frame pointer. +// RUN: %clang -### -target i386-pc-linux-gnu -S -O1 %s 2>&1 | \ +// RUN: FileCheck --check-prefix=LINUX-OPT %s +// LINUX-OPT: "-momit-leaf-frame-pointer" + +// RUN: %clang -### -target i386-pc-linux-gnu -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=LINUX %s +// LINUX-NOT: "-momit-leaf-frame-pointer" + +// Darwin disables omitting the leaf frame pointer even under optimization +// unless the command lines are given. +// RUN: %clang -### -target i386-apple-darwin -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=DARWIN %s +// DARWIN: "-mdisable-fp-elim" + +// RUN: %clang -### -target i386-apple-darwin -S -O1 %s 2>&1 | \ +// RUN: FileCheck --check-prefix=DARWIN-OPT %s +// DARWIN-OPT-NOT: "-momit-leaf-frame-pointer" + +// RUN: %clang -### -target i386-darwin -S -fomit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=OMIT_ALL %s +// OMIT_ALL-NOT: "-mdisable-fp-elim" + +// RUN: %clang -### -target i386-darwin -S -momit-leaf-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=OMIT_LEAF %s +// OMIT_LEAF: "-momit-leaf-frame-pointer" + +void f0() {} +void f1() { f0(); } diff --git a/test/Driver/freebsd.c b/test/Driver/freebsd.c index d0e608cd31..cc72443961 100644 --- a/test/Driver/freebsd.c +++ b/test/Driver/freebsd.c @@ -105,5 +105,5 @@ // RUN: %clang %s -### -o %t.o -target arm-gnueabi-freebsd10.0 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-ARM-EABI %s // CHECK-ARM-EABI-NOT: clang{{.*}}" "-cc1"{{.*}}" "-fsjlj-exceptions" -// CHECK-ARM-EABI: as{{.*}}" "-mfpu=softvfp" +// CHECK-ARM-EABI: as{{.*}}" "-mfpu=softvfp" "-meabi=5" // CHECK-ARM-EABI-NOT: as{{.*}}" "-matpcs" diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c index efb289f6a7..0e7522b548 100644 --- a/test/Driver/fsanitize.c +++ b/test/Driver/fsanitize.c @@ -16,6 +16,12 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=address-full %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FULL // CHECK-ASAN-FULL: "-fsanitize={{((address|init-order|use-after-return|use-after-scope),?){4}"}} +// RUN: %clang -target x86_64-linux-gnu -fno-sanitize=init-order -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-IMPLIED-INIT-ORDER +// CHECK-ASAN-IMPLIED-INIT-ORDER: "-fsanitize={{((address|init-order),?){2}"}} + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-sanitize=init-order %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-NO-IMPLIED-INIT-ORDER +// CHECK-ASAN-NO-IMPLIED-INIT-ORDER-NOT: init-order + // RUN: %clang -target x86_64-linux-gnu -fcatch-undefined-behavior -fno-sanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-NO-TRAP-ERROR // CHECK-UNDEFINED-NO-TRAP-ERROR: '-fcatch-undefined-behavior' not allowed with '-fno-sanitize-undefined-trap-on-error' @@ -89,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 new file mode 100644 index 0000000000..1a2650d16e --- /dev/null +++ b/test/Driver/hexagon-toolchain-elf.c @@ -0,0 +1,564 @@ +// REQUIRES: hexagon-registered-target + +// ----------------------------------------------------------------------------- +// Test standard include paths +// ----------------------------------------------------------------------------- + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK001 %s +// CHECK001: "-cc1" {{.*}} "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include" +// CHECK001: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include-fixed" +// CHECK001: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include" +// CHECK001-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as" + +// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK002 %s +// CHECK002: "-cc1" {{.*}} "-internal-isystem" "[[INSTALL_DIR:.*]]/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include/c++/4.4.0" +// CHECK002: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include" +// CHECK002: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include-fixed" +// CHECK002: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include" +// CHECK002-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as" + +// ----------------------------------------------------------------------------- +// Test -nostdinc, -nostdlibinc, -nostdinc++ +// ----------------------------------------------------------------------------- + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -nostdinc \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK003 %s +// CHECK003: "-cc1" +// CHECK003-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include" +// CHECK003-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include-fixed" +// CHECK003-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include" +// CHECK003-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as" + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -nostdlibinc \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK004 %s +// CHECK004: "-cc1" +// CHECK004-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include" +// CHECK004-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include-fixed" +// CHECK004-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include" +// CHECK004-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as" + +// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -nostdlibinc \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK005 %s +// CHECK005: "-cc1" +// CHECK005-NOT: "-internal-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include/c++/4.4.0" +// CHECK005-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include" +// CHECK005-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include-fixed" +// CHECK005-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include" +// CHECK005-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as" + +// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -nostdinc++ \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK006 %s +// CHECK006: "-cc1" +// CHECK006-NOT: "-internal-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include/c++/4.4.0" +// CHECK006-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as" + +// ----------------------------------------------------------------------------- +// Test -march=<archname> -mcpu=<archname> -mv<number> +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -march=hexagonv3 \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK007 %s +// CHECK007: "-cc1" {{.*}} "-target-cpu" "hexagonv3" +// CHECK007-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"{{.*}} "-march=v3" +// CHECK007-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-ld"{{.*}} "-mv3" + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -mcpu=hexagonv5 \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK008 %s +// CHECK008: "-cc1" {{.*}} "-target-cpu" "hexagonv5" +// CHECK008-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"{{.*}} "-march=v5" +// CHECK008-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-ld"{{.*}} "-mv5" + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -mv2 \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK009 %s +// CHECK009: "-cc1" {{.*}} "-target-cpu" "hexagonv2" +// CHECK009-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"{{.*}} "-march=v2" +// CHECK009-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-ld"{{.*}} "-mv2" + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK010 %s +// CHECK010: "-cc1" {{.*}} "-target-cpu" "hexagonv4" +// CHECK010-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"{{.*}} "-march=v4" +// CHECK010-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-ld"{{.*}} "-mv4" + +// RUN: %clang -march=hexagonv2 -target hexagon-unknown-elf \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V2 %s +// RUN: %clang -mcpu=hexagonv2 -target hexagon-unknown-elf \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V2 %s +// RUN: %clang -mv2 -target hexagon-unknown-elf \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V2 %s +// CHECK-UNKNOWN-V2: error: unknown target CPU 'hexagonv2' + +// RUN: %clang -march=hexagonv3 -target hexagon-unknown-elf \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V3 %s +// RUN: %clang -mcpu=hexagonv3 -target hexagon-unknown-elf \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V3 %s +// RUN: %clang -mv3 -target hexagon-unknown-elf \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V3 %s +// CHECK-UNKNOWN-V3: error: unknown target CPU 'hexagonv3' + +// ----------------------------------------------------------------------------- +// Test Linker related args +// ----------------------------------------------------------------------------- + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Defaults for C +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK011 %s +// CHECK011: "{{.*}}clang{{.*}}" "-cc1" +// CHECK011-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK011-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK011-NOT: "-static" +// CHECK011-NOT: "-shared" +// CHECK011: "{{.*}}/hexagon/lib/v4/crt0_standalone.o" +// CHECK011: "{{.*}}/hexagon/lib/v4/crt0.o" +// CHECK011: "{{.*}}/hexagon/lib/v4/init.o" +// CHECK011: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK011: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK011: "-L{{.*}}/lib/gcc" +// CHECK011: "-L{{.*}}/hexagon/lib/v4" +// CHECK011: "-L{{.*}}/hexagon/lib" +// CHECK011: "{{[^"]+}}.o" +// CHECK011: "--start-group" "-lstandalone" "-lc" "-lgcc" "--end-group" +// CHECK011: "{{.*}}/hexagon/lib/v4/fini.o" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Defaults for C++ +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK012 %s +// CHECK012: "{{.*}}clang{{.*}}" "-cc1" +// CHECK012-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK012-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK012-NOT: "-static" +// CHECK012-NOT: "-shared" +// CHECK012: "{{.*}}/hexagon/lib/v4/crt0_standalone.o" +// CHECK012: "{{.*}}/hexagon/lib/v4/crt0.o" +// CHECK012: "{{.*}}/hexagon/lib/v4/init.o" +// CHECK012: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK012: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK012: "-L{{.*}}/lib/gcc" +// CHECK012: "-L{{.*}}/hexagon/lib/v4" +// CHECK012: "-L{{.*}}/hexagon/lib" +// CHECK012: "{{[^"]+}}.o" +// CHECK012: "-lstdc++" "-lm" +// CHECK012: "--start-group" "-lstandalone" "-lc" "-lgcc" "--end-group" +// CHECK012: "{{.*}}/hexagon/lib/v4/fini.o" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Additional Libraries (-L) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -Lone -L two -L three \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK013 %s +// CHECK013: "{{.*}}clang{{.*}}" "-cc1" +// CHECK013-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK013-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK013: "{{.*}}/hexagon/lib/v4/crt0_standalone.o" +// CHECK013: "{{.*}}/hexagon/lib/v4/crt0.o" +// CHECK013: "{{.*}}/hexagon/lib/v4/init.o" +// CHECK013: "-Lone" "-Ltwo" "-Lthree" +// CHECK013: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK013: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK013: "-L{{.*}}/lib/gcc" +// CHECK013: "-L{{.*}}/hexagon/lib/v4" +// CHECK013: "-L{{.*}}/hexagon/lib" +// CHECK013: "{{[^"]+}}.o" +// CHECK013: "--start-group" "-lstandalone" "-lc" "-lgcc" "--end-group" +// CHECK013: "{{.*}}/hexagon/lib/v4/fini.o" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// -static, -shared +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -static \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK014 %s +// CHECK014: "{{.*}}clang{{.*}}" "-cc1" +// CHECK014-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK014-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK014: "-static" +// CHECK014: "{{.*}}/hexagon/lib/v4/crt0_standalone.o" +// CHECK014: "{{.*}}/hexagon/lib/v4/crt0.o" +// CHECK014: "{{.*}}/hexagon/lib/v4/init.o" +// CHECK014: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK014: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK014: "-L{{.*}}/lib/gcc" +// CHECK014: "-L{{.*}}/hexagon/lib/v4" +// CHECK014: "-L{{.*}}/hexagon/lib" +// CHECK014: "{{[^"]+}}.o" +// CHECK014: "--start-group" "-lstandalone" "-lc" "-lgcc" "--end-group" +// CHECK014: "{{.*}}/hexagon/lib/v4/fini.o" + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -shared \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK015 %s +// CHECK015: "{{.*}}clang{{.*}}" "-cc1" +// CHECK015-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK015-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK015: "-shared" "-call_shared" +// CHECK015-NOT: crt0_standalone.o +// CHECK015-NOT: crt0.o +// CHECK015: "{{.*}}/hexagon/lib/v4/G0/initS.o" +// CHECK015: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4/G0" +// CHECK015: "-L{{.*}}/lib/gcc/hexagon/4.4.0/G0" +// CHECK015: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK015: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK015: "-L{{.*}}/lib/gcc" +// CHECK015: "-L{{.*}}/hexagon/lib/v4/G0" +// CHECK015: "-L{{.*}}/hexagon/lib/G0" +// CHECK015: "-L{{.*}}/hexagon/lib/v4" +// CHECK015: "-L{{.*}}/hexagon/lib" +// CHECK015: "{{[^"]+}}.o" +// CHECK015: "--start-group" +// CHECK015-NOT: "-lstandalone" +// CHECK015-NOT: "-lc" +// CHECK015: "-lgcc" +// CHECK015: "--end-group" +// CHECK015: "{{.*}}/hexagon/lib/v4/G0/finiS.o" + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -shared \ +// RUN: -static \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK016 %s +// CHECK016: "{{.*}}clang{{.*}}" "-cc1" +// CHECK016-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK016-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK016: "-shared" "-call_shared" "-static" +// CHECK016-NOT: crt0_standalone.o +// CHECK016-NOT: crt0.o +// CHECK016: "{{.*}}/hexagon/lib/v4/G0/init.o" +// CHECK016: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4/G0" +// CHECK016: "-L{{.*}}/lib/gcc/hexagon/4.4.0/G0" +// CHECK016: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK016: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK016: "-L{{.*}}/lib/gcc" +// CHECK016: "-L{{.*}}/hexagon/lib/v4/G0" +// CHECK016: "-L{{.*}}/hexagon/lib/G0" +// CHECK016: "-L{{.*}}/hexagon/lib/v4" +// CHECK016: "-L{{.*}}/hexagon/lib" +// CHECK016: "{{[^"]+}}.o" +// CHECK016: "--start-group" +// CHECK016-NOT: "-lstandalone" +// CHECK016-NOT: "-lc" +// CHECK016: "-lgcc" +// CHECK016: "--end-group" +// CHECK016: "{{.*}}/hexagon/lib/v4/G0/fini.o" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// -nostdlib, -nostartfiles, -nodefaultlibs +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -nostdlib \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK017 %s +// CHECK017: "{{.*}}clang{{.*}}" "-cc1" +// CHECK017-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK017-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK017-NOT: crt0_standalone.o +// CHECK017-NOT: crt0.o +// CHECK017-NOT: init.o +// CHECK017: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK017: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK017: "-L{{.*}}/lib/gcc" +// CHECK017: "-L{{.*}}/hexagon/lib/v4" +// CHECK017: "-L{{.*}}/hexagon/lib" +// CHECK017: "{{[^"]+}}.o" +// CHECK017-NOT: "-lstdc++" +// CHECK017-NOT: "-lm" +// CHECK017-NOT: "--start-group" +// CHECK017-NOT: "-lstandalone" +// CHECK017-NOT: "-lc" +// CHECK017-NOT: "-lgcc" +// CHECK017-NOT: "--end-group" +// CHECK017-NOT: fini.o + +// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -nostartfiles \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK018 %s +// CHECK018: "{{.*}}clang{{.*}}" "-cc1" +// CHECK018-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK018-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK018-NOT: crt0_standalone.o +// CHECK018-NOT: crt0.o +// CHECK018-NOT: init.o +// CHECK018: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK018: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK018: "-L{{.*}}/lib/gcc" +// CHECK018: "-L{{.*}}/hexagon/lib/v4" +// CHECK018: "-L{{.*}}/hexagon/lib" +// CHECK018: "{{[^"]+}}.o" +// CHECK018: "-lstdc++" +// CHECK018: "-lm" +// CHECK018: "--start-group" +// CHECK018: "-lstandalone" +// CHECK018: "-lc" +// CHECK018: "-lgcc" +// CHECK018: "--end-group" +// CHECK018-NOT: fini.o + +// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -nodefaultlibs \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK019 %s +// CHECK019: "{{.*}}clang{{.*}}" "-cc1" +// CHECK019-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK019-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK019: "{{.*}}/hexagon/lib/v4/crt0_standalone.o" +// CHECK019: "{{.*}}/hexagon/lib/v4/crt0.o" +// CHECK019: "{{.*}}/hexagon/lib/v4/init.o" +// CHECK019: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK019: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK019: "-L{{.*}}/lib/gcc" +// CHECK019: "-L{{.*}}/hexagon/lib/v4" +// CHECK019: "-L{{.*}}/hexagon/lib" +// CHECK019: "{{[^"]+}}.o" +// CHECK019-NOT: "-lstdc++" +// CHECK019-NOT: "-lm" +// CHECK019-NOT: "--start-group" +// CHECK019-NOT: "-lstandalone" +// CHECK019-NOT: "-lc" +// CHECK019-NOT: "-lgcc" +// CHECK019-NOT: "--end-group" +// CHECK019: "{{.*}}/hexagon/lib/v4/fini.o" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// -moslib +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -moslib=first -moslib=second \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK020 %s +// CHECK020: "{{.*}}clang{{.*}}" "-cc1" +// CHECK020-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK020-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK020-NOT: "-static" +// CHECK020-NOT: "-shared" +// CHECK020-NOT: crt0_standalone.o +// CHECK020: "{{.*}}/hexagon/lib/v4/crt0.o" +// CHECK020: "{{.*}}/hexagon/lib/v4/init.o" +// CHECK020: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK020: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK020: "-L{{.*}}/lib/gcc" +// CHECK020: "-L{{.*}}/hexagon/lib/v4" +// CHECK020: "-L{{.*}}/hexagon/lib" +// CHECK020: "{{[^"]+}}.o" +// CHECK020: "--start-group" +// CHECK020: "-lfirst" "-lsecond" +// CHECK020-NOT: "-lstandalone" +// CHECK020: "-lc" "-lgcc" "--end-group" +// CHECK020: "{{.*}}/hexagon/lib/v4/fini.o" + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -moslib=first -moslib=second -moslib=standalone\ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK021 %s +// CHECK021: "{{.*}}clang{{.*}}" "-cc1" +// CHECK021-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK021-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK021-NOT: "-static" +// CHECK021-NOT: "-shared" +// CHECK021: "{{.*}}/hexagon/lib/v4/crt0_standalone.o" +// CHECK021: "{{.*}}/hexagon/lib/v4/crt0.o" +// CHECK021: "{{.*}}/hexagon/lib/v4/init.o" +// CHECK021: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK021: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK021: "-L{{.*}}/lib/gcc" +// CHECK021: "-L{{.*}}/hexagon/lib/v4" +// CHECK021: "-L{{.*}}/hexagon/lib" +// CHECK021: "{{[^"]+}}.o" +// CHECK021: "--start-group" +// CHECK021: "-lfirst" "-lsecond" +// CHECK021: "-lstandalone" +// CHECK021: "-lc" "-lgcc" "--end-group" +// CHECK021: "{{.*}}/hexagon/lib/v4/fini.o" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Other args to pass to linker +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -s \ +// RUN: -Tbss 0xdead -Tdata 0xbeef -Ttext 0xcafe \ +// RUN: -t \ +// RUN: -e start_here \ +// RUN: -uFoo -undefined Bar \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK022 %s +// CHECK022: "{{.*}}clang{{.*}}" "-cc1" +// CHECK022-NEXT: "{{.*}}/bin/hexagon-as"{{.*}} +// CHECK022-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK022: "{{.*}}/hexagon/lib/v4/crt0_standalone.o" +// CHECK022: "{{.*}}/hexagon/lib/v4/crt0.o" +// CHECK022: "{{.*}}/hexagon/lib/v4/init.o" +// CHECK022: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4" +// CHECK022: "-L{{.*}}/lib/gcc/hexagon/4.4.0" +// CHECK022: "-L{{.*}}/lib/gcc" +// CHECK022: "-L{{.*}}/hexagon/lib/v4" +// CHECK022: "-L{{.*}}/hexagon/lib" +// CHECK022: "-Tbss" "0xdead" "-Tdata" "0xbeef" "-Ttext" "0xcafe" +// CHECK022: "-s" +// CHECK022: "-t" +// CHECK022: "-u" "Foo" "-undefined" "Bar" +// CHECK022: "{{[^"]+}}.o" +// CHECK022: "-lstdc++" "-lm" +// CHECK022: "--start-group" "-lstandalone" "-lc" "-lgcc" "--end-group" +// CHECK022: "{{.*}}/hexagon/lib/v4/fini.o" + +// ----------------------------------------------------------------------------- +// pic, small data threshold +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK023 %s +// CHECK023: "{{.*}}clang{{.*}}" "-cc1" +// CHECK023: "-mrelocation-model" "static" +// CHECK023-NEXT: "{{.*}}/bin/hexagon-as" +// CHECK023-NOT: "-G{{[0-9]+}}" +// CHECK023-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK023-NOT: "-G{{[0-9]+}}" + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -fpic \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK024 %s +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -fPIC \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK024 %s +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -fPIC \ +// RUN: -msmall_data_threshold=8 \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK024 %s +// CHECK024: "{{.*}}clang{{.*}}" "-cc1" +// CHECK024-NOT: "-mrelocation-model" "static" +// CHECK024: "-pic-level" "{{[12]}}" +// CHECK024: "-mllvm" "-hexagon-small-data-threshold=0" +// CHECK024-NEXT: "{{.*}}/bin/hexagon-as" +// CHECK024: "-G0" +// CHECK024-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK024: "-G0" + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -G=8 \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK025 %s +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -G 8 \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK025 %s +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -msmall-data-threshold=8 \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK025 %s +// CHECK025: "{{.*}}clang{{.*}}" "-cc1" +// CHECK025: "-mrelocation-model" "static" +// CHECK025: "-mllvm" "-hexagon-small-data-threshold=8" +// CHECK025-NEXT: "{{.*}}/bin/hexagon-as" +// CHECK025: "-G8" +// CHECK025-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK025: "-G8" + +// ----------------------------------------------------------------------------- +// pie +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -pie \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK026 %s +// CHECK026: "{{.*}}clang{{.*}}" "-cc1" +// CHECK026-NEXT: "{{.*}}/bin/hexagon-as" +// CHECK026-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK026: "-pie" + +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -pie -shared \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK027 %s +// CHECK027: "{{.*}}clang{{.*}}" "-cc1" +// CHECK027-NEXT: "{{.*}}/bin/hexagon-as" +// CHECK027-NEXT: "{{.*}}/bin/hexagon-ld" +// CHECK027-NOT: "-pie" + +// ----------------------------------------------------------------------------- +// Misc Defaults +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK028 %s +// CHECK028: "{{.*}}clang{{.*}}" "-cc1" +// CHECK028: "-mqdsp6-compat" +// CHECK028: "-Wreturn-type" +// CHECK028-NEXT: "{{.*}}/bin/hexagon-as" +// CHECK028-NEXT: "{{.*}}/bin/hexagon-ld" + +// ----------------------------------------------------------------------------- +// Test Assembler related args +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-elf \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ +// RUN: -gdwarf-2 \ +// RUN: -Wa,--noexecstack,--trap \ +// RUN: -Xassembler --keep-locals \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK029 %s +// CHECK029: "{{.*}}clang{{.*}}" "-cc1" +// CHECK029-NEXT: "{{.*}}/bin/hexagon-as" +// 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 bfa627c421..3e66f354c4 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/inhibit-downstream-commands.c b/test/Driver/inhibit-downstream-commands.c index e06fdb1a3d..5e46708cfe 100644 --- a/test/Driver/inhibit-downstream-commands.c +++ b/test/Driver/inhibit-downstream-commands.c @@ -2,4 +2,5 @@ // CHECK: error: unknown type name 'invalid' // CHECK-NOT: clang: error: assembler command failed // CHECK-NOT: clang: error: linker command failed +// XFAIL: win32 invalid C code! diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c index 79282cbf41..ebac718b33 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 0000000000..fd2b46f41b --- /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 146b1930c6..216b65607e 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 0000000000..e59fadca58 --- /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 0000000000..ac3adfd910 --- /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 new file mode 100644 index 0000000000..6ea49be3c3 --- /dev/null +++ b/test/Driver/mips-eleb.c @@ -0,0 +1,29 @@ +// Check that -EL/-EB options adjust the toolchain flags. +// +// 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 -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 -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 -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" +// MIPS64-EB: "{{.*}}as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB" +// MIPS64-EB: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf64btsmip" diff --git a/test/Driver/mips-features.c b/test/Driver/mips-features.c index 3bebffc11b..31bf1935ea 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 5c16b9b063..9e62c0a95e 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 7752e22b7e..b93054dbf8 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 -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 037cdd0c3c..0000000000 --- a/test/Driver/modules_integrated_as.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %clang -fmodules -no-integrated-as -fsyntax-only %s 2>&1 | FileCheck %s - -// CHECK: error: modules can only be used with the compiler's integrated assembler -// CHECK note: '-no-integrated-as' cannot be used with '-fmodules' diff --git a/test/Driver/no-integrated-as-win.c b/test/Driver/no-integrated-as-win.c new file mode 100644 index 0000000000..0d6c2958e5 --- /dev/null +++ b/test/Driver/no-integrated-as-win.c @@ -0,0 +1,3 @@ +// RUN: %clang -target x86_64-pc-win32 -### -no-integrated-as %s -c 2>&1 | FileCheck %s + +// CHECK: there is no external assembler we can use on windows diff --git a/test/Driver/objc++-cpp-output.mm b/test/Driver/objc++-cpp-output.mm index 63b15d8c18..a42f7b2557 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 8c174f7732..293bbc7ef2 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 c1fec56eac..042ae3d40c 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 8ba931954b..3faed2d18f 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/ppc-features.cpp b/test/Driver/ppc-features.cpp index 1918ed7d76..be78e19861 100644 --- a/test/Driver/ppc-features.cpp +++ b/test/Driver/ppc-features.cpp @@ -68,3 +68,21 @@ // RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-qpx -mqpx -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-QPX %s // CHECK-QPX-NOT: "-target-feature" "-qpx" +// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-mfcrf -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOMFCRF %s +// CHECK-NOMFCRF: "-target-feature" "-mfocrf" + +// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-mfcrf -mmfcrf -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-MFCRF %s +// CHECK-MFCRF: "-target-feature" "+mfocrf" + +// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-popcntd -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOPOPCNTD %s +// CHECK-NOPOPCNTD: "-target-feature" "-popcntd" + +// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-popcntd -mpopcntd -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-POPCNTD %s +// CHECK-POPCNTD: "-target-feature" "+popcntd" + +// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-fprnd -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOFPRND %s +// CHECK-NOFPRND: "-target-feature" "-fprnd" + +// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-fprnd -mfprnd -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-FPRND %s +// CHECK-FPRND: "-target-feature" "+fprnd" + diff --git a/test/Driver/r600-mcpu.cl b/test/Driver/r600-mcpu.cl new file mode 100644 index 0000000000..1c5e76225b --- /dev/null +++ b/test/Driver/r600-mcpu.cl @@ -0,0 +1,52 @@ +// 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=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=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 +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv740 %s -o - 2>&1 | FileCheck --check-prefix=RV770-CHECK %s +// 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=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 +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=hemlock %s -o - 2>&1 | FileCheck --check-prefix=CYPRESS-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=cypress %s -o - 2>&1 | FileCheck --check-prefix=CYPRESS-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=barts %s -o - 2>&1 | FileCheck --check-prefix=BARTS-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=turks %s -o - 2>&1 | FileCheck --check-prefix=TURKS-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=caicos %s -o - 2>&1 | FileCheck --check-prefix=CAICOS-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=cayman %s -o - 2>&1 | FileCheck --check-prefix=CAYMAN-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=aruba %s -o - 2>&1 | FileCheck --check-prefix=CAYMAN-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=tahiti %s -o - 2>&1 | FileCheck --check-prefix=TAHITI-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=pitcairn %s -o - 2>&1 | FileCheck --check-prefix=PITCAIRN-CHECK %s +// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=verde %s -o - 2>&1 | FileCheck --check-prefix=VERDE-CHECK %s +// 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" +// TURKS-CHECK: "-target-cpu" "turks" +// CAICOS-CHECK: "-target-cpu" "caicos" +// CAYMAN-CHECK: "-target-cpu" "cayman" +// TAHITI-CHECK: "-target-cpu" "tahiti" +// PITCAIRN-CHECK: "-target-cpu" "pitcairn" +// VERDE-CHECK: "-target-cpu" "verde" +// OLAND-CHECK: "-target-cpu" "oland" diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c index 9bb2eab29a..fd7e97fc20 100644 --- a/test/Driver/sanitizer-ld.c +++ b/test/Driver/sanitizer-ld.c @@ -2,6 +2,7 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target i386-unknown-linux -fsanitize=address \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ASAN-LINUX %s // @@ -9,11 +10,14 @@ // 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: "-export-dynamic" +// CHECK-ASAN-LINUX-NOT: "-export-dynamic" +// CHECK-ASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.asan-i386.a.syms" // RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target i386-unknown-linux -fsanitize=address \ +// RUN: -resource-dir=%S/Inputs/empty_resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ASAN-LINUX-CXX %s // @@ -21,8 +25,10 @@ // 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" // CHECK-ASAN-LINUX-CXX: stdc++ // RUN: %clang -no-canonical-prefixes %s -### -o /dev/null -fsanitize=address \ @@ -58,6 +64,7 @@ // RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target x86_64-unknown-linux -lstdc++ -fsanitize=thread \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-TSAN-LINUX-CXX %s // @@ -65,12 +72,15 @@ // 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: "-export-dynamic" +// CHECK-TSAN-LINUX-CXX-NOT: "-export-dynamic" +// CHECK-TSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.tsan-x86_64.a.syms" // CHECK-TSAN-LINUX-CXX: stdc++ // RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target x86_64-unknown-linux -lstdc++ -fsanitize=memory \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-MSAN-LINUX-CXX %s // @@ -78,8 +88,10 @@ // 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: "-export-dynamic" +// CHECK-MSAN-LINUX-CXX-NOT: "-export-dynamic" +// CHECK-MSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.msan-x86_64.a.syms" // CHECK-MSAN-LINUX-CXX: stdc++ // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \ @@ -87,9 +99,52 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s // CHECK-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}" -// CHECK-UBSAN-LINUX-NOT: "-lc" -// CHECK-UBSAN-LINUX: libclang_rt.ubsan-i386.a" +// CHECK-UBSAN-LINUX-NOT: libclang_rt.asan +// CHECK-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.san-i386.a" "-no-whole-archive" +// CHECK-UBSAN-LINUX-NOT: libclang_rt.asan +// CHECK-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive" +// CHECK-UBSAN-LINUX-NOT: libclang_rt.ubsan_cxx // CHECK-UBSAN-LINUX: "-lpthread" +// CHECK-UBSAN-LINUX-NOT: "-lstdc++" + +// RUN: %clangxx -fsanitize=undefined %s -### -o %t.o 2>&1 \ +// RUN: -target i386-unknown-linux \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX-CXX %s +// CHECK-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}" +// CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan +// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.san-i386.a" "-no-whole-archive" +// CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan +// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive" +// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan_cxx-i386.a" "-no-whole-archive" +// CHECK-UBSAN-LINUX-CXX: "-lpthread" +// CHECK-UBSAN-LINUX-CXX: "-lstdc++" + +// RUN: %clang -fsanitize=address,undefined %s -### -o %t.o 2>&1 \ +// RUN: -target i386-unknown-linux \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-ASAN-UBSAN-LINUX %s +// CHECK-ASAN-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}" +// CHECK-ASAN-UBSAN-LINUX-NOT: libclang_rt.san +// CHECK-ASAN-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive" +// CHECK-ASAN-UBSAN-LINUX-NOT: libclang_rt.san +// CHECK-ASAN-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive" +// CHECK-ASAN-UBSAN-LINUX-NOT: libclang_rt.ubsan_cxx +// CHECK-ASAN-UBSAN-LINUX: "-lpthread" +// CHECK-ASAN-UBSAN-LINUX-NOT: "-lstdc++" + +// RUN: %clangxx -fsanitize=address,undefined %s -### -o %t.o 2>&1 \ +// RUN: -target i386-unknown-linux \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-ASAN-UBSAN-LINUX-CXX %s +// CHECK-ASAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}" +// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: libclang_rt.san +// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive" +// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: libclang_rt.san +// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive" +// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan_cxx-i386.a" "-no-whole-archive" +// CHECK-ASAN-UBSAN-LINUX-CXX: "-lpthread" +// CHECK-ASAN-UBSAN-LINUX-CXX: "-lstdc++" // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \ // RUN: -target i386-unknown-linux \ @@ -97,6 +152,4 @@ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHARED %s // CHECK-UBSAN-LINUX-SHARED: "{{.*}}ld{{(.exe)?}}" -// CHECK-UBSAN-LINUX-SHARED-NOT: "-lc" -// CHECK-UBSAN-LINUX-SHARED: libclang_rt.ubsan-i386.a" -// CHECK-UBSAN-LINUX-SHARED: "-lpthread" +// CHECK-UBSAN-LINUX-SHARED-NOT: libclang_rt.ubsan-i386.a" diff --git a/test/Driver/save-temps.c b/test/Driver/save-temps.c new file mode 100644 index 0000000000..a4ca3b2664 --- /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 0000000000..d5f077af13 --- /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/Driver/unknown-gcc-arch.c b/test/Driver/unknown-gcc-arch.c index 5e4746babd..dcd17d4f46 100644 --- a/test/Driver/unknown-gcc-arch.c +++ b/test/Driver/unknown-gcc-arch.c @@ -1,8 +1,32 @@ -// RUN: %clang -target x86_64-unknown-unknown -c -x assembler %s -### 2> %t.log -// RUN: grep '.*gcc.*"-m64"' %t.log -// RUN: %clang -target x86_64-unknown-unknown -c -x assembler %s -### -m32 2> %t.log -// RUN: grep '.*gcc.*"-m32"' %t.log -// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### 2> %t.log -// RUN: grep '.*gcc.*"-m32"' %t.log -// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### -m64 2> %t.log -// RUN: grep '.*gcc.*"-m64"' %t.log +// RUN: %clang -target x86_64-unknown-unknown -c -x assembler %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=X86_64 %s +// X86_64: {{.*gcc.*-m64}} + +// RUN: %clang -target x86_64-unknown-unknown -c -x assembler %s -### -m32 2>&1 \ +// RUN: | FileCheck -check-prefix=X86_64-M32 %s +// X86_64-M32: {{.*gcc.*-m32}} + +// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=I386 %s +// I386: {{.*gcc.*-m32}} + +// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### -m64 2>&1 \ +// RUN: | FileCheck -check-prefix=I386-M64 %s +// I386-M64: {{.*gcc.*-m64}} + + +// RUN: %clang -target powerpc64-unknown-unknown -c -x assembler %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=PPC64 %s +// PPC64: {{.*gcc.*-m64}} + +// RUN: %clang -target powerpc64-unknown-unknown -c -x assembler %s -### -m32 2>&1 \ +// RUN: | FileCheck -check-prefix=PPC64-M32 %s +// PPC64-M32: {{.*gcc.*-m32}} + +// RUN: %clang -target powerpc-unknown-unknown -c -x assembler %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=PPC %s +// PPC: {{.*gcc.*-m32}} + +// RUN: %clang -target powerpc-unknown-unknown -c -x assembler %s -### -m64 2>&1 \ +// RUN: | FileCheck -check-prefix=PPC-M64 %s +// PPC-M64: {{.*gcc.*-m64}} diff --git a/test/FixIt/auto-isa-fixit.m b/test/FixIt/auto-isa-fixit.m new file mode 100644 index 0000000000..3f22c1838a --- /dev/null +++ b/test/FixIt/auto-isa-fixit.m @@ -0,0 +1,66 @@ +// RUN: cp %s %t +// RUN: %clang_cc1 -x objective-c -fixit %t +// RUN: %clang_cc1 -x objective-c -Werror %t +// rdar://13503456 + +void object_setClass(id, id); +Class object_getClass(id); + +id rhs(); + +Class pr6302(id x123) { + x123->isa = 0; + x123->isa = rhs(); + x123->isa = (id)(x123->isa); + x123->isa = (id)x123->isa; + x123->isa = (x123->isa); + x123->isa = (id)(x123->isa); + return x123->isa; +} + + +@interface BaseClass { +@public + Class isa; // expected-note 3 {{instance variable is declared here}} +} +@end + +@interface OtherClass { +@public + id firstIvar; + Class isa; // note, not first ivar; +} +@end + +@interface Subclass : BaseClass @end + +@interface SiblingClass : BaseClass @end + +@interface Root @end + +@interface hasIsa : Root { +@public + Class isa; // note, isa is not in root class +} +@end + +@implementation Subclass +-(void)method { + hasIsa *u; + id v; + BaseClass *w; + Subclass *x; + SiblingClass *y; + OtherClass *z; + (void)v->isa; + (void)w->isa; + (void)x->isa; + (void)y->isa; + (void)z->isa; + (void)u->isa; + y->isa = 0; + y->isa = w->isa; + x->isa = rhs(); +} +@end + diff --git a/test/FixIt/bridge-in-non-arc.m b/test/FixIt/bridge-in-non-arc.m index 948fa8ebcc..b4d2677be0 100644 --- a/test/FixIt/bridge-in-non-arc.m +++ b/test/FixIt/bridge-in-non-arc.m @@ -4,9 +4,9 @@ @end void foo(void *p) { - I *i = (__bridge I*)p; - I *i2 = (__bridge/*cake*/I*)p; + I *i = (__bridge_transfer I*)p; + I *i2 = (__bridge_transfer/*cake*/I*)p; } -// CHECK: {7:11-7:20}:"" -// CHECK: {8:12-8:20}:"" +// CHECK: {7:11-7:29}:"" +// CHECK: {8:12-8:29}:"" diff --git a/test/FixIt/fixit-cxx1y-compat.cpp b/test/FixIt/fixit-cxx1y-compat.cpp new file mode 100644 index 0000000000..9fd5ff26e5 --- /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/FixIt/fixit.cpp b/test/FixIt/fixit.cpp index 253abd0f4e..fca596b715 100644 --- a/test/FixIt/fixit.cpp +++ b/test/FixIt/fixit.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -pedantic -Wall -Wno-comment -verify -fcxx-exceptions -x c++ %s +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -x c++ %s 2>&1 | FileCheck %s // RUN: cp %s %t // RUN: not %clang_cc1 -pedantic -Wall -Wno-comment -fcxx-exceptions -fixit -x c++ %t // RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Werror -Wno-comment -fcxx-exceptions -x c++ %t @@ -299,3 +300,10 @@ class foo { } int i(); }; + +namespace dtor_fixit { + class foo { + ~bar() { } // expected-error {{expected the class name after '~' to name a destructor}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:6-[[@LINE-1]]:9}:"foo" + }; +} diff --git a/test/FixIt/format-darwin.m b/test/FixIt/format-darwin.m index cfaac29e90..f520564348 100644 --- a/test/FixIt/format-darwin.m +++ b/test/FixIt/format-darwin.m @@ -23,6 +23,8 @@ typedef long SInt32; typedef unsigned long UInt32; #endif +typedef SInt32 OSStatus; + NSInteger getNSInteger(); NSUInteger getNSUInteger(); SInt32 getSInt32(); @@ -210,3 +212,9 @@ void testCapitals() { // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:14}:"d" // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:14}:"%D" } + +void testLayeredTypedefs(OSStatus i) { + printf("%s", i); // expected-warning {{values of type 'OSStatus' should not be used as format arguments}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d" +} + diff --git a/test/Format/basic.cpp b/test/Format/basic.cpp new file mode 100644 index 0000000000..a12866b9c1 --- /dev/null +++ b/test/Format/basic.cpp @@ -0,0 +1,6 @@ +// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp +// RUN: clang-format -style=LLVM -i %t.cpp +// RUN: FileCheck -strict-whitespace -input-file=%t.cpp %s + +// CHECK: {{^int\ \*i;}} + int * i ; diff --git a/test/Format/diagnostic.cpp b/test/Format/diagnostic.cpp new file mode 100644 index 0000000000..2e930ee5b7 --- /dev/null +++ b/test/Format/diagnostic.cpp @@ -0,0 +1,4 @@ +// RUN: clang-format 2>&1 >/dev/null %s |FileCheck %s + +} +// CHECK: diagnostic.cpp:[[@LINE-1]]:1: error: unexpected '}' diff --git a/test/Format/multiple-inputs-error.cpp b/test/Format/multiple-inputs-error.cpp new file mode 100644 index 0000000000..71f87e0b15 --- /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 0000000000..74c30db71e --- /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 0000000000..df267149fe --- /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 new file mode 100644 index 0000000000..c7fdd4b97a --- /dev/null +++ b/test/Format/ranges.cpp @@ -0,0 +1,11 @@ +// RUN: grep -Ev "// *[A-Z-]+:" %s > %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; + +// CHECK: {{^\ \ int\ \ \*\ \ i;$}} + int * i; + +// 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 0000000000..e827ad99cf --- /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/ast-main.cpp b/test/Frontend/ast-main.cpp new file mode 100644 index 0000000000..4bddbe1372 --- /dev/null +++ b/test/Frontend/ast-main.cpp @@ -0,0 +1,22 @@ +// RUN: %clang -emit-llvm -S -o %t1.ll -x c++ - < %s +// RUN: %clang -fno-delayed-template-parsing -emit-ast -o %t.ast %s +// RUN: %clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast +// RUN: diff %t1.ll %t2.ll + +// http://llvm.org/bugs/show_bug.cgi?id=15377 +template<typename T> +struct S { + T *mf(); +}; +template<typename T> +T *S<T>::mf() { + // warning: control reaches end of non-void function [-Wreturn-type] +} + +void f() { + S<int>().mf(); +} + +int main() { + return 0; +} diff --git a/test/Frontend/dependency-gen-escaping.c b/test/Frontend/dependency-gen-escaping.c new file mode 100644 index 0000000000..84eb242ec3 --- /dev/null +++ b/test/Frontend/dependency-gen-escaping.c @@ -0,0 +1,17 @@ +// REQUIRES: shell +// PR15642 +// RUN: rm -rf %t.dir +// RUN: mkdir -p %t.dir +// RUN: echo > '%t.dir/ .h' +// RUN: echo > '%t.dir/$$.h' +// RUN: echo > '%t.dir/##.h' +// RUN: cd %t.dir +// RUN: %clang -MD -MF - %s -fsyntax-only -I. | FileCheck -strict-whitespace %s + +// CHECK: \ \ \ \ .h +// CHECK: $$$$.h +// CHECK: \#\#.h + +#include " .h" +#include "$$.h" +#include "##.h" diff --git a/test/Frontend/rewrite-includes-invalid-hasinclude.c b/test/Frontend/rewrite-includes-invalid-hasinclude.c new file mode 100644 index 0000000000..e32d6ad8a3 --- /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 b79bbd9ca8..da4e209bc1 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 0000000000..783a96739a --- /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 546a2c44af..bf330a60a3 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 bc7479693b..eab66571b8 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 062e6bd861..3d71e04980 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 24a1c2a60d..21f2e4f222 100644 --- a/test/Headers/c11.c +++ b/test/Headers/c11.c @@ -1,4 +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+{{}} @@ -16,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 995fc6528d..54fe350ea5 100644 --- a/test/Headers/cxx11.cpp +++ b/test/Headers/cxx11.cpp @@ -1,4 +1,5 @@ // RUN: %clang -fsyntax-only -std=c++11 %s +// RUN: %clang -fsyntax-only -std=c++11 -fmodules %s #include <stdalign.h> @@ -12,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 0000000000..f015fc77ee --- /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-deep-statements.cpp b/test/Index/annotate-deep-statements.cpp index 32a48b7d6a..79f2d39ae5 100644 --- a/test/Index/annotate-deep-statements.cpp +++ b/test/Index/annotate-deep-statements.cpp @@ -3,6 +3,9 @@ // rdar://11979525 // Check that we don't get stack overflow trying to annotate an extremely deep AST. +// AddressSanitizer increases stack usage. +// XFAIL: asan + struct S { S &operator()(); }; diff --git a/test/Index/annotate-module.m b/test/Index/annotate-module.m index 33ca3f8324..55e21d235e 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 3062901b7c..16726547a2 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 7e888e394c..40c66a18b8 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 b0fb71e419..61d82a6cde 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 0000000000..fa0db914cd --- /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 0000000000..9eae5489fc --- /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-to-html-xml-conversion.cpp b/test/Index/comment-to-html-xml-conversion.cpp index b33fa4ace4..c770ca8d30 100644 --- a/test/Index/comment-to-html-xml-conversion.cpp +++ b/test/Index/comment-to-html-xml-conversion.cpp @@ -19,6 +19,7 @@ // RUN: FileCheck %s < %t/out.c-index-direct // RUN: FileCheck %s < %t/out.c-index-pch +// XFAIL: msan // XFAIL: valgrind #ifndef HEADER diff --git a/test/Index/comment-unqualified-objc-pointer.m b/test/Index/comment-unqualified-objc-pointer.m new file mode 100644 index 0000000000..546d4fa9f0 --- /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 0000000000..72e6140d12 --- /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/complete-declarators.m b/test/Index/complete-declarators.m index d42a3c7a6c..b3a60ded11 100644 --- a/test/Index/complete-declarators.m +++ b/test/Index/complete-declarators.m @@ -22,6 +22,7 @@ static P *p = 0; } +- (boid)method2 {} @end // RUN: c-index-test -code-completion-at=%s:7:4 %s | FileCheck -check-prefix=CHECK-CC0 %s @@ -81,3 +82,8 @@ // CHECK-CC5: NotImplemented:{TypedText unsigned} (50) // CHECK-CC5: NotImplemented:{TypedText void} (50) // CHECK-CC5: NotImplemented:{TypedText volatile} (50) + +// Check that there are no duplicate entries if we code-complete after an @implementation +// RUN: c-index-test -code-completion-at=%s:27:1 %s | FileCheck -check-prefix=CHECK-CC6 %s +// CHECK-CC6: ObjCInterfaceDecl:{TypedText A} +// CHECK-CC6-NOT: ObjCInterfaceDecl:{TypedText A} diff --git a/test/Index/complete-documentation-properties.m b/test/Index/complete-documentation-properties.m index d423f84d22..774a02021e 100644 --- a/test/Index/complete-documentation-properties.m +++ b/test/Index/complete-documentation-properties.m @@ -49,6 +49,7 @@ p = [self PropertyInPrimaryClass]; p = [self Record]; [self setThisRecord : (id)0 ]; + p = self.GetterInClassExtension; return 0; } @end @@ -66,3 +67,26 @@ // RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:51:9 %s | FileCheck -check-prefix=CC5 %s // CHECK-CC5: {TypedText setThisRecord:}{Placeholder (id)}{{.*}}(brief comment: This is Record) + +// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:52:12 %s | FileCheck -check-prefix=CC6 %s +// CHECK-CC6: {TypedText GetterInClassExtension}{{.*}}(brief comment: This is PropertyInClassExtension) + +@interface AnotherAppDelegate +/** + \brief This is ReadonlyProperty +*/ +@property (getter = ReadonlyGetter) int MyProperty; +/** + \brief This is getter = ReadonlyGetter +*/ +- (int) ReadonlyGetter; +@end + +@implementation AnotherAppDelegate +- (int) PropertyInPrimaryClass { +self.ReadonlyGetter; +} +@end +// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:87:6 %s | FileCheck -check-prefix=CC7 %s +// CHECK-CC7: {TypedText ReadonlyGetter}{{.*}}(brief comment: This is getter = ReadonlyGetter) + diff --git a/test/Index/crash-recovery-code-complete.c b/test/Index/crash-recovery-code-complete.c index f001578f78..c502ce5186 100644 --- a/test/Index/crash-recovery-code-complete.c +++ b/test/Index/crash-recovery-code-complete.c @@ -8,4 +8,7 @@ // // REQUIRES: crash-recovery +// FIXME: Please investigate abnormal path in MemoryBuffer. +// XFAIL: mingw32,win32 + #warning parsing original file diff --git a/test/Index/get-cursor.cpp b/test/Index/get-cursor.cpp index 8b70216dd1..996ecc25ef 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 b82345f9c6..f25013b882 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 58770191ea..db7b48f7ef 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/modules-objc-categories.m b/test/Index/modules-objc-categories.m new file mode 100644 index 0000000000..4d0fd260d4 --- /dev/null +++ b/test/Index/modules-objc-categories.m @@ -0,0 +1,10 @@ +@import category_top; +@import category_left; + +@interface Sub : Foo +- (void)left_sub; +@end + +// RUN: rm -rf %t +// RUN: c-index-test -test-load-source local -fmodules -fmodules-cache-path=%t %s -I%S/../Modules/Inputs | FileCheck %s +// CHECK: modules-objc-categories.m:5:9: ObjCInstanceMethodDecl=left_sub:5:9 [Overrides @2:9] diff --git a/test/Index/parse-all-comments.c b/test/Index/parse-all-comments.c new file mode 100644 index 0000000000..f8b0449f20 --- /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 0000000000..698d96705b --- /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 9358772dbf..4805f59f3f 100644 --- a/test/Index/print-type.c +++ b/test/Index/print-type.c @@ -11,17 +11,17 @@ 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] // CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0] -// CHECK: CallExpr=fn:3:55 [type=void] [typekind=Void] [isPOD=0] +// CHECK: CallExpr=fn:3:55 [type=void] [typekind=Void] [args= [int] [Int]] [isPOD=0] // CHECK: DeclRefExpr=fn:3:55 [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] // CHECK: UnaryOperator= [type=int] [typekind=Int] [isPOD=1] // CHECK: DeclRefExpr=p:3:13 [type=int *] [typekind=Pointer] [isPOD=1] diff --git a/test/Index/print-type.cpp b/test/Index/print-type.cpp index 876bda9dd2..49a05fbbdb 100644 --- a/test/Index/print-type.cpp +++ b/test/Index/print-type.cpp @@ -23,6 +23,12 @@ 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] @@ -54,3 +60,7 @@ struct Bar { // CHECK: DeclRefExpr=z:15:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] // CHECK: TypedefDecl=OtherType:19:18 (Definition) [type=OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1] // 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 9325c3fbdd..6f146f8020 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 aa992075c6..0fa0ecba6b 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 0000000000..9682a9f71d --- /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 cfa1046cc8..022a139d36 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 be0e323c93..dccfb75872 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 0000000000..96dce3dd44 --- /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 6ffeebda1f..68b542fb29 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 c9a5f56ddf..e26e309c03 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 8e0222dcec..62a965caac 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 b67886fa33..d0bbe9ea3a 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 0000000000..224ccfbbf8 --- /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 c74da29f6d..94335b825c 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 c8f7d2fe6c..31715cd15e 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/ast-dump-stmt.cpp b/test/Misc/ast-dump-stmt.cpp new file mode 100644 index 0000000000..cf3e8bf289 --- /dev/null +++ b/test/Misc/ast-dump-stmt.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s + +namespace n { +void function() {} +int Variable; +} +using n::function; +using n::Variable; +void TestFunction() { + void (*f)() = &function; +// CHECK: DeclRefExpr{{.*}} (UsingShadow{{.*}}function + Variable = 4; +// CHECK: DeclRefExpr{{.*}} (UsingShadow{{.*}}Variable +} diff --git a/test/Misc/diag-template-diffing-color.cpp b/test/Misc/diag-template-diffing-color.cpp index 2c228414b3..c771857f39 100644 --- a/test/Misc/diag-template-diffing-color.cpp +++ b/test/Misc/diag-template-diffing-color.cpp @@ -70,3 +70,17 @@ void test19() { // TREE: vector< // TREE: [const != const [[CYAN]]volatile[[RESET]]] vector< // TREE: [...]>> + +namespace default_args { + template <int x, int y = 1+1, int z = 2> + class A {}; + + void foo(A<0> &M) { + // CHECK: no viable conversion from 'A<[...], (default) [[CYAN]]1 + 1[[RESET]][[BOLD]] aka [[CYAN]]2[[RESET]][[BOLD]], (default) [[CYAN]]2[[RESET]][[BOLD]]>' to 'A<[...], [[CYAN]]0[[RESET]][[BOLD]], [[CYAN]]0[[RESET]][[BOLD]]>' + A<0, 0, 0> N = M; + + // CHECK: no viable conversion from 'A<[2 * ...], (default) [[CYAN]]2[[RESET]][[BOLD]]>' to 'A<[2 * ...], [[CYAN]]0[[RESET]][[BOLD]]>' + A<0, 2, 0> N2 = M; + } + +} diff --git a/test/Misc/diag-template-diffing-cxx98.cpp b/test/Misc/diag-template-diffing-cxx98.cpp index cd40ccc374..a21e4cf060 100644 --- a/test/Misc/diag-template-diffing-cxx98.cpp +++ b/test/Misc/diag-template-diffing-cxx98.cpp @@ -4,4 +4,46 @@ namespace PR14342 { template<typename T, char a> struct X {}; X<int, 1> x = X<long, 257>(); // CHECK: error: no viable conversion from 'X<long, [...]>' to 'X<int, [...]>' -}
\ No newline at end of file +} + +namespace PR15513 { + template <int x, int y = x+1> + class A {}; + + void foo(A<0> &M) { + // CHECK: no viable conversion from 'A<[...], (default) x + 1 aka 1>' to 'A<[...], 0>' + A<0, 0> N = M; + // CHECK: no viable conversion from 'A<0, [...]>' to 'A<1, [...]>' + A<1, 1> O = M; + } +} + +namespace default_args { + template <int x, int y = 1+1, int z = 2> + class A {}; + + void foo(A<0> &M) { + // CHECK: no viable conversion from 'A<[...], (default) 1 + 1 aka 2, (default) 2>' to 'A<[...], 0, 0>' + A<0, 0, 0> N = M; + + // CHECK: no viable conversion from 'A<[2 * ...], (default) 2>' to 'A<[2 * ...], 0>' + A<0, 2, 0> N2 = M; + } + +} + +namespace qualifiers { + template <class T> + void foo(void (func(T*)), T*) {} + + template <class T> + class vector{}; + + void bar(const vector<int>*) {} + + void test(volatile vector<int>* V) { + foo(bar, V); + } + + // CHECK: candidate template ignored: deduced conflicting types for parameter 'T' ('const vector<[...]>' vs. 'volatile vector<[...]>') +} diff --git a/test/Misc/diag-template-diffing.cpp b/test/Misc/diag-template-diffing.cpp index 6be705511d..add96efd37 100644 --- a/test/Misc/diag-template-diffing.cpp +++ b/test/Misc/diag-template-diffing.cpp @@ -645,41 +645,41 @@ void Play1() { } // CHECK-ELIDE-NOTREE: no viable overloaded '=' -// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<1>' to 'Foo1<2>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<1>' to 'const Foo1<2>' for 1st argument // CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo1<1>' to 'Foo1<2>' for 1st argument // CHECK-ELIDE-NOTREE: no viable overloaded '=' -// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<2>' to 'Foo1<1>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<2>' to 'const Foo1<1>' for 1st argument // CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo1<2>' to 'Foo1<1>' for 1st argument // CHECK-NOELIDE-NOTREE: no viable overloaded '=' -// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<1>' to 'Foo1<2>' for 1st argument +// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<1>' to 'const Foo1<2>' for 1st argument // CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo1<1>' to 'Foo1<2>' for 1st argument // CHECK-NOELIDE-NOTREE: no viable overloaded '=' -// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<2>' to 'Foo1<1>' for 1st argument +// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<2>' to 'const Foo1<1>' for 1st argument // CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo1<2>' to 'Foo1<1>' for 1st argument // CHECK-ELIDE-TREE: no viable overloaded '=' // CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-ELIDE-TREE: Foo1< +// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo1< // CHECK-ELIDE-TREE: [1 != 2]> // CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-ELIDE-TREE: Foo1< // CHECK-ELIDE-TREE: [1 != 2]> // CHECK-ELIDE-TREE: no viable overloaded '=' // CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-ELIDE-TREE: Foo1< +// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo1< // CHECK-ELIDE-TREE: [2 != 1]> // CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-ELIDE-TREE: Foo1< // CHECK-ELIDE-TREE: [2 != 1]> // CHECK-NOELIDE-TREE: no viable overloaded '=' // CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-NOELIDE-TREE: Foo1< +// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo1< // CHECK-NOELIDE-TREE: [1 != 2]> // CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-NOELIDE-TREE: Foo1< // CHECK-NOELIDE-TREE: [1 != 2]> // CHECK-NOELIDE-TREE: no viable overloaded '=' // CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-NOELIDE-TREE: Foo1< +// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo1< // CHECK-NOELIDE-TREE: [2 != 1]> // CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-NOELIDE-TREE: Foo1< @@ -694,41 +694,41 @@ void Play2() { F3 = F2; } // CHECK-ELIDE-NOTREE: no viable overloaded '=' -// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<1>' to 'Foo2<2>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<1>' to 'const Foo2<2>' for 1st argument // CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo2<1>' to 'Foo2<2>' for 1st argument // CHECK-ELIDE-NOTREE: no viable overloaded '=' -// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'Foo2<1>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'const Foo2<1>' for 1st argument // CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'Foo2<1>' for 1st argument // CHECK-NOELIDE-NOTREE: no viable overloaded '=' -// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<1>' to 'Foo2<2>' for 1st argument +// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<1>' to 'const Foo2<2>' for 1st argument // CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo2<1>' to 'Foo2<2>' for 1st argument // CHECK-NOELIDE-NOTREE: no viable overloaded '=' -// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'Foo2<1>' for 1st argument +// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'const Foo2<1>' for 1st argument // CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'Foo2<1>' for 1st argument // CHECK-ELIDE-TREE: no viable overloaded '=' // CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-ELIDE-TREE: Foo2< +// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo2< // CHECK-ELIDE-TREE: [1 != 2]> // CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-ELIDE-TREE: Foo2< // CHECK-ELIDE-TREE: [1 != 2]> // CHECK-ELIDE-TREE: no viable overloaded '=' // CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-ELIDE-TREE: Foo2< +// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo2< // CHECK-ELIDE-TREE: [(default) 2 != 1]> // CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-ELIDE-TREE: Foo2< // CHECK-ELIDE-TREE: [(default) 2 != 1]> // CHECK-NOELIDE-TREE: no viable overloaded '=' // CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-NOELIDE-TREE: Foo2< +// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo2< // CHECK-NOELIDE-TREE: [1 != 2]> // CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-NOELIDE-TREE: Foo2< // CHECK-NOELIDE-TREE: [1 != 2]> // CHECK-NOELIDE-TREE: no viable overloaded '=' // CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-NOELIDE-TREE: Foo2< +// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo2< // CHECK-NOELIDE-TREE: [(default) 2 != 1]> // CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-NOELIDE-TREE: Foo2< @@ -743,20 +743,20 @@ void Play3() { F3 = F2; } // CHECK-ELIDE-NOTREE: no viable overloaded '=' -// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'Foo3<2, 1>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'const Foo3<2, 1>' for 1st argument // CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'Foo3<2, 1>' for 1st argument // CHECK-ELIDE-NOTREE: no viable overloaded '=' -// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'Foo3<1, (no argument)>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'const Foo3<1, (no argument)>' for 1st argument // CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'Foo3<1, (no argument)>' for 1st argument // CHECK-NOELIDE-NOTREE: no viable overloaded '=' -// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'Foo3<2, 1>' for 1st argument +// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'const Foo3<2, 1>' for 1st argument // CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'Foo3<2, 1>' for 1st argument // CHECK-NOELIDE-NOTREE: no viable overloaded '=' -// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'Foo3<1, (no argument)>' for 1st argument +// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'const Foo3<1, (no argument)>' for 1st argument // CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'Foo3<1, (no argument)>' for 1st argument // CHECK-ELIDE-TREE: no viable overloaded '=' // CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-ELIDE-TREE: Foo3< +// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo3< // CHECK-ELIDE-TREE: [1 != 2], // CHECK-ELIDE-TREE: [(no argument) != 1]> // CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument @@ -765,7 +765,7 @@ void Play3() { // CHECK-ELIDE-TREE: [(no argument) != 1]> // CHECK-ELIDE-TREE: no viable overloaded '=' // CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-ELIDE-TREE: Foo3< +// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo3< // CHECK-ELIDE-TREE: [2 != 1], // CHECK-ELIDE-TREE: [1 != (no argument)]> // CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument @@ -774,7 +774,7 @@ void Play3() { // CHECK-ELIDE-TREE: [1 != (no argument)]> // CHECK-NOELIDE-TREE: no viable overloaded '=' // CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-NOELIDE-TREE: Foo3< +// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo3< // CHECK-NOELIDE-TREE: [1 != 2], // CHECK-NOELIDE-TREE: [(no argument) != 1]> // CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument @@ -783,7 +783,7 @@ void Play3() { // CHECK-NOELIDE-TREE: [(no argument) != 1]> // CHECK-NOELIDE-TREE: no viable overloaded '=' // CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-NOELIDE-TREE: Foo3< +// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo3< // CHECK-NOELIDE-TREE: [2 != 1], // CHECK-NOELIDE-TREE: [1 != (no argument)]> // CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument @@ -797,7 +797,7 @@ namespace PR14342 { X<int, (signed char)-1> x = X<long, -1>(); X<int, 3UL> y = X<int, 2>(); // CHECK-ELIDE-NOTREE: error: no viable conversion from 'X<long, [...]>' to 'X<int, [...]>' - // CHECK-ELIDE-NOTREE: error: no viable conversion from 'X<[...], 2>' to 'X<[...], 3UL>' + // CHECK-ELIDE-NOTREE: error: no viable conversion from 'X<[...], 2>' to 'X<[...], 3>' } namespace PR14489 { @@ -903,6 +903,105 @@ namespace ValueDecl { } } +namespace DependentDefault { + template <typename> struct Trait { + enum { V = 40 }; + typedef int Ty; + static int I; + }; + int other; + + template <typename T, int = Trait<T>::V > struct A {}; + template <typename T, typename = Trait<T>::Ty > struct B {}; + template <typename T, int& = Trait<T>::I > struct C {}; + + void test() { + + A<int> a1; + A<char> a2; + A<int, 10> a3; + a1 = a2; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'A<char, [...]>' to 'A<int, [...]>' + a3 = a1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'A<[...], (default) 40>' to 'A<[...], 10>' + a2 = a3; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'A<int, 10>' to 'A<char, 40>' + + B<int> b1; + B<char> b2; + B<int, char> b3; + b1 = b2; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'B<char, (default) Trait<T>::Ty>' to 'B<int, int>' + b3 = b1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'B<[...], (default) Trait<T>::Ty>' to 'B<[...], char>' + b2 = b3; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'B<int, char>' to 'B<char, int>' + + C<int> c1; + C<char> c2; + C<int, other> c3; + c1 = c2; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'C<char, (default) I>' to 'C<int, I>' + c3 = c1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'C<[...], (default) I>' to 'C<[...], other>' + c2 = c3; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'C<int, other>' to 'C<char, I>' + } +} + +namespace VariadicDefault { + int i1, i2, i3; + template <int = 5, int...> struct A {}; + template <int& = i1, int& ...> struct B {}; + template <typename = void, typename...> struct C {}; + + void test() { + A<> a1; + A<5, 6, 7> a2; + A<1, 2> a3; + a2 = a1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'A<[...], (no argument), (no argument)>' to 'A<[...], 6, 7>' + a3 = a1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'A<(default) 5, (no argument)>' to 'A<1, 2>' + + B<> b1; + B<i1, i2, i3> b2; + B<i2, i3> b3; + b2 = b1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'B<[...], (no argument), (no argument)>' to 'B<[...], i2, i3>' + b3 = b1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'B<(default) i1, (no argument)>' to 'B<i2, i3>' + + B<i1, i2, i3> b4 = b1; + // CHECK-ELIDE-NOTREE: no viable conversion from 'B<[...], (no argument), (no argument)>' to 'B<[...], i2, i3>' + B<i2, i3> b5 = b1; + // CHECK-ELIDE-NOTREE: no viable conversion from 'B<(default) i1, (no argument)>' to 'B<i2, i3>' + + C<> c1; + C<void, void> c2; + C<char, char> c3; + c2 = c1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'C<[...], (no argument)>' to 'C<[...], void>' + c3 = c1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'C<(default) void, (no argument)>' to 'C<char, char>' + } +} + // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated. diff --git a/test/Misc/diagnostic-crash.cpp b/test/Misc/diagnostic-crash.cpp new file mode 100644 index 0000000000..cbb9ac60dd --- /dev/null +++ b/test/Misc/diagnostic-crash.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -verify -fsyntax-only %s +// The diagnostics we produce for this code tickled a bug in raw_ostream. +template <typename _Alloc> class allocator; +template <class _CharT> struct char_traits; +template <typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > +class basic_string; +typedef basic_string<wchar_t> wstring; +class Closure { +}; +template <class A1> class Callback1 { +}; +template <class A1, class A2> class Callback2 { +}; +template <class R, class A2> class ResultCallback1 { +}; +template <bool del, class R, class T, class P1, class P2, class A1> +class AAAAAAAResultCallback_2_1 : public ResultCallback1<R, A1> { +}; +template <bool del, class T, class P1, class P2, class A1> +class AAAAAAAResultCallback_2_1< del, void, T, P1, P2, A1> : + public Callback1<A1> { + public: + typedef Callback1<A1> base; +}; +template <class T1, class T2, class R, class P1, class P2, class A1> +inline typename AAAAAAAResultCallback_2_1<true, R, T1, P1, P2, A1>::base* +NewCallback(T1* obj, R(T2::* member)(P1, P2, A1), const P1& p1, const P2& p2) {} +namespace util { class Status {}; } +class xxxxxxxxxxxxxxxxx { + void Bar(wstring* s, util::Status* status, + Callback2<util::Status, wstring>* done); + void Foo(); +}; +void xxxxxxxxxxxxxxxxx::Foo() { + wstring* s = __null; + util::Status* status = __null; + Closure* cb = NewCallback(this, &xxxxxxxxxxxxxxxxx::Bar, s, status); // expected-error{{cannot initialize}} +} diff --git a/test/Misc/warn-in-system-header.c b/test/Misc/warn-in-system-header.c index 6e0237d0dc..132f083af7 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/Misc/warning-flags.c b/test/Misc/warning-flags.c index 931de8365b..a6dc8f1352 100644 --- a/test/Misc/warning-flags.c +++ b/test/Misc/warning-flags.c @@ -18,7 +18,7 @@ This test serves two purposes: The list of warnings below should NEVER grow. It should gradually shrink to 0. -CHECK: Warnings without flags (144): +CHECK: Warnings without flags (143): CHECK-NEXT: ext_delete_void_ptr_operand CHECK-NEXT: ext_enum_friend CHECK-NEXT: ext_expected_semi_decl_list @@ -148,7 +148,6 @@ CHECK-NEXT: warn_related_result_type_compatibility_class CHECK-NEXT: warn_related_result_type_compatibility_protocol CHECK-NEXT: warn_second_parameter_of_va_start_not_last_named_argument CHECK-NEXT: warn_second_parameter_to_va_arg_never_compatible -CHECK-NEXT: warn_standalone_specifier CHECK-NEXT: warn_static_inline_explicit_inst_ignored CHECK-NEXT: warn_static_non_static CHECK-NEXT: warn_template_export_unsupported diff --git a/test/Modules/Inputs/Conflicts/conflict_a.h b/test/Modules/Inputs/Conflicts/conflict_a.h new file mode 100644 index 0000000000..c16b5f5ef2 --- /dev/null +++ b/test/Modules/Inputs/Conflicts/conflict_a.h @@ -0,0 +1 @@ +int conflict_a; diff --git a/test/Modules/Inputs/Conflicts/conflict_b.h b/test/Modules/Inputs/Conflicts/conflict_b.h new file mode 100644 index 0000000000..4baf16f88e --- /dev/null +++ b/test/Modules/Inputs/Conflicts/conflict_b.h @@ -0,0 +1 @@ +int conflict_b; diff --git a/test/Modules/Inputs/Conflicts/module.map b/test/Modules/Inputs/Conflicts/module.map new file mode 100644 index 0000000000..e6aafaccec --- /dev/null +++ b/test/Modules/Inputs/Conflicts/module.map @@ -0,0 +1,10 @@ +module Conflicts { + explicit module A { + header "conflict_a.h" + conflict B, "we just don't like B" + } + + module B { + header "conflict_b.h" + } +} diff --git a/test/Modules/Inputs/Modified/B.h b/test/Modules/Inputs/Modified/B.h index d1c8bb5e8e..52526b7f3a 100644 --- a/test/Modules/Inputs/Modified/B.h +++ b/test/Modules/Inputs/Modified/B.h @@ -1,2 +1,3 @@ -#include "A.h" +@import ModA; + int getB(); diff --git a/test/Modules/Inputs/Modified/module.map b/test/Modules/Inputs/Modified/module.map index d9aed01430..27b0d7062c 100644 --- a/test/Modules/Inputs/Modified/module.map +++ b/test/Modules/Inputs/Modified/module.map @@ -1,2 +1,5 @@ -module A { header "A.h" } -module B { header "B.h" } +module ModA { header "A.h" } +module ModB { + header "B.h" + export * +} diff --git a/test/Modules/Inputs/ModuleDiags/has_errors.h b/test/Modules/Inputs/ModuleDiags/has_errors.h new file mode 100644 index 0000000000..2c0929a6f5 --- /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 0000000000..87112be695 --- /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 0000000000..09b25088e6 --- /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/StdDef/module.map b/test/Modules/Inputs/StdDef/module.map new file mode 100644 index 0000000000..69c69eac35 --- /dev/null +++ b/test/Modules/Inputs/StdDef/module.map @@ -0,0 +1,11 @@ +module StdDef { + module SizeT { + header "size_t.h" + export * + } + + module Other { + header "other.h" + export * + } +} diff --git a/test/Modules/Inputs/StdDef/other.h b/test/Modules/Inputs/StdDef/other.h new file mode 100644 index 0000000000..f29f6366cc --- /dev/null +++ b/test/Modules/Inputs/StdDef/other.h @@ -0,0 +1,2 @@ +#include <stddef.h> + diff --git a/test/Modules/Inputs/StdDef/size_t.h b/test/Modules/Inputs/StdDef/size_t.h new file mode 100644 index 0000000000..9ac61c5e0d --- /dev/null +++ b/test/Modules/Inputs/StdDef/size_t.h @@ -0,0 +1,4 @@ +#ifndef _SIZE_T +#define _SIZE_T +typedef __SIZE_TYPE__ size_t; +#endif 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 0000000000..9a020d1bf5 --- /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 884b59c80c..9b2f3af2ba 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 0000000000..f6d4cca9f8 --- /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/Inputs/builtin.h b/test/Modules/Inputs/builtin.h new file mode 100644 index 0000000000..7be90177d1 --- /dev/null +++ b/test/Modules/Inputs/builtin.h @@ -0,0 +1,3 @@ +int i; +int *p = &i; + diff --git a/test/Modules/Inputs/builtin_sub.h b/test/Modules/Inputs/builtin_sub.h new file mode 100644 index 0000000000..79e3c03325 --- /dev/null +++ b/test/Modules/Inputs/builtin_sub.h @@ -0,0 +1,4 @@ +int getBos1(void) { + return __builtin_object_size(p, 0); +} + diff --git a/test/Modules/Inputs/config.h b/test/Modules/Inputs/config.h new file mode 100644 index 0000000000..f2dfda64c3 --- /dev/null +++ b/test/Modules/Inputs/config.h @@ -0,0 +1,7 @@ +#ifdef WANT_FOO +int* foo(); +#endif + +#ifdef WANT_BAR +char *bar(); +#endif diff --git a/test/Modules/Inputs/diag_pragma.h b/test/Modules/Inputs/diag_pragma.h new file mode 100644 index 0000000000..a8f958994c --- /dev/null +++ b/test/Modules/Inputs/diag_pragma.h @@ -0,0 +1,3 @@ +#define DIAG_PRAGMA_MACRO 1 + +#pragma clang diagnostic ignored "-Wparentheses" diff --git a/test/Modules/Inputs/linkage-merge-bar.h b/test/Modules/Inputs/linkage-merge-bar.h new file mode 100644 index 0000000000..cc528f7752 --- /dev/null +++ b/test/Modules/Inputs/linkage-merge-bar.h @@ -0,0 +1,3 @@ +#include <linkage-merge-foo.h> + +using ::g; diff --git a/test/Modules/Inputs/linkage-merge-foo.h b/test/Modules/Inputs/linkage-merge-foo.h new file mode 100644 index 0000000000..9cb62d2c0c --- /dev/null +++ b/test/Modules/Inputs/linkage-merge-foo.h @@ -0,0 +1,2 @@ +int f(); +static int g(int); diff --git a/test/Modules/Inputs/macros_left.h b/test/Modules/Inputs/macros_left.h index a8aac75a2f..076b0464e6 100644 --- a/test/Modules/Inputs/macros_left.h +++ b/test/Modules/Inputs/macros_left.h @@ -12,3 +12,5 @@ #define LEFT_RIGHT_DIFFERENT3 float #define LEFT_RIGHT_DIFFERENT float + +#define FN_ADD(a,b) (a+b) diff --git a/test/Modules/Inputs/macros_right.h b/test/Modules/Inputs/macros_right.h index 445f579cf6..dbbd2c3643 100644 --- a/test/Modules/Inputs/macros_right.h +++ b/test/Modules/Inputs/macros_right.h @@ -15,3 +15,5 @@ #undef TOP_RIGHT_REDEF #define TOP_RIGHT_REDEF float + +#define FN_ADD(x, y) (x+y) diff --git a/test/Modules/Inputs/macros_top.h b/test/Modules/Inputs/macros_top.h index 9c3f3c071f..dd303ffee4 100644 --- a/test/Modules/Inputs/macros_top.h +++ b/test/Modules/Inputs/macros_top.h @@ -8,8 +8,8 @@ - - +#define TOP_RIGHT_REDEF float +// The last definition will be exported from the sub-module. #define TOP_RIGHT_REDEF int #define TOP_RIGHT_UNDEF int diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map index 53f2fd65d3..d20521f9c7 100644 --- a/test/Modules/Inputs/module.map +++ b/test/Modules/Inputs/module.map @@ -183,3 +183,29 @@ module cxx_inline_namespace { module cxx_linkage_cache { header "cxx-linkage-cache.h" } + +module config { + header "config.h" + config_macros [exhaustive] WANT_FOO, WANT_BAR +} + +module diag_pragma { + header "diag_pragma.h" +} + +module builtin { + header "builtin.h" + explicit module sub { + header "builtin_sub.h" + } +} + +module linkage_merge { + explicit module foo { + header "linkage-merge-foo.h" + } + explicit module bar { + header "linkage-merge-bar.h" + } + +} diff --git a/test/Modules/Inputs/oldname/module.map b/test/Modules/Inputs/oldname/module.map new file mode 100644 index 0000000000..5812f869b3 --- /dev/null +++ b/test/Modules/Inputs/oldname/module.map @@ -0,0 +1,4 @@ +module NewName { + header "new_name.h" + export * +} diff --git a/test/Modules/Inputs/oldname/new_name.h b/test/Modules/Inputs/oldname/new_name.h new file mode 100644 index 0000000000..8bf2f1c8c3 --- /dev/null +++ b/test/Modules/Inputs/oldname/new_name.h @@ -0,0 +1 @@ +int same_api; diff --git a/test/Modules/auto-module-import.m b/test/Modules/auto-module-import.m index 4bd3c5279c..7351828182 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 7f75473cbb..4bf9d592a8 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/builtins.m b/test/Modules/builtins.m new file mode 100644 index 0000000000..40b4f9c743 --- /dev/null +++ b/test/Modules/builtins.m @@ -0,0 +1,16 @@ +@import builtin; + +int foo() { + return __builtin_object_size(p, 0); +} + +@import builtin.sub; + +int bar() { + return __builtin_object_size(p, 0); +} + + +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -I %S/Inputs %s -verify +// expected-no-diagnostics diff --git a/test/Modules/compiler_builtins.m b/test/Modules/compiler_builtins.m index 5ea7d795c7..4b8cb5bdc5 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/config_macros.m b/test/Modules/config_macros.m new file mode 100644 index 0000000000..200744d614 --- /dev/null +++ b/test/Modules/config_macros.m @@ -0,0 +1,28 @@ +@import config; + +int *test_foo() { + return foo(); +} + +char *test_bar() { + return bar(); // expected-warning{{implicit declaration of function 'bar' is invalid in C99}} \ + // expected-warning{{incompatible integer to pointer conversion}} +} + +#undef WANT_FOO // expected-note{{macro was #undef'd here}} +@import config; // expected-warning{{#undef of configuration macro 'WANT_FOO' has no effect on the import of 'config'; pass '-UWANT_FOO' on the command line to configure the module}} + +#define WANT_FOO 2 // expected-note{{macro was defined here}} +@import config; // expected-warning{{definition of configuration macro 'WANT_FOO' has no effect on the import of 'config'; pass '-DWANT_FOO=...' on the command line to configure the module}} + +#undef WANT_FOO +#define WANT_FOO 1 +@import config; // okay + +#define WANT_BAR 1 // expected-note{{macro was defined here}} +@import config; // expected-warning{{definition of configuration macro 'WANT_BAR' has no effect on the import of 'config'; pass '-DWANT_BAR=...' on the command line to configure the module}} + +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -DWANT_FOO=1 %s -verify + diff --git a/test/Modules/conflicts.m b/test/Modules/conflicts.m new file mode 100644 index 0000000000..2388e6f1d1 --- /dev/null +++ b/test/Modules/conflicts.m @@ -0,0 +1,7 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -I %S/Inputs/Conflicts %s -verify + +@import Conflicts; + +@import Conflicts.A; // expected-warning{{module 'Conflicts.A' conflicts with already-imported module 'Conflicts.B': we just don't like B}} + diff --git a/test/Modules/cstd.m b/test/Modules/cstd.m index 6d896a9155..3d1dcf38e3 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 4326e76a75..5f83092c95 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 7fb8a61386..7ed82b57e9 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 732c2a27e2..593f53b2c6 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/diag-pragma.c b/test/Modules/diag-pragma.c new file mode 100644 index 0000000000..7ec3400bba --- /dev/null +++ b/test/Modules/diag-pragma.c @@ -0,0 +1,13 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diag_pragma %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -x objective-c -verify -fmodules-cache-path=%t %s +// FIXME: When we have a syntax for modules in C, use that. + +@import diag_pragma; + +int foo(int x) { + if (x = DIAG_PRAGMA_MACRO) // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note {{place parentheses}} expected-note {{use '=='}} + return 0; + return 1; +} diff --git a/test/Modules/diamond-pch.c b/test/Modules/diamond-pch.c index 079f6afa9c..e7ad02dbe4 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 0bac1b7596..89d5bc0dda 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/driver.c b/test/Modules/driver.c index 0a787b996a..08fdaab441 100644 --- a/test/Modules/driver.c +++ b/test/Modules/driver.c @@ -1,6 +1,6 @@ // RUN: %clang -fmodules %s -### 2>&1 | FileCheck -check-prefix NO_MODULE_CACHE %s // RUN: %clang -fmodules -fmodules-cache-path=blarg %s -### 2>&1 | FileCheck -check-prefix WITH_MODULE_CACHE %s -// CHECK-NO_MODULE_CACHE: {{clang.*"-fmodules-cache-path=.*clang-module-cache"}} +// CHECK-NO_MODULE_CACHE: {{clang.*"-fmodules-cache-path=.*ModuleCache"}} // CHECK-WITH_MODULE_CACHE: {{clang.*"-fmodules-cache-path=blarg"}} diff --git a/test/Modules/linkage-merge.cpp b/test/Modules/linkage-merge.cpp new file mode 100644 index 0000000000..9cc9ae64bf --- /dev/null +++ b/test/Modules/linkage-merge.cpp @@ -0,0 +1,12 @@ +// 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@-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 16e2205078..e838ca1018 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 002b6d1556..efd88f47e3 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 abe95420d4..54c7491390 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 406e554a7a..433e03324b 100644 --- a/test/Modules/macros.c +++ b/test/Modules/macros.c @@ -1,4 +1,3 @@ -// XFAIL: * // RUN: rm -rf %t // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros_top %S/Inputs/module.map // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros_left %S/Inputs/module.map @@ -9,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}} -// expected-note{{other definition of 'LEFT_RIGHT_DIFFERENT'}} -// expected-note{{expanding this definition of 'TOP_RIGHT_REDEF'}} -// FIXME: expected-note{{previous definition is here}} \ -// expected-note{{expanding this definition of 'LEFT_RIGHT_DIFFERENT'}} - -// expected-note{{other 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; @@ -80,8 +79,8 @@ void f() { # error TOP should be visible #endif -#ifdef TOP_LEFT_UNDEF -# error TOP_LEFT_UNDEF should not be visible +#ifndef TOP_LEFT_UNDEF +# error TOP_LEFT_UNDEF should still be defined #endif void test1() { @@ -89,7 +88,8 @@ void test1() { TOP_RIGHT_REDEF *ip = &i; } -#define LEFT_RIGHT_DIFFERENT2 double // FIXME: expected-warning{{'LEFT_RIGHT_DIFFERENT2' macro redefined}} +#define LEFT_RIGHT_DIFFERENT2 double // FIXME: expected-warning{{'LEFT_RIGHT_DIFFERENT2' macro redefined}} \ + // expected-note{{other definition of 'LEFT_RIGHT_DIFFERENT2'}} // Import right module (which also imports top) @import macros_right; @@ -112,11 +112,11 @@ void test2() { int i; float f; double d; - TOP_RIGHT_REDEF *ip = &i; // expected-warning{{ambiguous expansion of macro 'TOP_RIGHT_REDEF'}} + TOP_RIGHT_REDEF *fp = &f; // expected-warning{{ambiguous expansion of macro 'TOP_RIGHT_REDEF'}} - LEFT_RIGHT_IDENTICAL *ip2 = &i; - LEFT_RIGHT_DIFFERENT *fp = &f; // expected-warning{{ambiguous expansion of macro 'LEFT_RIGHT_DIFFERENT'}} - LEFT_RIGHT_DIFFERENT2 *dp = &d; + LEFT_RIGHT_IDENTICAL *ip = &i; + LEFT_RIGHT_DIFFERENT *ip2 = &i; // expected-warning{{ambiguous expansion of macro 'LEFT_RIGHT_DIFFERENT'}} + LEFT_RIGHT_DIFFERENT2 *ip3 = &i; // expected-warning{{ambiguous expansion of macro 'LEFT_RIGHT_DIFFERENT2}} int LEFT_RIGHT_DIFFERENT3; } @@ -125,6 +125,7 @@ void test2() { void test3() { double d; LEFT_RIGHT_DIFFERENT *dp = &d; // okay + int x = FN_ADD(1,2); } #ifndef TOP_RIGHT_UNDEF @@ -133,6 +134,6 @@ void test3() { @import macros_right.undef; -#ifdef TOP_RIGHT_UNDEF -# error TOP_RIGHT_UNDEF should not be defined +#ifndef TOP_RIGHT_UNDEF +# error TOP_RIGHT_UNDEF should still be defined #endif diff --git a/test/Modules/method_pool.m b/test/Modules/method_pool.m index 9a8897b383..6fd74b0885 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/modify-module.m b/test/Modules/modify-module.m index 7433e6f7a2..953c917cdd 100644 --- a/test/Modules/modify-module.m +++ b/test/Modules/modify-module.m @@ -6,17 +6,22 @@ // RUN: cp %S/Inputs/Modified/A.h %t/include // RUN: cp %S/Inputs/Modified/B.h %t/include // RUN: cp %S/Inputs/Modified/module.map %t/include -// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify -// expected-no-diagnostics +// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify // RUN: echo '' >> %t/include/B.h -// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify +// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify // RUN: echo 'int getA(); int getA2();' > %t/include/A.h -// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify +// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify +// RUN: rm %t/cache/ModA.pcm +// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify +// RUN: touch %t/cache/ModA.pcm +// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify + +// expected-no-diagnostics // FIXME: It is intended to suppress this on win32. // REQUIRES: ansi-escape-sequences -@import B; +@import ModB; int getValue() { return getA() + getB(); } diff --git a/test/Modules/module-private.cpp b/test/Modules/module-private.cpp index d4e73b5396..438dcab984 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/module_file_info.m b/test/Modules/module_file_info.m new file mode 100644 index 0000000000..09319d60fe --- /dev/null +++ b/test/Modules/module_file_info.m @@ -0,0 +1,34 @@ + +@import DependsOnModule; + +// RUN: rm -rf %t +// RUN: %clang_cc1 -w -fmodules -fdisable-module-hash -fmodules-cache-path=%t -F %S/Inputs -DBLARG -DWIBBLE=WOBBLE %s +// RUN: %clang_cc1 -module-file-info %t/DependsOnModule.pcm | FileCheck %s + +// CHECK: Generated by this Clang: + +// CHECK: Language options: +// CHECK: C99: Yes +// CHECK: Objective-C 1: Yes +// CHECK: modules extension to C: Yes + +// CHECK: Target options: +// CHECK: Triple: +// CHECK: CPU: +// CHECK: ABI: +// CHECK: C++ ABI: +// CHECK: Linker version: + +// CHECK: Header search options: +// CHECK: System root [-isysroot=]: '/' +// CHECK: Use builtin include directories [-nobuiltininc]: Yes +// CHECK: Use standard system include directories [-nostdinc]: Yes +// CHECK: Use standard C++ include directories [-nostdinc++]: Yes +// CHECK: Use libc++ (rather than libstdc++) [-stdlib=]: + +// CHECK: Preprocessor options: +// CHECK: Uses compiler/target-specific predefines [-undef]: Yes +// CHECK: Uses detailed preprocessing record (for indexing): No +// CHECK: Predefined macros: +// CHECK: -DBLARG +// CHECK: -DWIBBLE=WOBBLE diff --git a/test/Modules/namespaces.cpp b/test/Modules/namespaces.cpp index 0e9dbffcbb..426e0025f9 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 423e808bca..8155318fb3 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 d3ebcb7527..81fb28bafb 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 31742f7e03..e958759420 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/prune.m b/test/Modules/prune.m new file mode 100644 index 0000000000..8af7e6c395 --- /dev/null +++ b/test/Modules/prune.m @@ -0,0 +1,46 @@ +// Test the automatic pruning of module cache entries. +#ifdef IMPORT_DEPENDS_ON_MODULE +@import DependsOnModule; +#else +@import Module; +#endif + +// We need 'touch' and 'find' for this test to work. +// REQUIRES: shell + +// Clear out the module cache +// RUN: rm -rf %t +// Run Clang twice so we end up creating the timestamp file (the second time). +// RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -F %S/Inputs -fmodules-cache-path=%t %s -verify +// RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -F %S/Inputs -fmodules-cache-path=%t %s -verify +// RUN: ls %t | grep modules.timestamp +// RUN: ls -R %t | grep ^Module.pcm +// RUN: ls -R %t | grep DependsOnModule.pcm + +// Set the timestamp back more than two days. We should try to prune, +// but nothing gets pruned because the module files are new enough. +// RUN: touch -m -a -t 201101010000 %t/modules.timestamp +// RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify +// RUN: ls %t | grep modules.timestamp +// RUN: ls -R %t | grep ^Module.pcm +// RUN: ls -R %t | grep DependsOnModule.pcm + +// Set the DependsOnModule access time back more than four days. +// This shouldn't prune anything, because the timestamp has been updated, so +// the pruning mechanism won't fire. +// RUN: find %t -name DependsOnModule.pcm | xargs touch -a -t 201101010000 +// RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify +// RUN: ls %t | grep modules.timestamp +// RUN: ls -R %t | grep ^Module.pcm +// RUN: ls -R %t | grep DependsOnModule.pcm + +// Set both timestamp and DependsOnModule.pcm back beyond the cutoff. +// This should trigger pruning, which will remove DependsOnModule but not Module. +// RUN: touch -m -a -t 201101010000 %t/modules.timestamp +// RUN: find %t -name DependsOnModule.pcm | xargs touch -a -t 201101010000 +// RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify +// RUN: ls %t | grep modules.timestamp +// RUN: ls -R %t | grep ^Module.pcm +// RUN: ls -R %t | not grep DependsOnModule.pcm + +// expected-no-diagnostics diff --git a/test/Modules/redecl-merge.m b/test/Modules/redecl-merge.m index e37366748d..37e5967f4e 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 0000000000..1647f86606 --- /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 0000000000..d41573ddc7 --- /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 0000000000..9ec02b03f2 --- /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 0000000000..a36568207b --- /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/renamed.m b/test/Modules/renamed.m new file mode 100644 index 0000000000..4e8f5329bb --- /dev/null +++ b/test/Modules/renamed.m @@ -0,0 +1,8 @@ +@import NewName; + +int f() { return same_api; } + +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -I %S/Inputs -fmodules-cache-path=%t %s -verify + +// expected-no-diagnostics diff --git a/test/Modules/serialized-diags.m b/test/Modules/serialized-diags.m new file mode 100644 index 0000000000..18bce06047 --- /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/stddef.m b/test/Modules/stddef.m new file mode 100644 index 0000000000..83f73f9d33 --- /dev/null +++ b/test/Modules/stddef.m @@ -0,0 +1,7 @@ +@import StdDef.Other; + +size_t getSize(); + +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/StdDef %s -verify +// expected-no-diagnostics diff --git a/test/Modules/subframeworks.m b/test/Modules/subframeworks.m index 22dfcca365..ad70cc2b22 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 0000000000..85b3263f72 --- /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/OpenMP/no_option.c b/test/OpenMP/no_option.c new file mode 100644 index 0000000000..4acc8d0656 --- /dev/null +++ b/test/OpenMP/no_option.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -verify -o - %s +// expected-no-diagnostics + +int a; +#pragma omp threadprivate(a,b) +#pragma omp parallel diff --git a/test/OpenMP/no_option_no_warn.c b/test/OpenMP/no_option_no_warn.c new file mode 100644 index 0000000000..c989991371 --- /dev/null +++ b/test/OpenMP/no_option_no_warn.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -verify -Wno-source-uses-openmp -o - %s +// expected-no-diagnostics + +int a; +#pragma omp threadprivate(a,b) +#pragma omp parallel diff --git a/test/OpenMP/openmp_common.c b/test/OpenMP/openmp_common.c new file mode 100644 index 0000000000..ca5d89a662 --- /dev/null +++ b/test/OpenMP/openmp_common.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +#pragma omp // expected-error {{expected an OpenMP directive}} +#pragma omp unknown_directive // expected-error {{expected an OpenMP directive}} + +void foo() { +#pragma omp // expected-error {{expected an OpenMP directive}} +#pragma omp unknown_directive // expected-error {{expected an OpenMP directive}} +} diff --git a/test/OpenMP/option_warn.c b/test/OpenMP/option_warn.c new file mode 100644 index 0000000000..ddec8e113e --- /dev/null +++ b/test/OpenMP/option_warn.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -verify -Wsource-uses-openmp -o - %s + +int a; +#pragma omp threadprivate(a,b) // expected-warning {{unexpected '#pragma omp ...' in program}} +#pragma omp parallel diff --git a/test/OpenMP/predefined_macro.c b/test/OpenMP/predefined_macro.c index e18c3d26d4..cf6c0cc611 100644 --- a/test/OpenMP/predefined_macro.c +++ b/test/OpenMP/predefined_macro.c @@ -15,3 +15,20 @@ #endif // _OPENMP #endif // FOPENMP +// RUN: %clang_cc1 -fopenmp -verify -DFOPENMP -o - %s +// RUN: %clang_cc1 -verify -o - %s +// expected-no-diagnostics +#ifdef FOPENMP +// -fopenmp option is specified +#ifndef _OPENMP +#error "No _OPENMP macro is defined with -fopenmp option" +#elsif _OPENMP != 201107 +#error "_OPENMP has incorrect value" +#endif // _OPENMP +#else +// No -fopenmp option is specified +#ifdef _OPENMP +#error "_OPENMP macro is defined without -fopenmp option" +#endif // _OPENMP +#endif // FOPENMP + diff --git a/test/OpenMP/threadprivate_ast_print.cpp b/test/OpenMP/threadprivate_ast_print.cpp new file mode 100644 index 0000000000..deb829e926 --- /dev/null +++ b/test/OpenMP/threadprivate_ast_print.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// expected-no-diagnostics + +struct St{ + int a; +}; + +struct St1{ + int a; + static int b; +// CHECK: static int b; +#pragma omp threadprivate(b) +// CHECK-NEXT: #pragma omp threadprivate(b) +} d; + +int a, b; +// CHECK: int a; +// CHECK: int b; +#pragma omp threadprivate(a) +// CHECK-NEXT: #pragma omp threadprivate(a) +#pragma omp threadprivate(d, b) +// CHECK-NEXT: #pragma omp threadprivate(d,b) + +template <class T> T foo() { + static T v; + #pragma omp threadprivate(v) + return v; +} +//CHECK: template <class T = int> int foo() { +//CHECK-NEXT: static int v; +//CHECK-NEXT: #pragma omp threadprivate(v) +//CHECK: template <class T> T foo() { +//CHECK-NEXT: static T v; +//CHECK-NEXT: #pragma omp threadprivate(v) + +int main () { + static int a; +// CHECK: static int a; +#pragma omp threadprivate(a) +// CHECK-NEXT: #pragma omp threadprivate(a) + a=2; + return (foo<int>()); +} diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp new file mode 100644 index 0000000000..0c448b2ef2 --- /dev/null +++ b/test/OpenMP/threadprivate_messages.cpp @@ -0,0 +1,119 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 %s + +#pragma omp threadprivate // expected-error {{expected '(' after 'threadprivate'}} +#pragma omp threadprivate( // expected-error {{expected unqualified-id}} +#pragma omp threadprivate() // expected-error {{expected unqualified-id}} +#pragma omp threadprivate(1) // expected-error {{expected unqualified-id}} +struct CompleteSt{ + int a; +}; + +struct CompleteSt1{ +#pragma omp threadprivate(1) // expected-error {{expected unqualified-id}} + int a; +} d; // expected-note {{forward declaration of 'd'}} + +int a; // expected-note {{forward declaration of 'a'}} + +#pragma omp threadprivate(a) +#pragma omp threadprivate(u) // expected-error {{use of undeclared identifier 'u'}} +#pragma omp threadprivate(d, a) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} +int foo() { // expected-note {{declared here}} + static int l; +#pragma omp threadprivate(l)) // expected-warning {{extra tokens at end of '#pragma omp threadprivate' are ignored}} + return (a); +} + +#pragma omp threadprivate a // expected-error {{expected '(' after 'threadprivate'}} +#pragma omp threadprivate(d // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{'#pragma omp threadprivate' must precede all references to variable 'd'}} +#pragma omp threadprivate(d)) +int x, y; +#pragma omp threadprivate(x)) // expected-warning {{extra tokens at end of '#pragma omp threadprivate' are ignored}} +#pragma omp threadprivate(y)), // expected-warning {{extra tokens at end of '#pragma omp threadprivate' are ignored}} +#pragma omp threadprivate(a,d) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-error {{'#pragma omp threadprivate' must precede all references to variable 'd'}} +#pragma omp threadprivate(d.a) // expected-error {{expected unqualified-id}} +#pragma omp threadprivate((float)a) // expected-error {{expected unqualified-id}} +int foa; +#pragma omp threadprivate(faa) // expected-error {{use of undeclared identifier 'faa'; did you mean 'foa'?}} +#pragma omp threadprivate(foo) // expected-error {{'foo' is not a global variable, static local variable or static data member}} +#pragma omp threadprivate (int a=2) // expected-error {{expected unqualified-id}} + +struct IncompleteSt; // expected-note {{forward declaration of 'IncompleteSt'}} + +extern IncompleteSt e; +#pragma omp threadprivate (e) // expected-error {{a threadprivate variable must not have incomplete type 'IncompleteSt'}} + +int &f = a; // expected-note {{forward declaration of 'f'}} +#pragma omp threadprivate (f) // expected-error {{arguments of '#pragma omp threadprivate' cannot be of reference type 'int &'}} + +class Class { + private: + int a; // expected-note {{declared here}} + static int b; + Class() : a(0){} + public: + Class (int aaa) : a(aaa) {} +#pragma omp threadprivate (b, a) // expected-error {{'a' is not a global variable, static local variable or static data member}} +} g(10); +#pragma omp threadprivate (b) // expected-error {{use of undeclared identifier 'b'}} +#pragma omp threadprivate (Class::b) // expected-error {{expected unqualified-id}} +#pragma omp threadprivate (g) + +namespace ns { + int m; +#pragma omp threadprivate (m) +} +#pragma omp threadprivate (m) // expected-error {{use of undeclared identifier 'm'}} +#pragma omp threadprivate (ns::m) // expected-error {{expected unqualified-id}} +#pragma omp threadprivate (ns:m) // expected-error {{expected unqualified-id}} + +const int h = 12; +const volatile int i = 10; +#pragma omp threadprivate (h, i) + + +template <class T> +class TempClass { + private: + T a; + TempClass() : a(){} + public: + TempClass (T aaa) : a(aaa) {} + static T s; +#pragma omp threadprivate (s) +}; +#pragma omp threadprivate (s) // expected-error {{use of undeclared identifier 's'}} + +static __thread int t; // expected-note {{forward declaration of 't'}} +#pragma omp threadprivate (t) // expected-error {{variable 't' cannot be threadprivate because it is thread-local}} + +int o; // expected-note {{candidate found by name lookup is 'o'}} +namespace { +int o; // expected-note {{candidate found by name lookup is '<anonymous namespace>::o'}} +} +#pragma omp threadprivate (o) // expected-error {{reference to 'o' is ambiguous}} + +int main(int argc, char **argv) { // expected-note {{forward declaration of 'argc'}} + + int x, y = argc; // expected-note {{forward declaration of 'y'}} + static double d1; + static double d2; + static double d3; // expected-note {{forward declaration of 'd3'}} + + d.a = a; + d2++; + ; +#pragma omp threadprivate(argc+y) // expected-error {{expected unqualified-id}} +#pragma omp threadprivate(argc,y) // expected-error 2 {{arguments of '#pragma omp threadprivate' must have static storage duration}} +#pragma omp threadprivate(d2) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'd2'}} +#pragma omp threadprivate(d1) + { + ++a;d2=0; +#pragma omp threadprivate(d3) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'd3' variable declaration}} + } +#pragma omp threadprivate(d3) + +#pragma omp threadprivate(a) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'a' variable declaration}} + return (y); +#pragma omp threadprivate(d) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'd' variable declaration}} +} diff --git a/test/PCH/captured-stmt.cpp b/test/PCH/captured-stmt.cpp new file mode 100644 index 0000000000..6f5ca3836e --- /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/chain-late-anonymous-namespace.cpp b/test/PCH/chain-late-anonymous-namespace.cpp index 87205c631b..edae285c90 100644 --- a/test/PCH/chain-late-anonymous-namespace.cpp +++ b/test/PCH/chain-late-anonymous-namespace.cpp @@ -2,6 +2,8 @@ // RUN: %clang_cc1 -include %s -include %s -fsyntax-only %s // with PCH // RUN: %clang_cc1 -chain-include %s -chain-include %s -fsyntax-only %s +// with PCH, with modules enabled +// RUN: %clang_cc1 -chain-include %s -chain-include %s -fsyntax-only -fmodules %s #if !defined(PASS1) #define PASS1 diff --git a/test/PCH/cxx-constexpr.cpp b/test/PCH/cxx-constexpr.cpp index 8fe48f7377..13f04a7947 100644 --- a/test/PCH/cxx-constexpr.cpp +++ b/test/PCH/cxx-constexpr.cpp @@ -4,6 +4,9 @@ // RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t-cxx11 // RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t-cxx11 -verify %s +// RUN: %clang_cc1 -pedantic-errors -std=c++98 -emit-pch %s -o %t -fmodules +// RUN: %clang_cc1 -pedantic-errors -std=c++98 -include-pch %t -verify %s -fmodules + #ifndef HEADER_INCLUDED #define HEADER_INCLUDED diff --git a/test/PCH/cxx-templates.cpp b/test/PCH/cxx-templates.cpp index ddebae4df2..58c4c177fd 100644 --- a/test/PCH/cxx-templates.cpp +++ b/test/PCH/cxx-templates.cpp @@ -5,7 +5,7 @@ // Test with pch. // RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h // RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t -verify %s -ast-dump -o - -// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize | FileCheck %s // expected-no-diagnostics diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h index 3dda059026..e672b0b387 100644 --- a/test/PCH/cxx-templates.h +++ b/test/PCH/cxx-templates.h @@ -246,3 +246,26 @@ struct __mt_alloc { } }; } + +namespace PR13020 { +template<typename T> +void f() { + enum E { + enumerator + }; + + T t = enumerator; +} + +template void f<int>(); +} + +template<typename T> void doNotDeserialize() {} +template<typename T> struct ContainsDoNotDeserialize { + static int doNotDeserialize; +}; +template<typename T> struct ContainsDoNotDeserialize2 { + static void doNotDeserialize(); +}; +template<typename T> int ContainsDoNotDeserialize<T>::doNotDeserialize = 0; +template<typename T> void ContainsDoNotDeserialize2<T>::doNotDeserialize() {} diff --git a/test/PCH/cxx-typeid.cpp b/test/PCH/cxx-typeid.cpp index d1e0f9ded7..534863af21 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 aa3b16aa0b..f10f4de87c 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 2ca7dad0dd..2cab1f031a 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 3bb7b40aa9..722ca6e9ff 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 0000000000..a1c9339cb6 --- /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 0000000000..5a68f27045 --- /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 35e3921058..fa2ba8d29c 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 8ca0c361c4..4b24ac6b40 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 20010fbd1c..139f8ba4a6 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 49392ca2fe..092e2c9d9b 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 4c426e4f77..8dabb8b03d 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 0072818a1a..42882307dc 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 0000000000..f65c12af09 --- /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 f8161d17df..6ab66c2cab 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 c6f0275bc2..876b9438d1 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 4c6f4f891d..35c63d4b55 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 fd38dca194..d8a597a8cc 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/asm.c b/test/Parser/asm.c index 23052c389e..b95e08bcca 100644 --- a/test/Parser/asm.c +++ b/test/Parser/asm.c @@ -8,6 +8,12 @@ void f1() { void f2() { asm("foo" : "=r" (a)); // expected-error {{use of undeclared identifier 'a'}} asm("foo" : : "r" (b)); // expected-error {{use of undeclared identifier 'b'}} + + asm const (""); // expected-warning {{ignored const qualifier on asm}} + asm volatile (""); + asm restrict (""); // expected-warning {{ignored restrict qualifier on asm}} + // FIXME: Once GCC supports _Atomic, check whether it allows this. + asm _Atomic (""); // expected-warning {{ignored _Atomic qualifier on asm}} } diff --git a/test/Parser/atomic.c b/test/Parser/atomic.c new file mode 100644 index 0000000000..432deeb59c --- /dev/null +++ b/test/Parser/atomic.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -std=c11 %s -fsyntax-only -verify -pedantic + +typedef _Atomic(int) atomic_int; +typedef _Atomic int atomic_int; +typedef _Atomic _Atomic _Atomic(int) atomic_int; // expected-warning {{duplicate '_Atomic' declaration specifier}} + +typedef const int const_int; + +typedef const atomic_int const_atomic_int; +typedef _Atomic const int const_atomic_int; +typedef const _Atomic int const_atomic_int; +typedef const _Atomic(int) const_atomic_int; +typedef const _Atomic(_Atomic int) const_atomic_int; // expected-error {{_Atomic cannot be applied to atomic type '_Atomic(int)'}} +typedef _Atomic const_int const_atomic_int; +typedef _Atomic(const_int) const_atomic_int; // expected-error {{_Atomic cannot be applied to qualified type 'const_int' (aka 'const int')}} + +typedef int *_Atomic atomic_int_ptr; +typedef _Atomic(int *) atomic_int_ptr; +typedef int (*_Atomic atomic_int_ptr); + +typedef int _Atomic *int_atomic_ptr; +typedef _Atomic(int) *int_atomic_ptr; + +typedef int int_fn(); +typedef _Atomic int_fn atomic_int_fn; // expected-error {{_Atomic cannot be applied to function type 'int_fn' (aka 'int ()')}} +typedef _Atomic int atomic_int_array[3]; +typedef _Atomic atomic_int_array atomic_int_atomic_array; // expected-error {{_Atomic cannot be applied to array type 'atomic_int_array' (aka '_Atomic(int) [3]')}} + +_Atomic struct S { int n; }; // expected-warning {{'_Atomic' ignored on this declaration}} + +typedef _Atomic int __attribute__((address_space(1))) atomic_addr_space_int; +typedef _Atomic(int) __attribute__((address_space(1))) atomic_addr_space_int; + +typedef _Atomic int __attribute__((vector_size(16))) atomic_vector_int; +typedef _Atomic(int __attribute__((vector_size(16)))) atomic_vector_int; diff --git a/test/Parser/attributes.mm b/test/Parser/attributes.mm new file mode 100644 index 0000000000..d92e3d35cf --- /dev/null +++ b/test/Parser/attributes.mm @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -Wno-objc-root-class %s + +__attribute__((deprecated)) @class B; // expected-error {{prefix attribute must be followed by an interface or protocol}} + +__attribute__((deprecated)) @interface A @end +__attribute__((deprecated)) @protocol P0; +__attribute__((deprecated)) @protocol P1 +@end + +#define EXP __attribute__((visibility("default"))) +class EXP C {}; +EXP class C2 {}; // expected-warning {{attribute 'visibility' is ignored, place it after "class" to apply attribute to type declaration}} + +@interface EXP I @end // expected-error {{postfix attributes are not allowed on Objective-C directives, place them in front of '@interface'}} +EXP @interface I2 @end + +@implementation EXP I @end // expected-error-re {{postfix attributes are not allowed on Objective-C directives$}} +// FIXME: Prefix attribute recovery skips until ';' +EXP @implementation I2 @end; // expected-error {{prefix attribute must be followed by an interface or protocol}} + +@class EXP OC; // expected-error-re {{postfix attributes are not allowed on Objective-C directives$}} +EXP @class OC2; // expected-error {{prefix attribute must be followed by an interface or protocol}} + +@protocol EXP P @end // expected-error {{postfix attributes are not allowed on Objective-C directives, place them in front of '@protocol'}} +EXP @protocol P2 @end diff --git a/test/Parser/c11-noreturn.c b/test/Parser/c11-noreturn.c index 7a2fe50f88..e61901dfb7 100644 --- a/test/Parser/c11-noreturn.c +++ b/test/Parser/c11-noreturn.c @@ -4,11 +4,15 @@ _Noreturn int f(); int _Noreturn f(); // expected-note {{previous}} int f _Noreturn(); // expected-error {{expected ';'}} expected-error 2{{}} -int f() _Noreturn; // expected-error {{expected ';'}} expected-warning {{does not declare anything}} +int f() _Noreturn; // expected-error {{expected ';'}} expected-warning {{does not declare anything}} expected-error {{'_Noreturn' can only appear on functions}} _Noreturn char c1; // expected-error {{'_Noreturn' can only appear on functions}} char _Noreturn c2; // expected-error {{'_Noreturn' can only appear on functions}} typedef _Noreturn int g(); // expected-error {{'_Noreturn' can only appear on functions}} +_Noreturn int; // expected-error {{'_Noreturn' can only appear on functions}} expected-warning {{does not declare anything}} +_Noreturn struct S; // expected-error {{'_Noreturn' can only appear on functions}} +_Noreturn enum E { e }; // expected-error {{'_Noreturn' can only appear on functions}} + // CHECK-EXT: _Noreturn functions are a C11-specific feature diff --git a/test/Parser/captured-statements.c b/test/Parser/captured-statements.c new file mode 100644 index 0000000000..30dddb549c --- /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/crash-report.c b/test/Parser/crash-report.c new file mode 100644 index 0000000000..42481aa7d0 --- /dev/null +++ b/test/Parser/crash-report.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s 2>&1 | FileCheck %s +// REQUIRES: crash-recovery + +#prag\ +ma clang __debug crash + +// CHECK: prag\ +// CHECK-NEXT: ma + diff --git a/test/Parser/cxx-class.cpp b/test/Parser/cxx-class.cpp index 8ed5882a28..5fac797285 100644 --- a/test/Parser/cxx-class.cpp +++ b/test/Parser/cxx-class.cpp @@ -88,6 +88,17 @@ namespace ctor_error { // expected-error{{unknown type name 'UnknownType'}} } +namespace nns_decl { + struct A { + struct B; + }; + namespace N { + union C; + } + struct A::B; // expected-error {{forward declaration of struct cannot have a nested name specifier}} + union N::C; // expected-error {{forward declaration of union cannot have a nested name specifier}} +} + // PR13775: Don't assert here. namespace PR13775 { class bar diff --git a/test/Parser/cxx0x-ambig.cpp b/test/Parser/cxx0x-ambig.cpp index dac3c099fc..4c22ed3a9b 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 { @@ -133,3 +133,19 @@ namespace ellipsis { void l(int(S<int>::*...)(T)); // expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}} }; } + +namespace braced_init_list { + struct X { + void foo() {} + }; + + void (*pf1)() {}; + void (X::*pmf1)() {&X::foo}; + void (X::*pmf2)() = {&X::foo}; + + void test() { + void (*pf2)() {}; + void (X::*pmf3)() {&X::foo}; + void (X::*pmf4)() = {&X::foo}; + } +} diff --git a/test/Parser/cxx0x-decl.cpp b/test/Parser/cxx0x-decl.cpp index b9441fd681..e6cba726ab 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/missing-closing-rbrace.m b/test/Parser/missing-closing-rbrace.m new file mode 100644 index 0000000000..d811421e48 --- /dev/null +++ b/test/Parser/missing-closing-rbrace.m @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar: //6854840 +@interface A {@end // expected-error {{'@end' appears where closing brace '}' is expected}} diff --git a/test/Parser/objc-boxing.m b/test/Parser/objc-boxing.m index a16a137b8f..a6bb0243cf 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 0000000000..444fb5dab4 --- /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 0000000000..96f19fe6a5 --- /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 7844e71080..d168a2751a 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 84778cd501..172a332510 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/Parser/prefix-attributes.m b/test/Parser/prefix-attributes.m deleted file mode 100644 index 399421fd72..0000000000 --- a/test/Parser/prefix-attributes.m +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %clang_cc1 -verify -fsyntax-only %s - -__attribute__((deprecated)) @class B; // expected-error {{prefix attribute must be followed by an interface or protocol}} - -__attribute__((deprecated)) @interface A @end -__attribute__((deprecated)) @protocol P0; -__attribute__((deprecated)) @protocol P1 -@end diff --git a/test/Preprocessor/aarch64-target-features.c b/test/Preprocessor/aarch64-target-features.c index 65104e3311..8bb8427c0d 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 0ae9afd7ee..5152977ba2 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 7877df3f78..fb49638040 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/has_include.c b/test/Preprocessor/has_include.c index 7cc67fac03..131e51919f 100644 --- a/test/Preprocessor/has_include.c +++ b/test/Preprocessor/has_include.c @@ -176,3 +176,12 @@ __has_include #else #error "__has_include failed (9)." #endif + +#if FOO +#elif __has_include(<foo>) +#endif + +// PR15539 +#ifdef FOO +#elif __has_include(<foo>) +#endif diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c index 73a3a7353e..9671f7e232 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 @@ -248,6 +280,7 @@ // ARM:#define __SIZEOF_SIZE_T__ 4 // ARM:#define __SIZEOF_WCHAR_T__ 4 // ARM:#define __SIZEOF_WINT_T__ 4 +// ARM:#define __SIZE_MAX__ 4294967295U // ARM:#define __SIZE_TYPE__ unsigned int // ARM:#define __SIZE_WIDTH__ 32 // ARM:#define __THUMB_INTERWORK__ 1 @@ -351,6 +384,7 @@ // ARMEABISOFTFP:#define __SIZEOF_SIZE_T__ 4 // ARMEABISOFTFP:#define __SIZEOF_WCHAR_T__ 4 // ARMEABISOFTFP:#define __SIZEOF_WINT_T__ 4 +// ARMEABISOFTFP:#define __SIZE_MAX__ 4294967295U // ARMEABISOFTFP:#define __SIZE_TYPE__ unsigned int // ARMEABISOFTFP:#define __SIZE_WIDTH__ 32 // ARMEABISOFTFP:#define __SOFTFP__ 1 @@ -455,6 +489,7 @@ // ARMEABIHARDFP:#define __SIZEOF_SIZE_T__ 4 // ARMEABIHARDFP:#define __SIZEOF_WCHAR_T__ 4 // ARMEABIHARDFP:#define __SIZEOF_WINT_T__ 4 +// ARMEABIHARDFP:#define __SIZE_MAX__ 4294967295U // ARMEABIHARDFP:#define __SIZE_TYPE__ unsigned int // ARMEABIHARDFP:#define __SIZE_WIDTH__ 32 // ARMEABIHARDFP-NOT:#define __SOFTFP__ 1 @@ -554,6 +589,7 @@ // I386:#define __SIZEOF_SIZE_T__ 4 // I386:#define __SIZEOF_WCHAR_T__ 4 // I386:#define __SIZEOF_WINT_T__ 4 +// I386:#define __SIZE_MAX__ 4294967295U // I386:#define __SIZE_TYPE__ unsigned int // I386:#define __SIZE_WIDTH__ 32 // I386:#define __UINTMAX_TYPE__ long long unsigned int @@ -651,6 +687,7 @@ // I386-LINUX:#define __SIZEOF_SIZE_T__ 4 // I386-LINUX:#define __SIZEOF_WCHAR_T__ 4 // I386-LINUX:#define __SIZEOF_WINT_T__ 4 +// I386-LINUX:#define __SIZE_MAX__ 4294967295U // I386-LINUX:#define __SIZE_TYPE__ unsigned int // I386-LINUX:#define __SIZE_WIDTH__ 32 // I386-LINUX:#define __UINTMAX_TYPE__ long long unsigned int @@ -759,6 +796,7 @@ // MIPS32BE:#define __SIZEOF_SIZE_T__ 4 // MIPS32BE:#define __SIZEOF_WCHAR_T__ 4 // MIPS32BE:#define __SIZEOF_WINT_T__ 4 +// MIPS32BE:#define __SIZE_MAX__ 4294967295U // MIPS32BE:#define __SIZE_TYPE__ unsigned int // MIPS32BE:#define __SIZE_WIDTH__ 32 // MIPS32BE:#define __STDC_HOSTED__ 0 @@ -875,6 +913,7 @@ // MIPS32EL:#define __SIZEOF_SIZE_T__ 4 // MIPS32EL:#define __SIZEOF_WCHAR_T__ 4 // MIPS32EL:#define __SIZEOF_WINT_T__ 4 +// MIPS32EL:#define __SIZE_MAX__ 4294967295U // MIPS32EL:#define __SIZE_TYPE__ unsigned int // MIPS32EL:#define __SIZE_WIDTH__ 32 // MIPS32EL:#define __UINTMAX_TYPE__ long long unsigned int @@ -988,6 +1027,7 @@ // MIPS64BE:#define __SIZEOF_SIZE_T__ 8 // MIPS64BE:#define __SIZEOF_WCHAR_T__ 4 // MIPS64BE:#define __SIZEOF_WINT_T__ 4 +// MIPS64BE:#define __SIZE_MAX__ 18446744073709551615UL // MIPS64BE:#define __SIZE_TYPE__ long unsigned int // MIPS64BE:#define __SIZE_WIDTH__ 64 // MIPS64BE:#define __UINTMAX_TYPE__ long long unsigned int @@ -1103,6 +1143,7 @@ // MIPS64EL:#define __SIZEOF_SIZE_T__ 8 // MIPS64EL:#define __SIZEOF_WCHAR_T__ 4 // MIPS64EL:#define __SIZEOF_WINT_T__ 4 +// MIPS64EL:#define __SIZE_MAX__ 18446744073709551615UL // MIPS64EL:#define __SIZE_TYPE__ long unsigned int // MIPS64EL:#define __SIZE_WIDTH__ 64 // MIPS64EL:#define __UINTMAX_TYPE__ long long unsigned int @@ -1141,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 \ @@ -1153,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 @@ -1249,6 +1306,7 @@ // MSP430:#define __SIZEOF_SIZE_T__ 2 // MSP430:#define __SIZEOF_WCHAR_T__ 2 // MSP430:#define __SIZEOF_WINT_T__ 2 +// MSP430:#define __SIZE_MAX__ 65535U // MSP430:#define __SIZE_TYPE__ unsigned int // MSP430:#define __SIZE_WIDTH__ 16 // MSP430:#define __UINTMAX_TYPE__ long unsigned int @@ -1346,6 +1404,7 @@ // NVPTX32:#define __SIZEOF_SIZE_T__ 4 // NVPTX32:#define __SIZEOF_WCHAR_T__ 4 // NVPTX32:#define __SIZEOF_WINT_T__ 4 +// NVPTX32:#define __SIZE_MAX__ 4294967295U // NVPTX32:#define __SIZE_TYPE__ unsigned int // NVPTX32:#define __SIZE_WIDTH__ 32 // NVPTX32:#define __UINTMAX_TYPE__ long long unsigned int @@ -1442,6 +1501,7 @@ // NVPTX64:#define __SIZEOF_SIZE_T__ 8 // NVPTX64:#define __SIZEOF_WCHAR_T__ 4 // NVPTX64:#define __SIZEOF_WINT_T__ 4 +// NVPTX64:#define __SIZE_MAX__ 18446744073709551615UL // NVPTX64:#define __SIZE_TYPE__ long long unsigned int // NVPTX64:#define __SIZE_WIDTH__ 64 // NVPTX64:#define __UINTMAX_TYPE__ long long unsigned int @@ -1543,6 +1603,7 @@ // PPC603E:#define __SIZEOF_SIZE_T__ 4 // PPC603E:#define __SIZEOF_WCHAR_T__ 4 // PPC603E:#define __SIZEOF_WINT_T__ 4 +// PPC603E:#define __SIZE_MAX__ 4294967295U // PPC603E:#define __SIZE_TYPE__ long unsigned int // PPC603E:#define __SIZE_WIDTH__ 32 // PPC603E:#define __UINTMAX_TYPE__ long long unsigned int @@ -1651,6 +1712,7 @@ // PPC64:#define __SIZEOF_SIZE_T__ 8 // PPC64:#define __SIZEOF_WCHAR_T__ 4 // PPC64:#define __SIZEOF_WINT_T__ 4 +// PPC64:#define __SIZE_MAX__ 18446744073709551615UL // PPC64:#define __SIZE_TYPE__ long unsigned int // PPC64:#define __SIZE_WIDTH__ 64 // PPC64:#define __UINTMAX_TYPE__ long unsigned int @@ -1913,6 +1975,7 @@ // PPC64-LINUX:#define __SIZEOF_SIZE_T__ 8 // PPC64-LINUX:#define __SIZEOF_WCHAR_T__ 4 // PPC64-LINUX:#define __SIZEOF_WINT_T__ 4 +// PPC64-LINUX:#define __SIZE_MAX__ 18446744073709551615UL // PPC64-LINUX:#define __SIZE_TYPE__ long unsigned int // PPC64-LINUX:#define __SIZE_WIDTH__ 64 // PPC64-LINUX:#define __UINTMAX_TYPE__ long unsigned int @@ -2017,6 +2080,7 @@ // PPC:#define __SIZEOF_SIZE_T__ 4 // PPC:#define __SIZEOF_WCHAR_T__ 4 // PPC:#define __SIZEOF_WINT_T__ 4 +// PPC:#define __SIZE_MAX__ 4294967295U // PPC:#define __SIZE_TYPE__ long unsigned int // PPC:#define __SIZE_WIDTH__ 32 // PPC:#define __UINTMAX_TYPE__ long long unsigned int @@ -2117,6 +2181,7 @@ // PPC-LINUX:#define __SIZEOF_SIZE_T__ 4 // PPC-LINUX:#define __SIZEOF_WCHAR_T__ 4 // PPC-LINUX:#define __SIZEOF_WINT_T__ 4 +// PPC-LINUX:#define __SIZE_MAX__ 4294967295U // PPC-LINUX:#define __SIZE_TYPE__ unsigned int // PPC-LINUX:#define __SIZE_WIDTH__ 32 // PPC-LINUX:#define __UINTMAX_TYPE__ long long unsigned int @@ -2130,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 @@ -2212,6 +2369,7 @@ // SPARC:#define __SIZEOF_SIZE_T__ 4 // SPARC:#define __SIZEOF_WCHAR_T__ 4 // SPARC:#define __SIZEOF_WINT_T__ 4 +// SPARC:#define __SIZE_MAX__ 4294967295U // SPARC:#define __SIZE_TYPE__ long unsigned int // SPARC:#define __SIZE_WIDTH__ 32 // SPARC:#define __UINTMAX_TYPE__ long long unsigned int @@ -2306,6 +2464,7 @@ // TCE:#define __SIZEOF_SIZE_T__ 4 // TCE:#define __SIZEOF_WCHAR_T__ 4 // TCE:#define __SIZEOF_WINT_T__ 4 +// TCE:#define __SIZE_MAX__ 4294967295U // TCE:#define __SIZE_TYPE__ unsigned int // TCE:#define __SIZE_WIDTH__ 32 // TCE:#define __TCE_V1__ 1 @@ -2406,6 +2565,7 @@ // X86_64:#define __SIZEOF_SIZE_T__ 8 // X86_64:#define __SIZEOF_WCHAR_T__ 4 // X86_64:#define __SIZEOF_WINT_T__ 4 +// X86_64:#define __SIZE_MAX__ 18446744073709551615UL // X86_64:#define __SIZE_TYPE__ long unsigned int // X86_64:#define __SIZE_WIDTH__ 64 // X86_64:#define __SSE2_MATH__ 1 @@ -2509,6 +2669,7 @@ // X86_64-LINUX:#define __SIZEOF_SIZE_T__ 8 // X86_64-LINUX:#define __SIZEOF_WCHAR_T__ 4 // X86_64-LINUX:#define __SIZEOF_WINT_T__ 4 +// X86_64-LINUX:#define __SIZE_MAX__ 18446744073709551615UL // X86_64-LINUX:#define __SIZE_TYPE__ long unsigned int // X86_64-LINUX:#define __SIZE_WIDTH__ 64 // X86_64-LINUX:#define __SSE2_MATH__ 1 diff --git a/test/Preprocessor/line-directive.c b/test/Preprocessor/line-directive.c index ffa7c5a419..ea0a36fca3 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/macro_misc.c b/test/Preprocessor/macro_misc.c index 53d99821cc..3feaa210f7 100644 --- a/test/Preprocessor/macro_misc.c +++ b/test/Preprocessor/macro_misc.c @@ -21,3 +21,17 @@ #define FUNC_LIKE3(a) ( a) // expected-note {{previous definition is here}} #define FUNC_LIKE3(a) (a) // expected-warning {{'FUNC_LIKE3' macro redefined}} +// RUN: %clang_cc1 -fms-extensions -DMS_EXT %s -Eonly -verify +#ifndef MS_EXT +// This should under C99. +#define FUNC_LIKE4(a,b) (a+b) // expected-note {{previous definition is here}} +#define FUNC_LIKE4(x,y) (x+y) // expected-warning {{'FUNC_LIKE4' macro redefined}} +#else +// This shouldn't under MS extensions. +#define FUNC_LIKE4(a,b) (a+b) +#define FUNC_LIKE4(x,y) (x+y) + +// This should. +#define FUNC_LIKE5(a,b) (a+b) // expected-note {{previous definition is here}} +#define FUNC_LIKE5(x,y) (y+x) // expected-warning {{'FUNC_LIKE5' macro redefined}} +#endif diff --git a/test/Preprocessor/pp-modules.c b/test/Preprocessor/pp-modules.c new file mode 100644 index 0000000000..213a5fd23c --- /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 0000000000..e4ccacf143 --- /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 0000000000..be2a62b5e4 --- /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 075c9803a5..3c94363152 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 680f39af71..d0125cd0ed 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/predefined-macros.c b/test/Preprocessor/predefined-macros.c index 2c193018b5..94671f3335 100644 --- a/test/Preprocessor/predefined-macros.c +++ b/test/Preprocessor/predefined-macros.c @@ -26,3 +26,21 @@ // RUN: %clang_cc1 %s -E -dM -o - \ // RUN: | FileCheck %s --check-prefix=CHECK-FINITE-MATH-FLAG-UNDEFINED // CHECK-FINITE-MATH-FLAG-UNDEFINED: #define __FINITE_MATH_ONLY__ 0 +// +// RUN: %clang_cc1 %s -E -dM -o - -triple i686 -target-cpu i386 \ +// RUN: | FileCheck %s --check-prefix=CHECK-SYNC_CAS_I386 +// CHECK-SYNC_CAS_I386-NOT: __GCC_HAVE_SYNC_COMPARE_AND_SWAP +// +// RUN: %clang_cc1 %s -E -dM -o - -triple i686 -target-cpu i486 \ +// RUN: | FileCheck %s --check-prefix=CHECK-SYNC_CAS_I486 +// CHECK-SYNC_CAS_I486: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 +// CHECK-SYNC_CAS_I486: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 +// CHECK-SYNC_CAS_I486: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 +// CHECK-SYNC_CAS_I486-NOT: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 +// +// RUN: %clang_cc1 %s -E -dM -o - -triple i686 -target-cpu i586 \ +// RUN: | FileCheck %s --check-prefix=CHECK-SYNC_CAS_I586 +// CHECK-SYNC_CAS_I586: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 +// CHECK-SYNC_CAS_I586: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 +// CHECK-SYNC_CAS_I586: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 +// CHECK-SYNC_CAS_I586: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 diff --git a/test/Preprocessor/stdint.c b/test/Preprocessor/stdint.c index 70c106bf79..c3be05d97c 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 022bb5f4e3..f416b6622f 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/Rewriter/rewrite-line-directive.m b/test/Rewriter/rewrite-line-directive.m new file mode 100644 index 0000000000..5c4e9574c1 --- /dev/null +++ b/test/Rewriter/rewrite-line-directive.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -E %s -o %t.mm +// RUN: %clang -fms-extensions -rewrite-objc %t.mm -o %t-rw.cpp +// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s +// RUN: %clang -g -fms-extensions -rewrite-objc %t.mm -o %t-rw.cpp +// RUN: FileCheck -check-prefix LPG --input-file=%t-rw.cpp %s +// rdar://13138170 + +int z(); + +int x() { + id foo; + for (id y in foo) { + z(); + } + return 0; +} +// CHECK-LP-NOT: #line +// CHECK-LPG: #line diff --git a/test/Rewriter/rewrite-modern-qualified-type.mm b/test/Rewriter/rewrite-modern-qualified-type.mm new file mode 100644 index 0000000000..53e0d23ef2 --- /dev/null +++ b/test/Rewriter/rewrite-modern-qualified-type.mm @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp +// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D_Bool=bool -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp +// rdar://13562505 + +@protocol OS_dispatch_object @end + +@interface NSObject @end + +@protocol OS_dispatch_queue <OS_dispatch_object> @end typedef NSObject<OS_dispatch_queue> *dispatch_queue_t; + +typedef id<OS_dispatch_queue> dispatch_queue_i; diff --git a/test/Sema/MicrosoftCompatibility.cpp b/test/Sema/MicrosoftCompatibility.cpp new file mode 100644 index 0000000000..15c25586c4 --- /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/anonymous-struct-union.c b/test/Sema/anonymous-struct-union.c index e0822901b0..35d3175416 100644 --- a/test/Sema/anonymous-struct-union.c +++ b/test/Sema/anonymous-struct-union.c @@ -78,7 +78,7 @@ void g() { struct s0 { union { int f0; }; }; // <rdar://problem/6481130> -typedef struct { }; // expected-warning{{declaration does not declare anything}} +typedef struct { }; // expected-warning{{typedef requires a name}} // PR3675 struct s1 { diff --git a/test/Sema/arm-neon-types.c b/test/Sema/arm-neon-types.c index 1a170dbb7e..a49de12d44 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 b3cae60495..f92852f341 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 155d736b99..c81f16a387 100644 --- a/test/Sema/asm.c +++ b/test/Sema/asm.c @@ -123,3 +123,26 @@ void test13(void) { void *esp; __asm__ volatile ("mov %%esp, %o" : "=r"(esp) : : ); // expected-error {{invalid % escape in inline assembly string}} } + +// <rdar://problem/12700799> +struct S; // expected-note 2 {{forward declaration of 'struct S'}} +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 0000000000..ecc04c4c68 --- /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/atomic-ops.c b/test/Sema/atomic-ops.c index a33ff2b19c..b3daa0704d 100644 --- a/test/Sema/atomic-ops.c +++ b/test/Sema/atomic-ops.c @@ -173,3 +173,6 @@ void f(_Atomic(int) *i, _Atomic(int*) *p, _Atomic(float) *d, __c11_atomic_store(&const_atomic, 0, memory_order_release); // expected-error {{first argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} __c11_atomic_load(&const_atomic, memory_order_acquire); // expected-error {{first argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} } + +_Atomic(int*) PR12527_a; +void PR12527() { int *b = PR12527_a; } diff --git a/test/Sema/bitfield.c b/test/Sema/bitfield.c index a1ce894037..ab05a7773d 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/block-return.c b/test/Sema/block-return.c index 2ea4d813ab..6b4d99830c 100644 --- a/test/Sema/block-return.c +++ b/test/Sema/block-return.c @@ -134,3 +134,14 @@ void foo7() void (^blk)(void) = ^{ return (void)0; // expected-warning {{void block literal should not return void expression}} }; + +// rdar://13463504 +enum Test8 { T8_a, T8_b, T8_c }; +void test8(void) { + extern void test8_helper(int (^)(int)); + test8_helper(^(int flag) { if (flag) return T8_a; return T8_b; }); +} +void test8b(void) { + extern void test8_helper2(char (^)(int)); // expected-note {{here}} + test8_helper2(^(int flag) { if (flag) return T8_a; return T8_b; }); // expected-error {{passing 'enum Test8 (^)(int)' to parameter of type 'char (^)(int)'}} +} diff --git a/test/Sema/builtins-aarch64.c b/test/Sema/builtins-aarch64.c new file mode 100644 index 0000000000..03e03343eb --- /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 0000000000..9285a7802d --- /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/compare.c b/test/Sema/compare.c index b5d4ef5d12..887bce0630 100644 --- a/test/Sema/compare.c +++ b/test/Sema/compare.c @@ -93,8 +93,8 @@ int ints(long a, unsigned long b) { // (C,b) (C == (unsigned long) b) + (C == (unsigned int) b) + - (C == (unsigned short) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned short' is always false}} - (C == (unsigned char) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned char' is always false}} + (C == (unsigned short) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always false}} + (C == (unsigned char) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always false}} ((long) C == b) + ((int) C == b) + ((short) C == b) + @@ -105,8 +105,8 @@ int ints(long a, unsigned long b) { ((signed char) C == (unsigned char) b) + (C < (unsigned long) b) + (C < (unsigned int) b) + - (C < (unsigned short) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned short' is always false}} - (C < (unsigned char) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned char' is always false}} + (C < (unsigned short) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always false}} + (C < (unsigned char) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always false}} ((long) C < b) + ((int) C < b) + ((short) C < b) + @@ -123,8 +123,8 @@ int ints(long a, unsigned long b) { (a == (unsigned char) C) + ((long) a == C) + ((int) a == C) + - ((short) a == C) + // expected-warning {{comparison of constant 65536 with expression of type 'short' is always false}} - ((signed char) a == C) + // expected-warning {{comparison of constant 65536 with expression of type 'signed char' is always false}} + ((short) a == C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always false}} + ((signed char) a == C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always false}} ((long) a == (unsigned long) C) + ((int) a == (unsigned int) C) + ((short) a == (unsigned short) C) + @@ -135,8 +135,8 @@ int ints(long a, unsigned long b) { (a < (unsigned char) C) + ((long) a < C) + ((int) a < C) + - ((short) a < C) + // expected-warning {{comparison of constant 65536 with expression of type 'short' is always true}} - ((signed char) a < C) + // expected-warning {{comparison of constant 65536 with expression of type 'signed char' is always true}} + ((short) a < C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always true}} + ((signed char) a < C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always true}} ((long) a < (unsigned long) C) + // expected-warning {{comparison of integers of different signs}} ((int) a < (unsigned int) C) + // expected-warning {{comparison of integers of different signs}} ((short) a < (unsigned short) C) + diff --git a/test/Sema/crash-invalid-array.c b/test/Sema/crash-invalid-array.c index a3bc03b70b..eeac39148c 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/decl-invalid.c b/test/Sema/decl-invalid.c index f6fed3c92d..0544304c20 100644 --- a/test/Sema/decl-invalid.c +++ b/test/Sema/decl-invalid.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify // See Sema::ParsedFreeStandingDeclSpec about the double diagnostic -typedef union <anonymous> __mbstate_t; // expected-error {{declaration of anonymous union must be a definition}} expected-warning {{declaration does not declare anything}} +typedef union <anonymous> __mbstate_t; // expected-error {{declaration of anonymous union must be a definition}} expected-warning {{typedef requires a name}} // PR2017 @@ -14,7 +14,7 @@ int a() { } int; // expected-warning {{declaration does not declare anything}} -typedef int; // expected-warning {{declaration does not declare anything}} +typedef int; // expected-warning {{typedef requires a name}} const int; // expected-warning {{declaration does not declare anything}} struct; // expected-error {{declaration of anonymous struct must be a definition}} // expected-warning {{declaration does not declare anything}} typedef int I; diff --git a/test/Sema/declspec.c b/test/Sema/declspec.c index 7354028cba..30c009201c 100644 --- a/test/Sema/declspec.c +++ b/test/Sema/declspec.c @@ -10,7 +10,7 @@ int typedef validTypeDecl() { } // expected-error {{function definition declared struct _zend_module_entry { } // expected-error {{expected ';' after struct}} int gv1; typedef struct _zend_function_entry { } // expected-error {{expected ';' after struct}} \ - // expected-warning {{declaration does not declare anything}} + // expected-warning {{typedef requires a name}} int gv2; static void buggy(int *x) { } diff --git a/test/Sema/expr-comma-c99.c b/test/Sema/expr-comma-c99.c index 6e97a4fc49..02886bff05 100644 --- a/test/Sema/expr-comma-c99.c +++ b/test/Sema/expr-comma-c99.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c99 +// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c99 -Wno-sizeof-array-decay // expected-no-diagnostics // rdar://6095180 diff --git a/test/Sema/expr-comma.c b/test/Sema/expr-comma.c index 7902715915..e2beafe236 100644 --- a/test/Sema/expr-comma.c +++ b/test/Sema/expr-comma.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c89 +// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c89 -Wno-sizeof-array-decay // expected-no-diagnostics // rdar://6095180 diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c index df3e25857c..2fb17e4880 100644 --- a/test/Sema/exprs.c +++ b/test/Sema/exprs.c @@ -94,7 +94,7 @@ int test8(void) { struct f { int x : 4; float y[]; }; int test9(struct f *P) { int R; - R = __alignof(P->x); // expected-error {{invalid application of '__alignof' to bit-field}} + R = __alignof(P->x); // expected-error {{invalid application of 'alignof' to bit-field}} R = __alignof(P->y); // ok. R = sizeof(P->x); // expected-error {{invalid application of 'sizeof' to bit-field}} return R; diff --git a/test/Sema/extern-redecl.c b/test/Sema/extern-redecl.c index ae4386eaae..e9a4c571bd 100644 --- a/test/Sema/extern-redecl.c +++ b/test/Sema/extern-redecl.c @@ -22,3 +22,43 @@ int PR10013(void) { static int test1_a[]; // expected-warning {{tentative array definition assumed to have one element}} extern int test1_a[]; + +// rdar://13535367 +void test2declarer() { extern int test2_array[100]; } +extern int test2_array[]; +int test2v = sizeof(test2_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} + +void test3declarer() { + { extern int test3_array[100]; } + 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 3ee8763a56..561f7fae6b 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 1b0dc2adeb..bbf81a56cb 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/inline.c b/test/Sema/inline.c index c27c00efaa..496e282eca 100644 --- a/test/Sema/inline.c +++ b/test/Sema/inline.c @@ -73,6 +73,16 @@ inline int useStaticAgain () { // expected-note 2 {{use 'static' to give inline #pragma clang diagnostic pop +inline void defineStaticVar() { // expected-note {{use 'static' to give inline function 'defineStaticVar' internal linkage}} + static const int x = 0; // ok + static int y = 0; // expected-warning {{non-constant static local variable in inline function may be different in different files}} +} + +extern inline void defineStaticVarInExtern() { + static const int x = 0; // ok + static int y = 0; // ok +} + #endif 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 0000000000..a0702ad7df --- /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 c3b3aa77c5..300e585588 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 8f5f24652d..ac2694f72e 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,9 +87,29 @@ 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 { + struct BlockInputIter { + void* operator++(int); + void* operator--(int); + }; + + void test(BlockInputIter i) { + (void)(i++ ? true : false); // no-warning + (void)(i-- ? true : false); // no-warning + } } diff --git a/test/Sema/pragma-arc-cf-code-audited.c b/test/Sema/pragma-arc-cf-code-audited.c index b646e8966c..c1aa804557 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/private-extern.c b/test/Sema/private-extern.c index e480f3f224..e9b67d5070 100644 --- a/test/Sema/private-extern.c +++ b/test/Sema/private-extern.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -verify -fsyntax-only -Wno-private-extern %s +// RUN: %clang_cc1 -verify -fsyntax-only -Wno-private-extern -fmodules %s static int g0; // expected-note{{previous definition}} int g0; // expected-error{{non-static declaration of 'g0' follows static declaration}} diff --git a/test/Sema/return.c b/test/Sema/return.c index 77bd3f688e..7e7c8b7b84 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); @@ -244,6 +250,11 @@ const int ignored_c_quals(); // expected-warning{{'const' type qualifier on retu const volatile int ignored_cv_quals(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}} char* const volatile restrict ignored_cvr_quals(); // expected-warning{{'const volatile restrict' type qualifiers on return type have no effect}} +typedef const int CI; +CI ignored_quals_typedef(); + +const CI ignored_quals_typedef_2(); // expected-warning{{'const' type qualifier}} + // Test that for switch(enum) that if the switch statement covers all the cases // that we don't consider that for -Wreturn-type. enum Cases { C1, C2, C3, C4 }; diff --git a/test/Sema/static-assert.c b/test/Sema/static-assert.c index 9309987431..87fa0504b2 100644 --- a/test/Sema/static-assert.c +++ b/test/Sema/static-assert.c @@ -1,6 +1,10 @@ -// RUN: %clang_cc1 -std=c1x -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -xc++ -std=c++11 -fsyntax-only -verify %s -_Static_assert("foo", "string is nonzero"); // expected-error {{static_assert expression is not an integral constant expression}} +_Static_assert("foo", "string is nonzero"); +#ifndef __cplusplus +// expected-error@-2 {{static_assert expression is not an integral constant expression}} +#endif _Static_assert(1, "1 is nonzero"); _Static_assert(0, "0 is nonzero"); // expected-error {{static_assert failed "0 is nonzero"}} @@ -11,3 +15,28 @@ void foo(void) { } _Static_assert(1, invalid); // expected-error {{expected string literal for diagnostic message in static_assert}} + +struct A { + int a; + _Static_assert(1, "1 is nonzero"); + _Static_assert(0, "0 is nonzero"); // expected-error {{static_assert failed "0 is nonzero"}} +}; + +#ifdef __cplusplus +#define ASSERT_IS_TYPE(T) __is_same(T, T) +#else +#define ASSERT_IS_TYPE(T) __builtin_types_compatible_p(T, T) +#endif + +#define UNION(T1, T2) union { \ + __typeof__(T1) one; \ + __typeof__(T2) two; \ + _Static_assert(ASSERT_IS_TYPE(T1), "T1 is not a type"); \ + _Static_assert(ASSERT_IS_TYPE(T2), "T2 is not a type"); \ + _Static_assert(sizeof(T1) == sizeof(T2), "type size mismatch"); \ + } + +typedef UNION(unsigned, struct A) U1; +UNION(char[2], short) u2 = { .one = { 'a', 'b' } }; +typedef UNION(char, short) U3; // expected-error {{static_assert failed "type size mismatch"}} +typedef UNION(float, 0.5f) U4; // expected-error {{expected a type}} diff --git a/test/Sema/struct-decl.c b/test/Sema/struct-decl.c index 6070e875f5..819e856ac8 100644 --- a/test/Sema/struct-decl.c +++ b/test/Sema/struct-decl.c @@ -54,6 +54,6 @@ static struct test1 { // expected-warning {{'static' ignored on this declaration const struct test2 { // expected-warning {{'const' ignored on this declaration}} int x; }; -inline struct test3 { // expected-warning {{'inline' ignored on this declaration}} +inline struct test3 { // expected-error {{'inline' can only appear on functions}} int x; }; diff --git a/test/Sema/switch-1.c b/test/Sema/switch-1.c index 82ce6747a3..ce1e7dc943 100644 --- a/test/Sema/switch-1.c +++ b/test/Sema/switch-1.c @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-apple-darwin10 %s // RUN: %clang_cc1 -x c++ -fsyntax-only -verify -triple x86_64-apple-darwin10 %s // rdar://11577384 +// rdar://13423975 int f(int i) { switch (i) { @@ -10,6 +11,9 @@ int f(int i) { return 2; case (123456 *789012) + 1: // expected-warning {{overflow in expression; result is -1375982336 with type 'int'}} return 3; + case (2147483647*4)/4: // expected-warning {{overflow in expression; result is -4 with type 'int'}} + case (2147483647*4)%4: // expected-warning {{overflow in expression; result is -4 with type 'int'}} + return 4; case 2147483647: return 0; } diff --git a/test/Sema/thread-specifier.c b/test/Sema/thread-specifier.c index 8c40fcd0a6..9d516e8f14 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 f7576b6c02..363458b201 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 0132ef280c..b3ab0199dc 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 98c4993561..0737a8dedd 100644 --- a/test/Sema/warn-documentation.m +++ b/test/Sema/warn-documentation.m @@ -123,6 +123,20 @@ typedef id OBJ; } @end +// rdar://12379114 +// expected-warning@+4 {{'@methodgroup' command should be used in a comment attached to an Objective-C method declaration}} +// expected-warning@+6 {{'@method' command should be used in a comment attached to an Objective-C method declaratio}} +@interface rdar12379114 +/*! + @methodgroup Creating a request +*/ +/*! + @method initWithTimeout is the 2nd method +*/ +typedef unsigned int NSTimeInterval; +- (id)initWithTimeout:(NSTimeInterval)timeout; +@end + // expected-warning@+2 {{'@protocol' command should not be used in a comment attached to a non-protocol declaration}} /*! @protocol PROTO @@ -135,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 239f6f1995..f108b3aa6c 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/Sema/warn-sizeof-array-decay.c b/test/Sema/warn-sizeof-array-decay.c new file mode 100644 index 0000000000..cc3ee1d0fc --- /dev/null +++ b/test/Sema/warn-sizeof-array-decay.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void f(int x) { + char foo[10]; + int bar[20]; + char qux[30]; + + (void)sizeof(bar + 10); // expected-warning{{sizeof on pointer operation will return size of 'int *' instead of 'int [20]'}} + (void)sizeof(foo - 20); // expected-warning{{sizeof on pointer operation will return size of 'char *' instead of 'char [10]'}} + (void)sizeof(bar - x); // expected-warning{{sizeof on pointer operation will return size of 'int *' instead of 'int [20]'}} + (void)sizeof(foo + x); // expected-warning{{sizeof on pointer operation will return size of 'char *' instead of 'char [10]'}} + + // This is ptrdiff_t. + (void)sizeof(foo - qux); // no-warning + + (void)sizeof(foo, x); // no-warning + (void)sizeof(x, foo); // expected-warning{{sizeof on pointer operation will return size of 'char *' instead of 'char [10]'}} +} diff --git a/test/Sema/warn-unused-variables-werror.c b/test/Sema/warn-unused-variables-werror.c new file mode 100644 index 0000000000..ceaff1ba69 --- /dev/null +++ b/test/Sema/warn-unused-variables-werror.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Werror -verify %s + +void f() { + int i; // expected-error{{unused}} + int j; // expected-error{{unused}} +} diff --git a/test/SemaCXX/Inputs/warn-unused-variables.h b/test/SemaCXX/Inputs/warn-unused-variables.h new file mode 100644 index 0000000000..5fac45922c --- /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 449e24b03b..ab3ff69f27 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 18ad301b5f..50f2eff87b 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 0000000000..a9de1ad07c --- /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/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp index 93b5b0abba..9c2cf24a83 100644 --- a/test/SemaCXX/anonymous-union.cpp +++ b/test/SemaCXX/anonymous-union.cpp @@ -110,7 +110,7 @@ struct BadMembers { }; // <rdar://problem/6481130> -typedef union { }; // expected-warning{{declaration does not declare anything}} +typedef union { }; // expected-warning{{typedef requires a name}} // <rdar://problem/7562438> typedef struct objc_module *Foo ; diff --git a/test/SemaCXX/ast-print.cpp b/test/SemaCXX/ast-print.cpp index 5de8c4b51b..921f7d8baa 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/atomic-type.cxx b/test/SemaCXX/atomic-type.cxx index 18707eb8c5..947bb3c5f4 100644 --- a/test/SemaCXX/atomic-type.cxx +++ b/test/SemaCXX/atomic-type.cxx @@ -1,7 +1,9 @@ -// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -verify -pedantic %s template<typename T> struct atomic { _Atomic(T) value; + + void f() _Atomic; // expected-error {{expected ';' at end of declaration list}} }; template<typename T> struct user { @@ -15,9 +17,11 @@ user<int> u; struct A { }; int &ovl1(_Atomic(int)); +int &ovl1(_Atomic int); // ok, redeclaration long &ovl1(_Atomic(long)); float &ovl1(_Atomic(float)); double &ovl1(_Atomic(A const *const *)); +double &ovl1(A const *const *_Atomic); short &ovl1(_Atomic(A **)); void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af, @@ -33,3 +37,22 @@ void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af, double &dr2 = ovl1(ac); short &sr1 = ovl1(a); } + +typedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}} + +typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int; +typedef int(A::*_Atomic atomic_mem_ptr_to_int); + +typedef _Atomic(int)(A::*mem_ptr_to_atomic_int); +typedef _Atomic int(A::*mem_ptr_to_atomic_int); + +typedef _Atomic(int)&atomic_int_ref; +typedef _Atomic int &atomic_int_ref; +typedef _Atomic atomic_int_ref atomic_int_ref; // ok, qualifiers on references ignored in this case. + +typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}} +typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}} + +struct S { + _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}} +}; diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp index 002800e749..e9276cd2d9 100644 --- a/test/SemaCXX/attr-cxx0x.cpp +++ b/test/SemaCXX/attr-cxx0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -pedantic -std=c++11 %s int align_illegal alignas(3); //expected-error {{requested alignment is not a power of 2}} char align_big alignas(int); @@ -43,3 +43,5 @@ static_assert(alignof(align_class_template<16>) == 16, "template's alignment is static_assert(alignof(align_class_temp_pack_type<short, int, long>) == alignof(long), "template's alignment is wrong"); static_assert(alignof(align_class_temp_pack_expr<8, 16, 32>) == 32, "template's alignment is wrong"); static_assert(alignof(outer<int,char>::inner<double,short>) == alignof(int) * alignof(double), "template's alignment is wrong"); + +static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-warning{{invalid application of 'alignof' to a function type}} diff --git a/test/SemaCXX/attr-noreturn.cpp b/test/SemaCXX/attr-noreturn.cpp index f3d548b793..41214c4f4b 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/blocks.cpp b/test/SemaCXX/blocks.cpp index a635e998d9..a2672d13b7 100644 --- a/test/SemaCXX/blocks.cpp +++ b/test/SemaCXX/blocks.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fblocks -// expected-no-diagnostics void tovoid(void*); @@ -82,3 +81,22 @@ void move_block() { __block MoveOnly mo; } +// Don't crash after failing to build a block due to a capture of an +// invalid declaration. +namespace test5 { + struct B { // expected-note 2 {{candidate constructor}} + void *p; + B(int); // expected-note {{candidate constructor}} + }; + + void use_block(void (^)()); + void use_block_2(void (^)(), const B &a); + + void test() { + B x; // expected-error {{no matching constructor for initialization}} + use_block(^{ + int y; + use_block_2(^{ (void) y; }, x); + }); + } +} diff --git a/test/SemaCXX/captured-statements.cpp b/test/SemaCXX/captured-statements.cpp new file mode 100644 index 0000000000..dbb18a7b67 --- /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/class-base-member-init.cpp b/test/SemaCXX/class-base-member-init.cpp index e84e57b747..2cdca829ff 100644 --- a/test/SemaCXX/class-base-member-init.cpp +++ b/test/SemaCXX/class-base-member-init.cpp @@ -90,3 +90,11 @@ namespace test5 { } }; } + +namespace rdar13185264 { + class X { + X() : a(), // expected-note{{previous initialization is here}} + a() { } // expected-error{{multiple initializations given for non-static member 'a'}} + union { void *a; }; + }; +} diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp index 5771912590..feb1ccb9a2 100644 --- a/test/SemaCXX/compare.cpp +++ b/test/SemaCXX/compare.cpp @@ -89,8 +89,8 @@ int test0(long a, unsigned long b) { // (C,b) (C == (unsigned long) b) + (C == (unsigned int) b) + - (C == (unsigned short) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned short' is always false}} - (C == (unsigned char) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned char' is always false}} + (C == (unsigned short) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always false}} + (C == (unsigned char) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always false}} ((long) C == b) + ((int) C == b) + ((short) C == b) + @@ -101,8 +101,8 @@ int test0(long a, unsigned long b) { ((signed char) C == (unsigned char) b) + (C < (unsigned long) b) + (C < (unsigned int) b) + - (C < (unsigned short) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned short' is always false}} - (C < (unsigned char) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned char' is always false}} + (C < (unsigned short) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always false}} + (C < (unsigned char) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always false}} ((long) C < b) + ((int) C < b) + ((short) C < b) + @@ -119,8 +119,8 @@ int test0(long a, unsigned long b) { (a == (unsigned char) C) + ((long) a == C) + ((int) a == C) + - ((short) a == C) + // expected-warning {{comparison of constant 65536 with expression of type 'short' is always false}} - ((signed char) a == C) + // expected-warning {{comparison of constant 65536 with expression of type 'signed char' is always false}} + ((short) a == C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always false}} + ((signed char) a == C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always false}} ((long) a == (unsigned long) C) + ((int) a == (unsigned int) C) + ((short) a == (unsigned short) C) + @@ -131,8 +131,8 @@ int test0(long a, unsigned long b) { (a < (unsigned char) C) + ((long) a < C) + ((int) a < C) + - ((short) a < C) + // expected-warning {{comparison of constant 65536 with expression of type 'short' is always true}} - ((signed char) a < C) + // expected-warning {{comparison of constant 65536 with expression of type 'signed char' is always true}} + ((short) a < C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always true}} + ((signed char) a < C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always true}} ((long) a < (unsigned long) C) + // expected-warning {{comparison of integers of different signs}} ((int) a < (unsigned int) C) + // expected-warning {{comparison of integers of different signs}} ((short) a < (unsigned short) C) + diff --git a/test/SemaCXX/compound-literal.cpp b/test/SemaCXX/compound-literal.cpp index fe0e45d3c6..595747e40c 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 d805881194..73f3dceef6 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 30aa7d7b0b..09a9cb5dd8 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 0000000000..60ec82062d --- /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 9170fa1ec2..e545f45d60 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 e459f097b9..d137bd88db 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/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp index c54956db41..17576328c1 100644 --- a/test/SemaCXX/constructor-initializer.cpp +++ b/test/SemaCXX/constructor-initializer.cpp @@ -232,13 +232,15 @@ namespace PR7402 { // <rdar://problem/8308215>: don't crash. // Lots of questionable recovery here; errors can change. namespace test3 { - class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 2 {{candidate}} + class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 4 {{candidate}} class B : public A { public: B(const String& s, int e=0) // expected-error {{unknown type name}} : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}} B(const B& e) - : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} expected-error {{no member named 'm_String' in 'test3::B'}} + : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} \ + // expected-error {{no member named 'm_String' in 'test3::B'}} \ + // expected-error {{no matching}} } }; } diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp index 3ba03c4eee..bc03bcd2a1 100644 --- a/test/SemaCXX/cxx0x-defaulted-functions.cpp +++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fcxx-exceptions %s void fn() = default; // expected-error {{only special member}} struct foo { @@ -175,3 +175,16 @@ extern "C" { template<typename _Tp> // expected-error {{templates must have C++ linkage}} void PR13573(const _Tp&) = delete; // expected-error {{only functions can have deleted definitions}} } + +namespace PR15597 { + template<typename T> struct A { + A() noexcept(true) = default; + ~A() noexcept(true) = default; + }; + template<typename T> struct B { + B() noexcept(false) = default; // expected-error {{does not match the calculated one}} + ~B() noexcept(false) = default; // expected-error {{does not match the calculated one}} + }; + A<int> a; + B<int> b; // expected-note {{here}} +} diff --git a/test/SemaCXX/cxx11-ast-print.cpp b/test/SemaCXX/cxx11-ast-print.cpp index f95eeb50fe..f7bfc1123a 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 bd51af1da2..a4d4829f3f 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 0000000000..67d55213a0 --- /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 0000000000..9d9a82b7e6 --- /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 0000000000..f1dddc1c3b --- /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 0000000000..cd93ffbf21 --- /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 0000000000..1643adbe0b --- /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 0000000000..3f100b8b69 --- /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 0000000000..f0146f88d6 --- /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 0000000000..9b542403de --- /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 18fd1520ec..208ea4ce92 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-scoped.cpp b/test/SemaCXX/enum-scoped.cpp index a1f911d79d..d01000d22b 100644 --- a/test/SemaCXX/enum-scoped.cpp +++ b/test/SemaCXX/enum-scoped.cpp @@ -252,3 +252,17 @@ namespace pr13128 { enum class E { C }; }; } + +namespace PR15633 { + template<typename T> struct A { + struct B { + enum class E : T; + enum class E2 : T; + }; + }; + template<typename T> enum class A<T>::B::E { e }; + template class A<int>; + + struct B { enum class E; }; + template<typename T> enum class B::E { e }; // expected-error {{enumeration cannot be a template}} +} diff --git a/test/SemaCXX/enum-unscoped-nonexistent.cpp b/test/SemaCXX/enum-unscoped-nonexistent.cpp index d49800caa6..e9da38f558 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/extern-c.cpp b/test/SemaCXX/extern-c.cpp new file mode 100644 index 0000000000..c55b10d9d6 --- /dev/null +++ b/test/SemaCXX/extern-c.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace test1 { + extern "C" { + void f() { + void test1_g(int); // expected-note {{previous declaration is here}} + } + } +} +int test1_g(int); // expected-error {{functions that differ only in their return type cannot be overloaded}} + +namespace test2 { + extern "C" { + void f() { + extern int test2_x; // expected-note {{previous definition is here}} + } + } +} +float test2_x; // expected-error {{redefinition of 'test2_x' with a different type: 'float' vs 'int'}} + +namespace test3 { + extern "C" { + void f() { + extern int test3_b; // expected-note {{previous definition is here}} + } + } + extern "C" { + float test3_b; // expected-error {{redefinition of 'test3_b' with a different type: 'float' vs 'int'}} + } +} + +extern "C" { + void test4_f() { + extern int test4_b; // expected-note {{previous definition is here}} + } +} +static float test4_b; // expected-error {{redefinition of 'test4_b' with a different type: 'float' vs 'int'}} + +extern "C" { + void test5_f() { + extern int test5_b; // expected-note {{previous definition is here}} + } +} +extern "C" { + static float test5_b; // expected-error {{redefinition of 'test5_b' with a different type: 'float' vs 'int'}} +} + +extern "C" { + void f() { + extern int test6_b; + } +} +namespace foo { + extern "C" { + static float test6_b; + extern float test6_b; + } +} diff --git a/test/SemaCXX/for-range-unused.cpp b/test/SemaCXX/for-range-unused.cpp index ce6b379cc1..ec11015552 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/friend.cpp b/test/SemaCXX/friend.cpp index c5b11eb5a3..b401a06a7e 100644 --- a/test/SemaCXX/friend.cpp +++ b/test/SemaCXX/friend.cpp @@ -138,3 +138,19 @@ namespace test7 { }; } } + +// PR15485 +namespace test8 { + namespace ns1 { + namespace ns2 { + template<class T> void f(T t); // expected-note {{target of using declaration}} + } + using ns2::f; // expected-note {{using declaration}} + } + struct A { void f(); }; // expected-note {{target of using declaration}} + struct B : public A { using A::f; }; // expected-note {{using declaration}} + struct X { + template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}} + friend void B::f(); // expected-error {{cannot befriend target of using declaration}} + }; +} diff --git a/test/SemaCXX/function-extern-c.cpp b/test/SemaCXX/function-extern-c.cpp index a4b8400abc..6ab9657350 100644 --- a/test/SemaCXX/function-extern-c.cpp +++ b/test/SemaCXX/function-extern-c.cpp @@ -49,7 +49,7 @@ namespace test2 { struct A { A(const A&); }; - A f(void); // expected-warning {{'f' has C-linkage specified, but returns user-defined type 'test2::A' which is incompatible with C}} + A f(void); // no warning. warning is already issued on first declaration. } namespace test3 { @@ -61,3 +61,38 @@ namespace test3 { static A f(void); } } + +// rdar://13364028 +namespace rdar13364028 { +class A { +public: + virtual int x(); +}; + +extern "C" { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +A xyzzy(); +#pragma clang diagnostic pop +A bbb(); // expected-warning {{'bbb' has C-linkage specified, but returns user-defined type 'rdar13364028::A' which is incompatible with C}} +A ccc() { // expected-warning {{'ccc' has C-linkage specified, but returns user-defined type 'rdar13364028::A' which is incompatible with C}} + return A(); +}; +} + +A xyzzy(); + +A xyzzy() +{ + return A(); +} + +A bbb() +{ + return A(); +} + +A bbb(); + +A ccc(); +} diff --git a/test/SemaCXX/function-redecl.cpp b/test/SemaCXX/function-redecl.cpp index 7bf44b1c36..b9d1f23af4 100644 --- a/test/SemaCXX/function-redecl.cpp +++ b/test/SemaCXX/function-redecl.cpp @@ -116,32 +116,3 @@ bool Foo::isGood() { // expected-error {{out-of-line definition of 'isGood' does } void Foo::beEvil() {} // expected-error {{out-of-line definition of 'beEvil' does not match any declaration in namespace 'redecl_typo::Foo'; did you mean 'BeEvil'?}} } - -namespace test2 { - extern "C" { - void f() { - void test2_g(int); // expected-note {{previous declaration is here}} - } - } -} -int test2_g(int); // expected-error {{functions that differ only in their return type cannot be overloaded}} - -namespace test3 { - extern "C" { - void f() { - extern int test3_x; // expected-note {{previous definition is here}} - } - } -} -float test3_x; // expected-error {{redefinition of 'test3_x' with a different type: 'float' vs 'int'}} - -namespace test4 { - extern "C" { - void f() { - extern int b; // expected-note {{previous definition is here}} - } - } - extern "C" { - float b; // expected-error {{redefinition of 'b' with a different type: 'float' vs 'int'}} - } -} diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp index 5631577e0f..c80323ccd7 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 cb7e32c05d..504df0d35c 100644 --- a/test/SemaCXX/linkage-spec.cpp +++ b/test/SemaCXX/linkage-spec.cpp @@ -90,6 +90,10 @@ extern "C++" using N::value; // PR7076 extern "C" const char *Version_string = "2.9"; +extern "C" { + extern const char *Version_string2 = "2.9"; +} + namespace PR9162 { extern "C" { typedef struct _ArtsSink ArtsSink; @@ -102,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 6b73d596e0..13d295a5d5 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 2cee581b49..3cfa98138b 100644 --- a/test/SemaCXX/linkage2.cpp +++ b/test/SemaCXX/linkage2.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -fmodules %s namespace test1 { int x; // expected-note {{previous definition is here}} @@ -125,3 +126,41 @@ extern "C" { void __attribute__((overloadable)) test11_g(double); } } + +namespace test12 { + const int n = 0; + extern const int n; + void f() { + extern const int n; + } +} + +namespace test13 { + static void a(void); + extern void a(); + static void a(void) {} +} + +namespace test14 { + namespace { + void a(void); // expected-note {{previous declaration is here}} + static void a(void) {} // expected-error {{static declaration of 'a' follows non-static declaration}} + } +} + +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/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp index 3b2d0fceb9..7dca121905 100644 --- a/test/SemaCXX/member-pointer-ms.cpp +++ b/test/SemaCXX/member-pointer-ms.cpp @@ -1,14 +1,167 @@ -// RUN: %clang_cc1 -cxx-abi microsoft -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify %s +// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify %s +// +// This file should also give no diagnostics when run through cl.exe from MSVS +// 2012, which supports C++11 and static_assert. It should pass for both 64-bit +// and 32-bit x86. +// +// expected-no-diagnostics -// Test that we reject pointers to members of incomplete classes (for now) -struct A; //expected-note{{forward declaration of 'A'}} -int A::*pai1; //expected-error{{incomplete type 'A'}} +// Test the size of various member pointer combinations: +// - complete and incomplete +// - single, multiple, and virtual inheritance (and unspecified for incomplete) +// - data and function pointers +// - templated with declared specializations with annotations +// - template that can be instantiated -// Test that we don't allow reinterpret_casts from pointers of one size to -// pointers of a different size. -struct A {}; -struct B {}; -struct C: A, B {}; +// http://llvm.org/PR12070 +struct Foo { + typedef int Foo::*FooInt; + int f; +}; -void (A::*paf)(); -void (C::*pcf)() = reinterpret_cast<void (C::*)()>(paf); //expected-error{{cannot reinterpret_cast from member pointer type}} +enum { + kSingleDataSize = 1 * sizeof(int), + kSingleFunctionSize = 1 * sizeof(void *), + kMultipleDataSize = 1 * sizeof(int), + kMultipleFunctionSize = 2 * sizeof(void *), + kVirtualDataSize = 2 * sizeof(int), + kVirtualFunctionSize = 2 * sizeof(int) + 1 * sizeof(void *), + // Unspecified is weird, it's 1 more slot than virtual. + kUnspecifiedDataSize = kVirtualDataSize + 1 * sizeof(int), + kUnspecifiedFunctionSize = kVirtualFunctionSize + 1 * sizeof(void *), +}; + +// incomplete types +class __single_inheritance IncSingle; +class __multiple_inheritance IncMultiple; +class __virtual_inheritance IncVirtual; +static_assert(sizeof(int IncSingle::*) == kSingleDataSize, ""); +static_assert(sizeof(int IncMultiple::*) == kMultipleDataSize, ""); +static_assert(sizeof(int IncVirtual::*) == kVirtualDataSize, ""); +static_assert(sizeof(void (IncSingle::*)()) == kSingleFunctionSize, ""); +static_assert(sizeof(void (IncMultiple::*)()) == kMultipleFunctionSize, ""); +static_assert(sizeof(void (IncVirtual::*)()) == kVirtualFunctionSize, ""); + +// An incomplete type with an unspecified inheritance model seems to take one +// more slot than virtual. It's not clear what it's used for yet. +class IncUnspecified; +static_assert(sizeof(int IncUnspecified::*) == kUnspecifiedDataSize, ""); +static_assert(sizeof(void (IncUnspecified::*)()) == kUnspecifiedFunctionSize, ""); + +// complete types +struct B1 { }; +struct B2 { }; +struct Single { }; +struct Multiple : B1, B2 { }; +struct Virtual : virtual B1 { }; +static_assert(sizeof(int Single::*) == kSingleDataSize, ""); +static_assert(sizeof(int Multiple::*) == kMultipleDataSize, ""); +static_assert(sizeof(int Virtual::*) == kVirtualDataSize, ""); +static_assert(sizeof(void (Single::*)()) == kSingleFunctionSize, ""); +static_assert(sizeof(void (Multiple::*)()) == kMultipleFunctionSize, ""); +static_assert(sizeof(void (Virtual::*)()) == kVirtualFunctionSize, ""); + +// Test both declared and defined templates. +template <typename T> class X; +template <> class __single_inheritance X<IncSingle>; +template <> class __multiple_inheritance X<IncMultiple>; +template <> class __virtual_inheritance X<IncVirtual>; +// Don't declare X<IncUnspecified>. +static_assert(sizeof(int X<IncSingle>::*) == kSingleDataSize, ""); +static_assert(sizeof(int X<IncMultiple>::*) == kMultipleDataSize, ""); +static_assert(sizeof(int X<IncVirtual>::*) == kVirtualDataSize, ""); +static_assert(sizeof(int X<IncUnspecified>::*) == kUnspecifiedDataSize, ""); +static_assert(sizeof(void (X<IncSingle>::*)()) == kSingleFunctionSize, ""); +static_assert(sizeof(void (X<IncMultiple>::*)()) == kMultipleFunctionSize, ""); +static_assert(sizeof(void (X<IncVirtual>::*)()) == kVirtualFunctionSize, ""); +static_assert(sizeof(void (X<IncUnspecified>::*)()) == kUnspecifiedFunctionSize, ""); + +template <typename T> +struct Y : T { }; +static_assert(sizeof(int Y<Single>::*) == kSingleDataSize, ""); +static_assert(sizeof(int Y<Multiple>::*) == kMultipleDataSize, ""); +static_assert(sizeof(int Y<Virtual>::*) == kVirtualDataSize, ""); +static_assert(sizeof(void (Y<Single>::*)()) == kSingleFunctionSize, ""); +static_assert(sizeof(void (Y<Multiple>::*)()) == kMultipleFunctionSize, ""); +static_assert(sizeof(void (Y<Virtual>::*)()) == kVirtualFunctionSize, ""); + +struct A { int x; void bar(); }; +struct B : A { virtual void foo(); }; +static_assert(sizeof(int B::*) == kSingleDataSize, ""); +// A non-primary base class uses the multiple inheritance model for member +// pointers. +static_assert(sizeof(void (B::*)()) == kMultipleFunctionSize, ""); + +struct AA { int x; virtual void foo(); }; +struct BB : AA { void bar(); }; +struct CC : BB { virtual void baz(); }; +static_assert(sizeof(void (CC::*)()) == kSingleFunctionSize, ""); + +// We start out unspecified. +struct ForwardDecl1; +struct ForwardDecl2; + +// Re-declare to force us to iterate decls when adding attributes. +struct ForwardDecl1; +struct ForwardDecl2; + +typedef int ForwardDecl1::*MemPtr1; +typedef int ForwardDecl2::*MemPtr2; +MemPtr1 variable_forces_sizing; + +struct ForwardDecl1 : B { + virtual void foo(); +}; +struct ForwardDecl2 : B { + virtual void foo(); +}; + +static_assert(sizeof(variable_forces_sizing) == kUnspecifiedDataSize, ""); +static_assert(sizeof(MemPtr1) == kUnspecifiedDataSize, ""); +// FIXME: Clang fails this assert because it locks in the inheritance model at +// the point of the typedef instead of the first usage, while MSVC does not. +//static_assert(sizeof(MemPtr2) == kSingleDataSize, ""); + +struct MemPtrInBody { + typedef int MemPtrInBody::*MemPtr; + int a; + operator MemPtr() const { + return a ? &MemPtrInBody::a : 0; + } +}; + +static_assert(sizeof(MemPtrInBody::MemPtr) == kSingleDataSize, ""); + +// Passing a member pointer through a template should get the right size. +template<typename T> +struct SingleTemplate; +template<typename T> +struct SingleTemplate<void (T::*)(void)> { + static_assert(sizeof(int T::*) == kSingleDataSize, ""); + static_assert(sizeof(void (T::*)()) == kSingleFunctionSize, ""); +}; + +template<typename T> +struct UnspecTemplate; +template<typename T> +struct UnspecTemplate<void (T::*)(void)> { + static_assert(sizeof(int T::*) == kUnspecifiedDataSize, ""); + static_assert(sizeof(void (T::*)()) == kUnspecifiedFunctionSize, ""); +}; + +struct NewUnspecified; +SingleTemplate<void (IncSingle::*)()> tmpl_single; +UnspecTemplate<void (NewUnspecified::*)()> tmpl_unspec; + +struct NewUnspecified { }; + +static_assert(sizeof(void (NewUnspecified::*)()) == kUnspecifiedFunctionSize, ""); + +template <typename T> +struct MemPtrInTemplate { + // We can't require that the template arg be complete until we're + // instantiated. + int T::*data_ptr; + void (T::*func_ptr)(); +}; diff --git a/test/SemaCXX/pascal-strings.cpp b/test/SemaCXX/pascal-strings.cpp index 89194b54aa..f4c692db58 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/return.cpp b/test/SemaCXX/return.cpp index 2f98a277f6..580f0a7233 100644 --- a/test/SemaCXX/return.cpp +++ b/test/SemaCXX/return.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -Wignored-qualifiers -verify +// RUN: %clang_cc1 %s -std=c++11 -fcxx-exceptions -fexceptions -fsyntax-only -Wignored-qualifiers -verify int test1() { throw; @@ -45,6 +45,27 @@ const j(); const volatile int scalar_cv(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}} + +// FIXME: Maintain enough information that we can point the diagnostic at the 'volatile' keyword. +const +int S::* +volatile +mixed_ret(); // expected-warning {{'volatile' type qualifier on return type has no effect}} + +const int volatile // expected-warning {{'const volatile' type qualifiers on return type have no effect}} + (((parens()))); + +_Atomic(int) atomic(); + +_Atomic // expected-warning {{'_Atomic' type qualifier on return type has no effect}} + int + atomic(); + +auto + trailing_return_type() -> // expected-warning {{'const' type qualifier on return type has no effect}} + const int; + +const int ret_array()[4]; // expected-error {{cannot return array}} } namespace PR9328 { @@ -56,6 +77,7 @@ namespace PR9328 { } class foo { + operator const int (); operator int * const (); }; diff --git a/test/SemaCXX/storage-class.cpp b/test/SemaCXX/storage-class.cpp index 01cfbfc51f..74121843e5 100644 --- a/test/SemaCXX/storage-class.cpp +++ b/test/SemaCXX/storage-class.cpp @@ -3,5 +3,5 @@ extern const int PR6495a = 42; extern int PR6495b = 42; // expected-warning{{'extern' variable has an initializer}} extern const int PR6495c[] = {42,43,44}; -extern struct Test1 {}; // expected-warning {{'extern' ignored on this declaration}} +extern struct Test1 {}; // expected-warning {{'extern' is not permitted on a declaration of a type}} extern "C" struct Test0 {}; // no warning diff --git a/test/SemaCXX/switch-implicit-fallthrough.cpp b/test/SemaCXX/switch-implicit-fallthrough.cpp index 0f7891dc53..d7959238c6 100644 --- a/test/SemaCXX/switch-implicit-fallthrough.cpp +++ b/test/SemaCXX/switch-implicit-fallthrough.cpp @@ -247,3 +247,21 @@ int fallthrough_targets(int n) { } return n; } + +// Fallthrough annotations in local classes used to generate "fallthrough +// annotation does not directly precede switch label" warning. +void fallthrough_in_local_class() { + class C { + void f(int x) { + switch (x) { + case 0: + x++; + [[clang::fallthrough]]; // no diagnostics + case 1: + x++; + break; + } + } + }; +} + diff --git a/test/SemaCXX/trailing-return-0x.cpp b/test/SemaCXX/trailing-return-0x.cpp index 462b4fa3da..bd601db2ac 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/type-traits.cpp b/test/SemaCXX/type-traits.cpp index 4b6c44d257..aa18ff4e67 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -39,9 +39,34 @@ struct DerivesEmpty : Empty {}; struct HasCons { HasCons(int); }; struct HasCopyAssign { HasCopyAssign operator =(const HasCopyAssign&); }; struct HasMoveAssign { HasMoveAssign operator =(const HasMoveAssign&&); }; +struct HasNoThrowMoveAssign { + HasNoThrowMoveAssign& operator=( + const HasNoThrowMoveAssign&&) throw(); }; +struct HasNoExceptNoThrowMoveAssign { + HasNoExceptNoThrowMoveAssign& operator=( + const HasNoExceptNoThrowMoveAssign&&) noexcept; +}; +struct HasThrowMoveAssign { + HasThrowMoveAssign& operator=( + const HasThrowMoveAssign&&) throw(POD); }; +struct HasNoExceptFalseMoveAssign { + HasNoExceptFalseMoveAssign& operator=( + const HasNoExceptFalseMoveAssign&&) noexcept(false); }; +struct HasMoveCtor { HasMoveCtor(const HasMoveCtor&&); }; +struct HasMemberMoveCtor { HasMoveCtor member; }; +struct HasMemberMoveAssign { HasMoveAssign member; }; +struct HasStaticMemberMoveCtor { static HasMoveCtor member; }; +struct HasStaticMemberMoveAssign { static HasMoveAssign member; }; +struct HasMemberThrowMoveAssign { HasThrowMoveAssign member; }; +struct HasMemberNoExceptFalseMoveAssign { + HasNoExceptFalseMoveAssign member; }; +struct HasMemberNoThrowMoveAssign { HasNoThrowMoveAssign member; }; +struct HasMemberNoExceptNoThrowMoveAssign { + HasNoExceptNoThrowMoveAssign member; }; + struct HasDefaultTrivialCopyAssign { - HasDefaultTrivialCopyAssign &operator =(const HasDefaultTrivialCopyAssign&) - = default; + HasDefaultTrivialCopyAssign &operator=( + const HasDefaultTrivialCopyAssign&) = default; }; struct TrivialMoveButNotCopy { TrivialMoveButNotCopy &operator=(TrivialMoveButNotCopy&&) = default; @@ -69,6 +94,7 @@ struct DerivesHasPriv : HasPriv {}; struct DerivesHasProt : HasProt {}; struct DerivesHasRef : HasRef {}; struct DerivesHasVirt : HasVirt {}; +struct DerivesHasMoveCtor : HasMoveCtor {}; struct HasNoThrowCopyAssign { void operator =(const HasNoThrowCopyAssign&) throw(); @@ -165,7 +191,7 @@ typedef Empty EmptyAr[10]; struct Bit0 { int : 0; }; struct Bit0Cons { int : 0; Bit0Cons(); }; struct BitOnly { int x : 3; }; -//struct DerivesVirt : virtual POD {}; +struct DerivesVirt : virtual POD {}; void is_empty() { @@ -941,6 +967,19 @@ struct AllDefaulted { ~AllDefaulted() = default; }; +struct NoDefaultMoveAssignDueToUDCopyCtor { + NoDefaultMoveAssignDueToUDCopyCtor(const NoDefaultMoveAssignDueToUDCopyCtor&); +}; + +struct NoDefaultMoveAssignDueToUDCopyAssign { + NoDefaultMoveAssignDueToUDCopyAssign& operator=( + const NoDefaultMoveAssignDueToUDCopyAssign&); +}; + +struct NoDefaultMoveAssignDueToDtor { + ~NoDefaultMoveAssignDueToDtor(); +}; + struct AllDeleted { AllDeleted() = delete; AllDeleted(const AllDeleted &) = delete; @@ -1203,6 +1242,32 @@ void has_trivial_default_constructor() { { int arr[F(__has_trivial_constructor(ExtDefaulted))]; } } +void has_trivial_move_constructor() { + // n3376 12.8 [class.copy]/12 + // A copy/move constructor for class X is trivial if it is not + // user-provided, its declared parameter type is the same as + // if it had been implicitly declared, and if + // — class X has no virtual functions (10.3) and no virtual + // base classes (10.1), and + // — the constructor selected to copy/move each direct base + // class subobject is trivial, and + // — for each non-static data member of X that is of class + // type (or array thereof), the constructor selected + // to copy/move that member is trivial; + // otherwise the copy/move constructor is non-trivial. + { int arr[T(__has_trivial_move_constructor(POD))]; } + { int arr[T(__has_trivial_move_constructor(Union))]; } + { int arr[T(__has_trivial_move_constructor(HasCons))]; } + { int arr[T(__has_trivial_move_constructor(HasStaticMemberMoveCtor))]; } + { int arr[T(__has_trivial_move_constructor(AllDeleted))]; } + + { int arr[F(__has_trivial_move_constructor(HasVirt))]; } + { int arr[F(__has_trivial_move_constructor(DerivesVirt))]; } + { int arr[F(__has_trivial_move_constructor(HasMoveCtor))]; } + { int arr[F(__has_trivial_move_constructor(DerivesHasMoveCtor))]; } + { int arr[F(__has_trivial_move_constructor(HasMemberMoveCtor))]; } +} + void has_trivial_copy_constructor() { { int arr[T(__has_trivial_copy(Int))]; } { int arr[T(__has_trivial_copy(IntAr))]; } @@ -1355,6 +1420,54 @@ void has_nothrow_assign() { { int arr[F(__has_nothrow_assign(PR11110))]; } } +void has_nothrow_move_assign() { + { int arr[T(__has_nothrow_move_assign(Int))]; } + { int arr[T(__has_nothrow_move_assign(Enum))]; } + { int arr[T(__has_nothrow_move_assign(Int*))]; } + { int arr[T(__has_nothrow_move_assign(Enum POD::*))]; } + { int arr[T(__has_nothrow_move_assign(POD))]; } + { int arr[T(__has_nothrow_move_assign(HasPriv))]; } + { int arr[T(__has_nothrow_move_assign(HasNoThrowMoveAssign))]; } + { int arr[T(__has_nothrow_move_assign(HasNoExceptNoThrowMoveAssign))]; } + { int arr[T(__has_nothrow_move_assign(HasMemberNoThrowMoveAssign))]; } + { int arr[T(__has_nothrow_move_assign(HasMemberNoExceptNoThrowMoveAssign))]; } + { int arr[T(__has_nothrow_move_assign(AllDeleted))]; } + + + { int arr[F(__has_nothrow_move_assign(HasThrowMoveAssign))]; } + { int arr[F(__has_nothrow_move_assign(HasNoExceptFalseMoveAssign))]; } + { int arr[F(__has_nothrow_move_assign(HasMemberThrowMoveAssign))]; } + { int arr[F(__has_nothrow_move_assign(HasMemberNoExceptFalseMoveAssign))]; } + { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyCtor))]; } + { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyAssign))]; } + { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToDtor))]; } +} + +void has_trivial_move_assign() { + // n3376 12.8 [class.copy]/25 + // A copy/move assignment operator for class X is trivial if it + // is not user-provided, its declared parameter type is the same + // as if it had been implicitly declared, and if: + // — class X has no virtual functions (10.3) and no virtual base + // classes (10.1), and + // — the assignment operator selected to copy/move each direct + // base class subobject is trivial, and + // — for each non-static data member of X that is of class type + // (or array thereof), the assignment operator + // selected to copy/move that member is trivial; + { int arr[T(__has_trivial_move_assign(Int))]; } + { int arr[T(__has_trivial_move_assign(HasStaticMemberMoveAssign))]; } + { int arr[T(__has_trivial_move_assign(AllDeleted))]; } + + { int arr[F(__has_trivial_move_assign(HasVirt))]; } + { int arr[F(__has_trivial_move_assign(DerivesVirt))]; } + { int arr[F(__has_trivial_move_assign(HasMoveAssign))]; } + { int arr[F(__has_trivial_move_assign(DerivesHasMoveAssign))]; } + { int arr[F(__has_trivial_move_assign(HasMemberMoveAssign))]; } + { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyCtor))]; } + { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyAssign))]; } +} + void has_nothrow_copy() { { int arr[T(__has_nothrow_copy(Int))]; } { int arr[T(__has_nothrow_copy(IntAr))]; } diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp index 4a3f0f6b29..caa6355fe9 100644 --- a/test/SemaCXX/typo-correction.cpp +++ b/test/SemaCXX/typo-correction.cpp @@ -250,3 +250,13 @@ void f(B &x) { x.Createfoo(0,0); // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}} } } + +struct DataStruct {void foo();}; +struct T { + DataStruct data_struct; + void f(); +}; +// should be void T::f(); +void f() { + data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'$}} +} diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp index 839fdafb34..1b76a86dcb 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 3a41114e87..665cfe7e91 100644 --- a/test/SemaCXX/uninitialized.cpp +++ b/test/SemaCXX/uninitialized.cpp @@ -496,3 +496,30 @@ namespace references { int &b; }; } + +namespace operators { + struct A { + A(bool); + bool operator==(A); + }; + + A makeA(); + + A a1 = a1 = makeA(); // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}} + A a2 = a2 == a1; // expected-warning{{variable 'a2' is uninitialized when used within its own initialization}} + A a3 = a2 == a3; // expected-warning{{variable 'a3' is uninitialized when used within its own initialization}} + + 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 8f35171119..bf8612aa39 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-enum-compare.cpp b/test/SemaCXX/warn-enum-compare.cpp index c68275e1a7..0c287948cd 100644 --- a/test/SemaCXX/warn-enum-compare.cpp +++ b/test/SemaCXX/warn-enum-compare.cpp @@ -39,8 +39,8 @@ void test () { while (b == c); while (B1 == name1::B2); while (B2 == name2::B1); - while (x == AnonAA); // expected-warning {{comparison of constant 42 with expression of type 'Foo' is always false}} - while (AnonBB == y); // expected-warning {{comparison of constant 45 with expression of type 'Bar' is always false}} + while (x == AnonAA); // expected-warning {{comparison of constant 'AnonAA' (42) with expression of type 'Foo' is always false}} + while (AnonBB == y); // expected-warning {{comparison of constant 'AnonBB' (45) with expression of type 'Bar' is always false}} while (AnonAA == AnonAB); while (AnonAB == AnonBA); while (AnonBB == AnonAA); diff --git a/test/SemaCXX/warn-overloaded-virtual.cpp b/test/SemaCXX/warn-overloaded-virtual.cpp index 9b0f5aa9f3..629d59dee5 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-reinterpret-base-class.cpp b/test/SemaCXX/warn-reinterpret-base-class.cpp new file mode 100644 index 0000000000..67902f7a90 --- /dev/null +++ b/test/SemaCXX/warn-reinterpret-base-class.cpp @@ -0,0 +1,323 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s + +// PR 13824 +class A { +}; +class DA : public A { +}; +class DDA : public DA { +}; +class DAo : protected A { +}; +class DAi : private A { +}; + +class DVA : public virtual A { +}; +class DDVA : public virtual DA { +}; +class DMA : public virtual A, public virtual DA { +}; + +class B; + +struct C { + // Do not fail on incompletely-defined classes. + decltype(reinterpret_cast<C *>(0)) foo; + decltype(reinterpret_cast<A *>((C *) 0)) bar; + decltype(reinterpret_cast<C *>((A *) 0)) baz; +}; + +void reinterpret_not_defined_class(B *b, C *c) { + // Should not fail if class has no definition. + (void)*reinterpret_cast<C *>(b); + (void)*reinterpret_cast<B *>(c); + + (void)reinterpret_cast<C &>(*b); + (void)reinterpret_cast<B &>(*c); +} + +// Do not fail on erroneous classes with fields of incompletely-defined types. +// Base class is malformed. +namespace BaseMalformed { + struct A; // expected-note {{forward declaration of 'BaseMalformed::A'}} + struct B { + A a; // expected-error {{field has incomplete type 'BaseMalformed::A'}} + }; + struct C : public B {} c; + B *b = reinterpret_cast<B *>(&c); +} // end anonymous namespace + +// Child class is malformed. +namespace ChildMalformed { + struct A; // expected-note {{forward declaration of 'ChildMalformed::A'}} + struct B {}; + struct C : public B { + A a; // expected-error {{field has incomplete type 'ChildMalformed::A'}} + } c; + B *b = reinterpret_cast<B *>(&c); +} // end anonymous namespace + +// Base class outside upcast base-chain is malformed. +namespace BaseBaseMalformed { + struct A; // expected-note {{forward declaration of 'BaseBaseMalformed::A'}} + struct Y {}; + struct X { A a; }; // expected-error {{field has incomplete type 'BaseBaseMalformed::A'}} + struct B : Y, X {}; + struct C : B {} c; + B *p = reinterpret_cast<B*>(&c); +} + +namespace InheritanceMalformed { + struct A; // expected-note {{forward declaration of 'InheritanceMalformed::A'}} + struct B : A {}; // expected-error {{base class has incomplete type}} + struct C : B {} c; + B *p = reinterpret_cast<B*>(&c); +} + +// Virtual base class outside upcast base-chain is malformed. +namespace VBaseMalformed{ + struct A; // expected-note {{forward declaration of 'VBaseMalformed::A'}} + struct X { A a; }; // expected-error {{field has incomplete type 'VBaseMalformed::A'}} + struct B : public virtual X {}; + struct C : B {} c; + B *p = reinterpret_cast<B*>(&c); +} + +void reinterpret_not_updowncast(A *pa, const A *pca, A &a, const A &ca) { + (void)*reinterpret_cast<C *>(pa); + (void)*reinterpret_cast<const C *>(pa); + (void)*reinterpret_cast<volatile C *>(pa); + (void)*reinterpret_cast<const volatile C *>(pa); + + (void)*reinterpret_cast<const C *>(pca); + (void)*reinterpret_cast<const volatile C *>(pca); + + (void)reinterpret_cast<C &>(a); + (void)reinterpret_cast<const C &>(a); + (void)reinterpret_cast<volatile C &>(a); + (void)reinterpret_cast<const volatile C &>(a); + + (void)reinterpret_cast<const C &>(ca); + (void)reinterpret_cast<const volatile C &>(ca); +} + +void reinterpret_pointer_downcast(A *a, const A *ca) { + (void)*reinterpret_cast<DA *>(a); + (void)*reinterpret_cast<const DA *>(a); + (void)*reinterpret_cast<volatile DA *>(a); + (void)*reinterpret_cast<const volatile DA *>(a); + + (void)*reinterpret_cast<const DA *>(ca); + (void)*reinterpret_cast<const volatile DA *>(ca); + + (void)*reinterpret_cast<DDA *>(a); + (void)*reinterpret_cast<DAo *>(a); + (void)*reinterpret_cast<DAi *>(a); + // expected-warning@+2 {{'reinterpret_cast' to class 'DVA *' from its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)*reinterpret_cast<DVA *>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA *' from its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)*reinterpret_cast<DDVA *>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' to class 'DMA *' from its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)*reinterpret_cast<DMA *>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" +} + +void reinterpret_reference_downcast(A a, A &ra, const A &cra) { + (void)reinterpret_cast<DA &>(a); + (void)reinterpret_cast<const DA &>(a); + (void)reinterpret_cast<volatile DA &>(a); + (void)reinterpret_cast<const volatile DA &>(a); + + (void)reinterpret_cast<DA &>(ra); + (void)reinterpret_cast<const DA &>(ra); + (void)reinterpret_cast<volatile DA &>(ra); + (void)reinterpret_cast<const volatile DA &>(ra); + + (void)reinterpret_cast<const DA &>(cra); + (void)reinterpret_cast<const volatile DA &>(cra); + + (void)reinterpret_cast<DDA &>(a); + (void)reinterpret_cast<DAo &>(a); + (void)reinterpret_cast<DAi &>(a); + // expected-warning@+2 {{'reinterpret_cast' to class 'DVA &' from its virtual base 'A' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<DVA &>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA &' from its virtual base 'A' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<DDVA &>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' to class 'DMA &' from its virtual base 'A' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<DMA &>(a); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" +} + +void reinterpret_pointer_upcast(DA *da, const DA *cda, DDA *dda, DAo *dao, + DAi *dai, DVA *dva, DDVA *ddva, DMA *dma) { + (void)*reinterpret_cast<A *>(da); + (void)*reinterpret_cast<const A *>(da); + (void)*reinterpret_cast<volatile A *>(da); + (void)*reinterpret_cast<const volatile A *>(da); + + (void)*reinterpret_cast<const A *>(cda); + (void)*reinterpret_cast<const volatile A *>(cda); + + (void)*reinterpret_cast<A *>(dda); + (void)*reinterpret_cast<DA *>(dda); + (void)*reinterpret_cast<A *>(dao); + (void)*reinterpret_cast<A *>(dai); + // expected-warning@+2 {{'reinterpret_cast' from class 'DVA *' to its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)*reinterpret_cast<A *>(dva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)*reinterpret_cast<A *>(ddva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'DA *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)*reinterpret_cast<DA *>(ddva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'A *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)*reinterpret_cast<A *>(dma); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'DA *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)*reinterpret_cast<DA *>(dma); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast" +} + +void reinterpret_reference_upcast(DA &da, const DA &cda, DDA &dda, DAo &dao, + DAi &dai, DVA &dva, DDVA &ddva, DMA &dma) { + (void)reinterpret_cast<A &>(da); + (void)reinterpret_cast<const A &>(da); + (void)reinterpret_cast<volatile A &>(da); + (void)reinterpret_cast<const volatile A &>(da); + + (void)reinterpret_cast<const A &>(cda); + (void)reinterpret_cast<const volatile A &>(cda); + + (void)reinterpret_cast<A &>(dda); + (void)reinterpret_cast<DA &>(dda); + (void)reinterpret_cast<A &>(dao); + (void)reinterpret_cast<A &>(dai); + // expected-warning@+2 {{'reinterpret_cast' from class 'DVA' to its virtual base 'A &' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<A &>(dva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'A &' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<A &>(ddva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'DA &' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<DA &>(ddva); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'A &' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<A &>(dma); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'DA &' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<DA &>(dma); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" +} + +struct E { + int x; +}; + +class F : public E { + virtual int foo() { return x; } +}; + +class G : public F { +}; + +class H : public E, public A { +}; + +class I : virtual public F { +}; + +typedef const F * K; +typedef volatile K L; + +void different_subobject_downcast(E *e, F *f, A *a) { + // expected-warning@+2 {{'reinterpret_cast' to class 'F *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<F *>(e); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' to class 'G *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<G *>(e); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + (void)reinterpret_cast<H *>(e); + // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<I *>(e); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + + (void)reinterpret_cast<G *>(f); + // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'F *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<I *>(f); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + (void)reinterpret_cast<H *>(a); + + // expected-warning@+2 {{'reinterpret_cast' to class 'L' (aka 'const F *volatile') from its base at non-zero offset 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} + (void)reinterpret_cast<L>(e); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" +} + +void different_subobject_upcast(F *f, G *g, H *h, I *i) { + // expected-warning@+2 {{'reinterpret_cast' from class 'F *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<E *>(f); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + (void)reinterpret_cast<F *>(g); + // expected-warning@+2 {{'reinterpret_cast' from class 'G *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<E *>(g); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + (void)reinterpret_cast<E *>(h); + (void)reinterpret_cast<A *>(h); + + // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'F *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<F *>(i); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" + + // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'E *' behaves differently from 'static_cast'}} + // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}} + (void)reinterpret_cast<E *>(i); + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast" +} diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp index 3f41124d47..bc4b40ead7 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 e12668bf2a..9fb601130d 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 0000000000..6386c4b682 --- /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 4e8d51d319..00597f929b 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 e652bee82d..b5d9002130 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 3443bda99b..d9392ed73f 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 b140c64da7..b9b5cc516d 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 d89d035fca..1d4e42de64 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 bf7ef19bea..fddcd506d4 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/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m index c0aa9fc070..aa4b479e00 100644 --- a/test/SemaObjC/attr-deprecated.m +++ b/test/SemaObjC/attr-deprecated.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s @interface A { int X __attribute__((deprecated)); // expected-note 2 {{declared here}} @@ -135,3 +136,21 @@ typedef struct { @property footype c; // expected-warning {{'footype' is deprecated}} @property footype d __attribute((deprecated)); @end + +// rdar://13569424 +@interface NewI ++(void)cmeth; +@end + +typedef NewI DeprI __attribute__((deprecated("blah"))); // expected-note 4 {{'DeprI' declared here}} + +@interface SI : DeprI // expected-warning {{'DeprI' is deprecated: blah}} +-(DeprI*)meth; // expected-warning {{'DeprI' is deprecated: blah}} +@end + +@implementation SI +-(DeprI*)meth { // expected-warning {{'DeprI' is deprecated: blah}} + [DeprI cmeth]; // expected-warning {{'DeprI' is deprecated: blah}} + return 0; +} +@end diff --git a/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m index dd659addef..b523e4c916 100644 --- a/test/SemaObjC/blocks.m +++ b/test/SemaObjC/blocks.m @@ -196,8 +196,8 @@ typedef short (^short_block_t)(); void testAnonymousEnumTypes(int arg) { int_block_t IB; IB = ^{ return AnonymousValue; }; - IB = ^{ if (arg) return TDE_Value; else return getTDE(); }; // expected-error {{incompatible block pointer}} - IB = ^{ if (arg) return getTDE(); else return TDE_Value; }; // expected-error {{incompatible block pointer}} + IB = ^{ if (arg) return TDE_Value; else return getTDE(); }; + IB = ^{ if (arg) return getTDE(); else return TDE_Value; }; // Since we fixed the underlying type of the enum, these are considered // compatible block types anyway. diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m index a7e69651ad..18b872aa8b 100644 --- a/test/SemaObjC/category-1.m +++ b/test/SemaObjC/category-1.m @@ -71,8 +71,7 @@ @interface MultipleCat_I() <MultipleCat_P> @end -@implementation MultipleCat_I // expected-warning {{incomplete implementation}} \ - // expected-warning {{method 'im0' in protocol not implemented}} +@implementation MultipleCat_I // expected-warning {{method 'im0' in protocol not implemented}} @end // <rdar://problem/7680391> - Handle nameless categories with no name that refer diff --git a/test/SemaObjC/compare-qualified-id.m b/test/SemaObjC/compare-qualified-id.m index d31dfae86e..82868f8a16 100644 --- a/test/SemaObjC/compare-qualified-id.m +++ b/test/SemaObjC/compare-qualified-id.m @@ -23,8 +23,7 @@ extern NSString * const NSTaskDidTerminateNotification; - (NSString *)evaluateAsStringInContext:(XCPropertyExpansionContext *)context withNestingState:(const void *)state; @end -@implementation XCPropertyExpansionContext // expected-warning {{incomplete implementation}} \ - // expected-warning {{method 'copyWithZone:' in protocol not implemented}} +@implementation XCPropertyExpansionContext // expected-warning {{method 'copyWithZone:' in protocol not implemented}} - (NSString *)expandedValueForProperty:(NSString *)property { id <XCPropertyValues> cachedValueNode = [_propNamesToPropValuesCache objectForKey:property]; // expected-warning {{method '-objectForKey:' not found (return type defaults to 'id')}} if (cachedValueNode == ((void *)0)) { } diff --git a/test/SemaObjC/conditional-expr.m b/test/SemaObjC/conditional-expr.m index e0a3210deb..ec1305dbe8 100644 --- a/test/SemaObjC/conditional-expr.m +++ b/test/SemaObjC/conditional-expr.m @@ -21,10 +21,10 @@ @end @interface DTFilterOutputStream2 -- nextOutputStream; // expected-note {{method definition for 'nextOutputStream' not found}} +- nextOutputStream; // expected-note {{method 'nextOutputStream' declared here}} @end -@implementation DTFilterOutputStream2 // expected-warning {{incomplete implementation}} +@implementation DTFilterOutputStream2 // expected-warning {{method definition for 'nextOutputStream' not found}} - (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream { id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; self = nextOutputStream; // expected-warning {{assigning to 'DTFilterOutputStream2 *' from incompatible type 'id<DTOutputStreams>'}} diff --git a/test/SemaObjC/default-synthesize-3.m b/test/SemaObjC/default-synthesize-3.m index 606ece33af..82f968da00 100644 --- a/test/SemaObjC/default-synthesize-3.m +++ b/test/SemaObjC/default-synthesize-3.m @@ -39,3 +39,75 @@ __attribute ((objc_requires_property_definitions)) __attribute ((objc_requires_property_definitions)) // expected-error {{objc_requires_property_definitions attribute may only be specified on a class}} @protocol P @end + +// rdar://13388503 +@interface NSObject @end +@protocol Foo +@property (readonly) char isFoo; // expected-note {{property declared here}} +@property (readonly) char isNotFree; +@end + +@interface Bar : NSObject <Foo> +@end + +@implementation Bar +- (char)isFoo { + return 0; +} +- (char)isNotFree { + return 0; +} +@end + +@interface Baz : Bar +@end + +@interface Baz () +@property (readwrite) char isFoo; // expected-warning {{auto property synthesis will not synthesize property 'isFoo' because it is 'readwrite' but it will be synthesized 'readonly' via another property}} +@property char Property1; // expected-warning {{auto property synthesis will not synthesize property 'Property1' because it cannot share an ivar with another synthesized property}} +@property char Property2; +@property (readwrite) char isNotFree; +@end + +@implementation Baz { + char _isFoo; + char _isNotFree; +} +@synthesize Property2 = Property1; // expected-note {{property synthesized here}} + +- (void) setIsNotFree : (char)Arg { + _isNotFree = Arg; +} + +@end + +// More test where such warnings should not be issued. +@protocol MyProtocol +-(void)setProp1:(id)x; +@end + +@protocol P1 <MyProtocol> +@end + +@interface B +@property (readonly) id prop; +@property (readonly) id prop1; +@property (readonly) id prop2; +@end + +@interface B() +-(void)setProp:(id)x; +@end + +@interface B(cat) +@property (readwrite) id prop2; +@end + +@interface S : B<P1> +@property (assign,readwrite) id prop; +@property (assign,readwrite) id prop1; +@property (assign,readwrite) id prop2; +@end + +@implementation S +@end diff --git a/test/SemaObjC/warn-isa-ref.m b/test/SemaObjC/deprecated-objc-introspection.m index 39a5e45496..faaef254d5 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; @@ -18,8 +24,8 @@ static void func() { id x; // rdar://8290002 - [(*x).isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_setClass() and object_getClass()}} - [x->isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_setClass() and object_getClass()}} + [(*x).isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} + [x->isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} Whatever *y; @@ -39,7 +45,7 @@ static void func() { @interface BaseClass { @public - Class isa; // expected-note 3 {{instance variable is declared here}} + Class isa; // expected-note 4 {{instance variable is declared here}} } @end @@ -70,12 +76,22 @@ static void func() { Subclass *x; SiblingClass *y; OtherClass *z; - (void)v->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}} - (void)w->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}} - (void)x->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}} - (void)y->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}} + (void)v->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} + (void)w->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} + (void)x->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} + (void)y->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} (void)z->isa; (void)u->isa; + + w->isa = 0; // expected-warning {{assignment to Objective-C's isa is deprecated in favor of object_setClass()}} } @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/enum-fixed-type.m b/test/SemaObjC/enum-fixed-type.m index 6fd400a637..c00e45a03e 100644 --- a/test/SemaObjC/enum-fixed-type.m +++ b/test/SemaObjC/enum-fixed-type.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s #if !__has_feature(objc_fixed_enum) # error Enumerations with a fixed underlying type are not supported @@ -28,9 +28,9 @@ void test() { // <rdar://10381507> typedef enum : long { Foo } IntegerEnum; -int arr[(sizeof(typeof(Foo)) == sizeof(typeof(IntegerEnum))) - 1]; -int arr1[(sizeof(typeof(Foo)) == sizeof(typeof(long))) - 1]; -int arr2[(sizeof(typeof(IntegerEnum)) == sizeof(typeof(long))) - 1]; +int arr[(sizeof(__typeof__(Foo)) == sizeof(__typeof__(IntegerEnum)))? 1 : -1]; +int arr1[(sizeof(__typeof__(Foo)) == sizeof(__typeof__(long)))? 1 : -1]; +int arr2[(sizeof(__typeof__(IntegerEnum)) == sizeof(__typeof__(long)))? 1 : -1]; // <rdar://problem/10760113> typedef enum : long long { Bar = -1 } LongLongEnum; diff --git a/test/SemaObjC/format-arg-attribute.m b/test/SemaObjC/format-arg-attribute.m index 6edb8fd99b..dede433f37 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 bd33ad41a5..8490130224 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/forward-protocol-incomplete-impl-warn.m b/test/SemaObjC/forward-protocol-incomplete-impl-warn.m index 1010cd75cd..01fedec3cf 100644 --- a/test/SemaObjC/forward-protocol-incomplete-impl-warn.m +++ b/test/SemaObjC/forward-protocol-incomplete-impl-warn.m @@ -16,6 +16,5 @@ @end @implementation IBImageCatalogDocument // expected-warning {{auto property synthesis will not synthesize property declared in a protocol}} \ - // expected-warning {{incomplete implementation}} \ // expected-warning {{method 'invalidate' in protocol not implemented}} @end diff --git a/test/SemaObjC/gcc-cast-ext.m b/test/SemaObjC/gcc-cast-ext.m index 30e0dce4bd..5858393b41 100644 --- a/test/SemaObjC/gcc-cast-ext.m +++ b/test/SemaObjC/gcc-cast-ext.m @@ -5,8 +5,8 @@ typedef struct _NSRange { } NSRange; @class PBXFileReference; @interface PBXDocBookmark -+ alloc; // expected-note {{method definition for 'alloc' not found}} -- autorelease; // expected-note {{method definition for 'autorelease' not found}} ++ alloc; // expected-note {{method 'alloc' declared here}} +- autorelease; // expected-note {{method 'autorelease' declared here}} @end // GCC allows pointer expressions in integer constant expressions. @@ -14,7 +14,8 @@ struct { char control[((int)(char *)2)]; } xx; -@implementation PBXDocBookmark // expected-warning {{incomplete implementation}} +@implementation PBXDocBookmark // expected-warning {{method definition for 'autorelease' not found}}\ + // expected-warning {{method definition for 'alloc' not found}} + (id)bookmarkWithFileReference:(PBXFileReference *)fileRef gylphRange:(NSRange)range anchor:(NSString *)htmlAnchor { diff --git a/test/SemaObjC/illegal-nonarc-bridged-cast.m b/test/SemaObjC/illegal-nonarc-bridged-cast.m index a5bb01ffe0..f3406ef983 100644 --- a/test/SemaObjC/illegal-nonarc-bridged-cast.m +++ b/test/SemaObjC/illegal-nonarc-bridged-cast.m @@ -18,17 +18,16 @@ NSString *CreateNSString(); void from_cf() { id obj1 = (__bridge_transfer id)CFCreateSomething(); // expected-warning {{'__bridge_transfer' casts have no effect when not using ARC}} id obj2 = (__bridge_transfer NSString*)CFCreateString(); // expected-warning {{'__bridge_transfer' casts have no effect when not using ARC}} - (__bridge int*)CFCreateSomething(); // expected-warning {{'__bridge' casts have no effect when not using ARC}} \ - // expected-warning {{expression result unused}} - id obj3 = (__bridge id)CFGetSomething(); // expected-warning {{'__bridge' casts have no effect when not using ARC}} - id obj4 = (__bridge NSString*)CFGetString(); // expected-warning {{'__bridge' casts have no effect when not using ARC}} + (__bridge int*)CFCreateSomething(); // expected-warning {{expression result unused}} + id obj3 = (__bridge id)CFGetSomething(); + id obj4 = (__bridge NSString*)CFGetString(); } void to_cf(id obj) { CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); // expected-warning {{'__bridge_retained' casts have no effect when not using ARC}} CFStringRef cf2 = (__bridge_retained CFStringRef)CreateNSString(); // expected-warning {{'__bridge_retained' casts have no effect when not using ARC}} - CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); // expected-warning {{'__bridge' casts have no effect when not using ARC}} - CFStringRef cf4 = (__bridge CFStringRef)CreateNSString(); // expected-warning {{'__bridge' casts have no effect when not using ARC}} + CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); + CFStringRef cf4 = (__bridge CFStringRef)CreateNSString(); } void fixits() { diff --git a/test/SemaObjC/incomplete-implementation.m b/test/SemaObjC/incomplete-implementation.m index 69e355cb9a..4b8d600cb8 100644 --- a/test/SemaObjC/incomplete-implementation.m +++ b/test/SemaObjC/incomplete-implementation.m @@ -1,13 +1,12 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -verify -Wno-objc-root-class %s @interface I -- Meth; // expected-note{{method definition for 'Meth' not found}} \ - // expected-note{{method 'Meth' declared here}} +- Meth; // expected-note 2 {{method 'Meth' declared here}} - unavailableMeth __attribute__((availability(macosx,unavailable))); - unavailableMeth2 __attribute__((unavailable)); @end -@implementation I // expected-warning{{incomplete implementation}} +@implementation I // expected-warning {{method definition for 'Meth' not found}} @end @implementation I(CAT) diff --git a/test/SemaObjC/instancetype.m b/test/SemaObjC/instancetype.m index 40f35d93b2..8137964737 100644 --- a/test/SemaObjC/instancetype.m +++ b/test/SemaObjC/instancetype.m @@ -5,9 +5,9 @@ #endif @interface Root -+ (instancetype)alloc; ++ (instancetype)alloc; // expected-note {{explicitly declared 'instancetype'}} - (instancetype)init; // expected-note{{overridden method is part of the 'init' method family}} -- (instancetype)self; +- (instancetype)self; // expected-note {{explicitly declared 'instancetype'}} - (Class)class; @property (assign) Root *selfProp; @@ -143,7 +143,7 @@ void test_instancetype_narrow_method_search() { @implementation Subclass4 + (id)alloc { - return self; // expected-warning{{incompatible pointer types casting 'Class' to type 'Subclass4 *'}} + return self; // expected-warning{{incompatible pointer types returning 'Class' from a function with result type 'Subclass4 *'}} } - (Subclass3 *)init { return 0; } // don't complain: we lost the related return type @@ -164,14 +164,14 @@ void test_instancetype_inherited() { // Check that related return types tighten up the semantics of // Objective-C method implementations. @implementation Subclass2 -- (instancetype)initSubclass2 { +- (instancetype)initSubclass2 { // expected-note {{explicitly declared 'instancetype'}} Subclass1 *sc1 = [[Subclass1 alloc] init]; - return sc1; // expected-warning{{incompatible pointer types casting 'Subclass1 *' to type 'Subclass2 *'}} + return sc1; // expected-warning{{incompatible pointer types returning 'Subclass1 *' from a function with result type 'Subclass2 *'}} } - (void)methodOnSubclass2 {} - (id)self { Subclass1 *sc1 = [[Subclass1 alloc] init]; - return sc1; // expected-warning{{incompatible pointer types casting 'Subclass1 *' to type 'Subclass2 *'}} + return sc1; // expected-warning{{incompatible pointer types returning 'Subclass1 *' from a function with result type 'Subclass2 *'}} } @end @@ -188,3 +188,29 @@ void test_instancetype_inherited() { @end +// rdar://12493140 +@protocol P4 +- (instancetype) foo; // expected-note {{current method is explicitly declared 'instancetype' and is expected to return an instance of its class type}} +@end +@interface A4 : Root <P4> +- (instancetype) bar; // expected-note {{current method is explicitly declared 'instancetype' and is expected to return an instance of its class type}} +- (instancetype) baz; // expected-note {{overridden method returns an instance of its class type}} expected-note {{previous definition is here}} +@end +@interface B4 : Root @end + +@implementation A4 { + B4 *_b; +} +- (id) foo { + return _b; // expected-warning {{incompatible pointer types returning 'B4 *' from a function with result type 'A4 *'}} +} +- (id) bar { + return _b; // expected-warning {{incompatible pointer types returning 'B4 *' from a function with result type 'A4 *'}} +} + +// This is really just to ensure that we don't crash. +// FIXME: only one diagnostic, please +- (float) baz { // expected-warning {{method is expected to return an instance of its class type 'A4', but is declared to return 'float'}} expected-warning {{conflicting return type in implementation}} + return 0; +} +@end diff --git a/test/SemaObjC/message.m b/test/SemaObjC/message.m index f43bdf9885..40fa102f35 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 df59f242ce..ec80a433cc 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/method-undef-category-warn-1.m b/test/SemaObjC/method-undef-category-warn-1.m index 2548cbd241..98d732babb 100644 --- a/test/SemaObjC/method-undef-category-warn-1.m +++ b/test/SemaObjC/method-undef-category-warn-1.m @@ -4,25 +4,25 @@ @end @protocol P -- (void) Pmeth; // expected-note {{method 'Pmeth' declared here}} -- (void) Pmeth1; // expected-note {{method 'Pmeth1' declared here}} +- (void) Pmeth; // expected-note {{method 'Pmeth' declared here}} +- (void) Pmeth1; // expected-note {{method 'Pmeth1' declared here}} @end @interface MyClass1(CAT) <P> // expected-note {{required for direct or indirect protocol 'P'}} -- (void) meth2; // expected-note {{method definition for 'meth2' not found}} +- (void) meth2; // expected-note {{method 'meth2' declared here}} @end -@implementation MyClass1(CAT) // expected-warning {{incomplete implementation}} \ - // expected-warning {{method 'Pmeth' in protocol not implemented}} +@implementation MyClass1(CAT) // expected-warning {{method 'Pmeth' in protocol not implemented}} \ + // expected-warning {{method definition for 'meth2' not found}} - (void) Pmeth1{} @end @interface MyClass1(DOG) <P> // expected-note {{required for direct or indirect protocol 'P'}} -- (void)ppp; // expected-note {{method definition for 'ppp' not found}} +- (void)ppp; // expected-note {{method 'ppp' declared here}} @end -@implementation MyClass1(DOG) // expected-warning {{incomplete implementation}} \ - // expected-warning {{method 'Pmeth1' in protocol not implemented}} +@implementation MyClass1(DOG) // expected-warning {{method 'Pmeth1' in protocol not implemented}} \ + // expected-warning {{method definition for 'ppp' not found}} - (void) Pmeth {} @end diff --git a/test/SemaObjC/method-undef-extension-warn-1.m b/test/SemaObjC/method-undef-extension-warn-1.m index c092f24828..fbc21bd39f 100644 --- a/test/SemaObjC/method-undef-extension-warn-1.m +++ b/test/SemaObjC/method-undef-extension-warn-1.m @@ -10,7 +10,7 @@ // Class extension @interface MyClass () <P> -- (void)meth2; // expected-note {{method definition for 'meth2' not found}} +- (void)meth2; // expected-note {{method 'meth2' declared here}} @end // Add a category to test that clang does not emit warning for this method. @@ -18,7 +18,7 @@ - (void)categoryMethod; @end -@implementation MyClass // expected-warning {{incomplete implementation}} \ - // expected-warning {{method 'Pmeth1' in protocol not implemented}} +@implementation MyClass // expected-warning {{method 'Pmeth1' in protocol not implemented}} \ + // expected-warning {{method definition for 'meth2' not found}} - (void)Pmeth {} @end diff --git a/test/SemaObjC/method-undefined-warn-1.m b/test/SemaObjC/method-undefined-warn-1.m index 27d645e73b..e22140d446 100644 --- a/test/SemaObjC/method-undefined-warn-1.m +++ b/test/SemaObjC/method-undefined-warn-1.m @@ -3,12 +3,14 @@ @interface INTF - (void) meth; - (void) meth : (int) arg1; -- (int) int_meth; // expected-note {{method definition for 'int_meth' not found}} -+ (int) cls_meth; // expected-note {{method definition for 'cls_meth' not found}} -+ (void) cls_meth1 : (int) arg1; // expected-note {{method definition for 'cls_meth1:' not found}} +- (int) int_meth; // expected-note {{method 'int_meth' declared here}} ++ (int) cls_meth; // expected-note {{method 'cls_meth' declared here}} ++ (void) cls_meth1 : (int) arg1; // expected-note {{method 'cls_meth1:' declared here}} @end -@implementation INTF // expected-warning {{incomplete implementation}} +@implementation INTF // expected-warning {{method definition for 'int_meth' not found}} \ + // expected-warning {{method definition for 'cls_meth' not found}} \ + // expected-warning {{method definition for 'cls_meth1:' not found}} - (void) meth {} - (void) meth : (int) arg2{} - (void) cls_meth1 : (int) arg2{} @@ -17,12 +19,14 @@ @interface INTF1 - (void) meth; - (void) meth : (int) arg1; -- (int) int_meth; // expected-note {{method definition for 'int_meth' not found}} -+ (int) cls_meth; // expected-note {{method definition for 'cls_meth' not found}} -+ (void) cls_meth1 : (int) arg1; // expected-note {{method definition for 'cls_meth1:' not found}} +- (int) int_meth; // expected-note {{method 'int_meth' declared here}} ++ (int) cls_meth; // expected-note {{method 'cls_meth' declared here}} ++ (void) cls_meth1 : (int) arg1; // expected-note {{method 'cls_meth1:' declared here}} @end -@implementation INTF1 // expected-warning {{incomplete implementation}} +@implementation INTF1 // expected-warning {{method definition for 'int_meth' not found}} \ + // expected-warning {{method definition for 'cls_meth' not found}} \ + // expected-warning {{method definition for 'cls_meth1:' not found}} - (void) meth {} - (void) meth : (int) arg2{} - (void) cls_meth1 : (int) arg2{} diff --git a/test/SemaObjC/no-protocol-option-tests.m b/test/SemaObjC/no-protocol-option-tests.m index dbd2a14e91..605cf9f1bf 100644 --- a/test/SemaObjC/no-protocol-option-tests.m +++ b/test/SemaObjC/no-protocol-option-tests.m @@ -17,9 +17,9 @@ // Test2 @interface super - PMeth; @end @interface J : super <P> -- PMeth; // expected-note {{method definition for 'PMeth' not found}} +- PMeth; // expected-note {{method 'PMeth' declared here}} @end -@implementation J @end // expected-warning {{incomplete implementation}} +@implementation J @end // expected-warning {{method definition for 'PMeth' not found}} // Test3 @interface K : super <P> diff --git a/test/SemaObjC/property-category-4.m b/test/SemaObjC/property-category-4.m index e7939b32c1..ccf5e9b2a8 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 be42deaf90..135b005761 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 aa7b764fab..7e10356ac5 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-in-class-extension.m b/test/SemaObjC/property-in-class-extension.m index a7b5130752..022a487ec6 100644 --- a/test/SemaObjC/property-in-class-extension.m +++ b/test/SemaObjC/property-in-class-extension.m @@ -37,11 +37,12 @@ void FUNC () { @interface rdar8747333 () - (NSObject *)bam; -- (NSObject *)warn; // expected-note {{method definition for 'warn' not found}} -- (void)setWarn : (NSObject *)val; // expected-note {{method definition for 'setWarn:' not found}} +- (NSObject *)warn; // expected-note {{method 'warn' declared here}} +- (void)setWarn : (NSObject *)val; // expected-note {{method 'setWarn:' declared here}} @end -@implementation rdar8747333 // expected-warning {{incomplete implementation}} +@implementation rdar8747333 // expected-warning {{method definition for 'warn' not found}} \ + // expected-warning {{method definition for 'setWarn:' not found}} @synthesize bar = _bar; @synthesize baz = _baz; @synthesize bam = _bam; diff --git a/test/SemaObjC/property-noninherited-availability-attr.m b/test/SemaObjC/property-noninherited-availability-attr.m new file mode 100644 index 0000000000..0c2a5d3853 --- /dev/null +++ b/test/SemaObjC/property-noninherited-availability-attr.m @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.8.0 -fsyntax-only -verify %s + +// This test case shows that 'availablity' and 'deprecated' does not inherit +// when a property is redeclared in a subclass. This is intentional. + +@interface NSObject @end +@protocol myProtocol +@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 +@property int myProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note {{'myProperty' declared here}} \ + // expected-note {{method 'myProperty' declared here}} \ + // expected-note {{property 'myProperty' is declared deprecated here}} +@end + +@interface Bar : Foo <myProtocol> +@property int myProperty; +@property int myProtocolProperty; +@end + +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]; // no-warning + + x.myProtocolProperty = 0; // no-warning + + [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 cda983c9ec..e84fad2394 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 76fdf5b242..7485447173 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 9e8ed8a627..90f6db0c84 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/related-result-type-inference.m b/test/SemaObjC/related-result-type-inference.m index b1d77dc172..50aaf2da4d 100644 --- a/test/SemaObjC/related-result-type-inference.m +++ b/test/SemaObjC/related-result-type-inference.m @@ -175,7 +175,7 @@ void test_inference() { @implementation Fail - (id<X>) initWithX { - return (id)self; // expected-warning {{returning 'Fail *' from a function with incompatible result type 'id<X>'}} + return (id)self; // expected-warning {{casting 'Fail *' to incompatible type 'id<X>'}} } @end diff --git a/test/SemaObjC/typo-correction.m b/test/SemaObjC/typo-correction.m new file mode 100644 index 0000000000..893e31294a --- /dev/null +++ b/test/SemaObjC/typo-correction.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only + +@interface B +@property int x; +@end + +@interface S : B +@end + +// Spell-checking 'undefined' is ok. +undefined var; // expected-error {{unknown type name}} + +typedef int super1; +@implementation S +-(void)foo { + // Spell-checking 'super' is not ok. + super.x = 0; + self.x = 0; +} +@end diff --git a/test/SemaObjC/undef-protocol-methods-1.m b/test/SemaObjC/undef-protocol-methods-1.m index 15ba1a1eb2..25b1dadb7c 100644 --- a/test/SemaObjC/undef-protocol-methods-1.m +++ b/test/SemaObjC/undef-protocol-methods-1.m @@ -28,10 +28,7 @@ // expected-note 2 {{required for direct or indirect protocol 'P2'}} @end -@implementation INTF // expected-warning {{incomplete implementation}} \ - // expected-warning 9 {{in protocol not implemented}} +@implementation INTF // expected-warning 9 {{in protocol not implemented}} - (void) DefP1proto{} - + (void) DefClsP3Proto{} - @end diff --git a/test/SemaObjC/warn-missing-super.m b/test/SemaObjC/warn-missing-super.m index 02b81651d7..e9769a9db1 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/SemaObjC/warning-missing-selector-name.m b/test/SemaObjC/warning-missing-selector-name.m index d43031eee0..a335e0266a 100644 --- a/test/SemaObjC/warning-missing-selector-name.m +++ b/test/SemaObjC/warning-missing-selector-name.m @@ -15,11 +15,11 @@ - method:(id) second:(id)second; // expected-warning {{'second' used as the name of the previous parameter rather than as part of the selector}} \ // expected-note {{introduce a parameter name to make 'second' part of the selector}} \ // expected-note {{or insert whitespace before ':' to use 'second' as parameter name and have an empty entry in the selector}} \ - // expected-note {{method definition for 'method::' not found}} + // expected-note {{method 'method::' declared here}} @end -@implementation INTF // expected-warning {{incomplete implementation}} +@implementation INTF // expected-warning {{method definition for 'method::' not found}} -(void) Name1:(id)Arg1 Name2:(id)Arg2{} -(void) Name1:(id) Name2:(id)Arg2 {} // expected-warning {{'Name2' used as the name of the previous parameter rather than as part of the selector}} \ // expected-note {{introduce a parameter name to make 'Name2' part of the selector}} \ diff --git a/test/SemaObjCXX/arc-system-header.mm b/test/SemaObjCXX/arc-system-header.mm index 107b5b5a53..3358e5fc12 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 3c4b908eab..d1302c19a5 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/instancetype.mm b/test/SemaObjCXX/instancetype.mm new file mode 100644 index 0000000000..bbf100ef04 --- /dev/null +++ b/test/SemaObjCXX/instancetype.mm @@ -0,0 +1,216 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#if !__has_feature(objc_instancetype) +# error Missing 'instancetype' feature macro. +#endif + +@interface Root ++ (instancetype)alloc; +- (instancetype)init; // expected-note{{overridden method is part of the 'init' method family}} +- (instancetype)self; // expected-note {{explicitly declared 'instancetype'}} +- (Class)class; + +@property (assign) Root *selfProp; +- (instancetype)selfProp; +@end + +@protocol Proto1 +@optional +- (instancetype)methodInProto1; +@end + +@protocol Proto2 +@optional +- (instancetype)methodInProto2; // expected-note{{overridden method returns an instance of its class type}} +- (instancetype)otherMethodInProto2; // expected-note{{overridden method returns an instance of its class type}} +@end + +@interface Subclass1 : Root +- (instancetype)initSubclass1; +- (void)methodOnSubclass1; ++ (instancetype)allocSubclass1; +@end + +@interface Subclass2 : Root +- (instancetype)initSubclass2; +- (void)methodOnSubclass2; +@end + +// Sanity check: the basic initialization pattern. +void test_instancetype_alloc_init_simple() { + Root *r1 = [[Root alloc] init]; + Subclass1 *sc1 = [[Subclass1 alloc] init]; +} + +// Test that message sends to instancetype methods have the right type. +void test_instancetype_narrow_method_search() { + // instancetype on class methods + Subclass1 *sc1 = [[Subclass1 alloc] initSubclass2]; // expected-warning{{'Subclass1' may not respond to 'initSubclass2'}} + Subclass2 *sc2 = [[Subclass2 alloc] initSubclass2]; // okay + + // instancetype on instance methods + [[[Subclass1 alloc] init] methodOnSubclass2]; // expected-warning{{'Subclass1' may not respond to 'methodOnSubclass2'}} + [[[Subclass2 alloc] init] methodOnSubclass2]; + + // instancetype on class methods using protocols + typedef Subclass1<Proto1> SC1Proto1; + typedef Subclass1<Proto2> SC1Proto2; + [[SC1Proto1 alloc] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} + [[SC1Proto2 alloc] methodInProto2]; + + // instancetype on instance methods + Subclass1<Proto1> *sc1proto1 = 0; + [[sc1proto1 self] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} + Subclass1<Proto2> *sc1proto2 = 0; + [[sc1proto2 self] methodInProto2]; + + // Exact type checks + typeof([[Subclass1 alloc] init]) *ptr1 = (Subclass1 **)0; + typeof([[Subclass2 alloc] init]) *ptr2 = (Subclass2 **)0; + + // Message sends to Class. + Subclass1<Proto1> *sc1proto1_2 = [[[sc1proto1 class] alloc] init]; + + // Property access + [sc1proto1.self methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} + [sc1proto2.self methodInProto2]; + [Subclass1.alloc initSubclass2]; // expected-warning{{'Subclass1' may not respond to 'initSubclass2'}} + [Subclass2.alloc initSubclass2]; + + [sc1proto1.selfProp methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} + [sc1proto2.selfProp methodInProto2]; +} + +// Test that message sends to super methods have the right type. +@interface Subsubclass1 : Subclass1 +- (instancetype)initSubclass1; ++ (instancetype)allocSubclass1; + +- (void)onlyInSubsubclass1; +@end + +@implementation Subsubclass1 +- (instancetype)initSubclass1 { + // Check based on method search. + [[super initSubclass1] methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}} + [super.initSubclass1 methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}} + + self = [super init]; // common pattern + + // Exact type check. + typeof([super initSubclass1]) *ptr1 = (Subsubclass1**)0; + + return self; +} + ++ (instancetype)allocSubclass1 { + // Check based on method search. + [[super allocSubclass1] methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}} + + // The ASTs don't model super property accesses well enough to get this right + [super.allocSubclass1 methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}} + + // Exact type check. + typeof([super allocSubclass1]) *ptr1 = (Subsubclass1**)0; + + return [super allocSubclass1]; +} + +- (void)onlyInSubsubclass1 {} +@end + +// Check compatibility rules for inheritance of related return types. +@class Subclass4; + +@interface Subclass3 <Proto1, Proto2> +- (Subclass3 *)methodInProto1; +- (Subclass4 *)methodInProto2; // expected-warning{{method is expected to return an instance of its class type 'Subclass3', but is declared to return 'Subclass4 *'}} +@end + +@interface Subclass4 : Root ++ (Subclass4 *)alloc; // okay +- (Subclass3 *)init; // expected-warning{{method is expected to return an instance of its class type 'Subclass4', but is declared to return 'Subclass3 *'}} +- (id)self; // expected-note{{overridden method is part of the 'self' method family}} +- (instancetype)initOther; +@end + +@protocol Proto3 <Proto1, Proto2> +@optional +- (id)methodInProto1; +- (Subclass1 *)methodInProto2; +- (int)otherMethodInProto2; // expected-warning{{protocol method is expected to return an instance of the implementing class, but is declared to return 'int'}} +@end + +@implementation Subclass4 ++ (id)alloc { + return self; // FIXME: we accept this in ObjC++ but not ObjC? +} + +- (Subclass3 *)init { return 0; } // don't complain: we lost the related return type + +- (Subclass3 *)self { return 0; } // expected-warning{{method is expected to return an instance of its class type 'Subclass4', but is declared to return 'Subclass3 *'}} + +- (Subclass4 *)initOther { return 0; } + +@end + +// Check that inherited related return types influence the types of +// message sends. +void test_instancetype_inherited() { + [[Subclass4 alloc] initSubclass1]; // expected-warning{{'Subclass4' may not respond to 'initSubclass1'}} + [[Subclass4 alloc] initOther]; +} + +// Check that related return types tighten up the semantics of +// Objective-C method implementations. +@implementation Subclass2 +- (instancetype)initSubclass2 { // expected-note {{explicitly declared 'instancetype'}} + Subclass1 *sc1 = [[Subclass1 alloc] init]; + return sc1; // expected-error{{cannot initialize return object of type 'Subclass2 *' with an lvalue of type 'Subclass1 *'}} +} +- (void)methodOnSubclass2 {} +- (id)self { + Subclass1 *sc1 = [[Subclass1 alloc] init]; + return sc1; // expected-error{{cannot initialize return object of type 'Subclass2 *' with an lvalue of type 'Subclass1 *'}} +} +@end + +@interface MyClass : Root ++ (int)myClassMethod; +@end + +@implementation MyClass ++ (int)myClassMethod { return 0; } + +- (void)blah { + int i = [[MyClass self] myClassMethod]; +} + +@end + +// rdar://12493140 +@protocol P4 +- (instancetype) foo; // expected-note {{current method is explicitly declared 'instancetype' and is expected to return an instance of its class type}} +@end +@interface A4 : Root <P4> +- (instancetype) bar; // expected-note {{current method is explicitly declared 'instancetype' and is expected to return an instance of its class type}} +- (instancetype) baz; // expected-note {{overridden method returns an instance of its class type}} expected-note {{previous definition is here}} +@end +@interface B4 : Root @end + +@implementation A4 { + B4 *_b; +} +- (id) foo { + return _b; // expected-error {{cannot initialize return object of type 'A4 *' with an lvalue of type 'B4 *'}} +} +- (id) bar { + return _b; // expected-error {{cannot initialize return object of type 'A4 *' with an lvalue of type 'B4 *'}} +} + +// This is really just to ensure that we don't crash. +// FIXME: only one diagnostic, please +- (float) baz { // expected-warning {{method is expected to return an instance of its class type 'A4', but is declared to return 'float'}} expected-warning {{conflicting return type in implementation}} + return 0; +} +@end diff --git a/test/SemaObjCXX/instantiate-expr.mm b/test/SemaObjCXX/instantiate-expr.mm index 071bf6bced..e9d296db8f 100644 --- a/test/SemaObjCXX/instantiate-expr.mm +++ b/test/SemaObjCXX/instantiate-expr.mm @@ -21,7 +21,7 @@ void f(U value, V value2) { get_an_A(N)->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}} get_an_A(N).prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}} T c = get_an_id(N)->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \ - // expected-warning 5 {{direct access to Objective-C's isa is deprecated in favor of object_setClass() and object_getClass()}} + // expected-warning 3 {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} } template void f<6, Class>(int, int); // expected-note{{in instantiation of}} @@ -46,7 +46,7 @@ template void f2(A*, int, double*); // expected-note{{instantiation of}} template<typename T, typename U> void f3(U ptr) { T c = ptr->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \ - // expected-warning 2 {{direct access to Objective-C's isa is deprecated in favor of object_setClass() and object_getClass()}} + // expected-warning 1 {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} } template void f3<Class>(id); // expected-note{{in instantiation of}} diff --git a/test/SemaObjCXX/parameters.mm b/test/SemaObjCXX/parameters.mm index 1a7869dc7a..363675a0dd 100644 --- a/test/SemaObjCXX/parameters.mm +++ b/test/SemaObjCXX/parameters.mm @@ -15,3 +15,6 @@ struct test2 { virtual void foo() = 0; }; // expected-note {{unimplemented}} @interface Test2 - (void) foo: (test2) foo; // expected-error {{parameter type 'test2' is an abstract class}} @end + +template<typename T> void r1(__restrict T); +void r2(__restrict id x) { r1(x); } diff --git a/test/SemaObjCXX/property-reference.mm b/test/SemaObjCXX/property-reference.mm index b86ae5e9f5..cfac9f30db 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 f63e17d98e..fa552076fb 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/endian-attr.cl b/test/SemaOpenCL/endian-attr.cl new file mode 100644 index 0000000000..e851cdf90b --- /dev/null +++ b/test/SemaOpenCL/endian-attr.cl @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -verify %s + +constant long a __attribute__((endian(host))) = 100; + +constant long b __attribute__((endian(device))) = 100; + +constant long c __attribute__((endian(none))) = 100; // expected-warning {{unknown endian 'none'}} + +void func() __attribute__((endian(host))); // expected-warning {{endian attribute only applies to variables}} diff --git a/test/SemaOpenCL/event_t.cl b/test/SemaOpenCL/event_t.cl index 57a0981cf1..06197d0c17 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 fdfe134621..d2678f2010 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 495f4a7ad3..5a06a706aa 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 eb75e69ef4..fa47ef5358 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/derived.cpp b/test/SemaTemplate/derived.cpp index 1fb9401c94..7b91f9a3ed 100644 --- a/test/SemaTemplate/derived.cpp +++ b/test/SemaTemplate/derived.cpp @@ -10,3 +10,21 @@ void test() { Foo2(vector2<int*>()); // expected-error{{no matching function for call to 'Foo2'}} Foo(vector<int*>()); // expected-error{{no matching function for call to 'Foo'}} } + +namespace rdar13267210 { + template < typename T > class A { + BaseTy; // expected-error{{C++ requires a type specifier for all declarations}} + }; + + template < typename T, int N > class C: A < T > {}; + + class B { + C<long, 16> ExternalDefinitions; + C<long, 64> &Record; + + void AddSourceLocation(A<long> &R); // expected-note{{passing argument to parameter 'R' here}} + void AddTemplateKWAndArgsInfo() { + AddSourceLocation(Record); // expected-error{{non-const lvalue reference to type}} + } + }; +} diff --git a/test/SemaTemplate/example-dynarray.cpp b/test/SemaTemplate/example-dynarray.cpp deleted file mode 100644 index 999521e91e..0000000000 --- a/test/SemaTemplate/example-dynarray.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// RUN: %clangxx -emit-llvm -c -o - %s -#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/friend-template.cpp b/test/SemaTemplate/friend-template.cpp index 9acbfdcea2..8a478777eb 100644 --- a/test/SemaTemplate/friend-template.cpp +++ b/test/SemaTemplate/friend-template.cpp @@ -302,3 +302,23 @@ namespace PR12585 { H<int> h1; // ok H<char> h2; // expected-note {{instantiation}} } + +// Ensure that we can still instantiate a friend function template +// after the friend declaration is instantiated during the delayed +// parsing of a member function, but before the friend function has +// been parsed. +namespace rdar12350696 { + template <class T> struct A { + void foo() { + A<int> a; + } + template <class U> friend void foo(const A<U> & a) { + int array[sizeof(T) == sizeof(U) ? -1 : 1]; // expected-error {{negative size}} + } + }; + + void test() { + A<int> b; + foo(b); // expected-note {{in instantiation}} + } +} diff --git a/test/SemaTemplate/fun-template-def.cpp b/test/SemaTemplate/fun-template-def.cpp index 0427781218..2d515b4b15 100644 --- a/test/SemaTemplate/fun-template-def.cpp +++ b/test/SemaTemplate/fun-template-def.cpp @@ -46,3 +46,11 @@ T f1(T t1, U u1, int i1) return u1; } + +template<typename T> +void f2(__restrict T x) {} // expected-note {{substitution failure [with T = int]: restrict requires a pointer or reference ('int' is invalid}} + +void f3() { + f2<int*>(0); + f2<int>(0); // expected-error {{no matching function for call to 'f2'}} +} diff --git a/test/SemaTemplate/local-member-templates.cpp b/test/SemaTemplate/local-member-templates.cpp new file mode 100644 index 0000000000..3cdf5df8d1 --- /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 131922bbfb..9efb02ce5f 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 8f80cb59e8..cb1a7f50b7 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 dc6d2a51ec..ad65397865 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 210b5e463f..24509524b2 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/auto-detect-from-source-parent-of-cwd.cpp b/test/Tooling/auto-detect-from-source-parent-of-cwd.cpp index 9692edcd4f..6b632b0a0d 100644 --- a/test/Tooling/auto-detect-from-source-parent-of-cwd.cpp +++ b/test/Tooling/auto-detect-from-source-parent-of-cwd.cpp @@ -8,3 +8,5 @@ invalid; // REQUIRES: shell +// PR15590 +// XFAIL: win64 diff --git a/test/Tooling/auto-detect-from-source-parent.cpp b/test/Tooling/auto-detect-from-source-parent.cpp index ea7eb158be..f1dbc0fa67 100644 --- a/test/Tooling/auto-detect-from-source-parent.cpp +++ b/test/Tooling/auto-detect-from-source-parent.cpp @@ -8,3 +8,5 @@ invalid; // REQUIRES: shell +// PR15590 +// XFAIL: win64 diff --git a/test/Tooling/auto-detect-from-source.cpp b/test/Tooling/auto-detect-from-source.cpp index d8e82e7754..77e06e781c 100644 --- a/test/Tooling/auto-detect-from-source.cpp +++ b/test/Tooling/auto-detect-from-source.cpp @@ -8,3 +8,5 @@ invalid; // REQUIRES: shell +// PR15590 +// XFAIL: win64 diff --git a/test/Tooling/clang-check-args.cpp b/test/Tooling/clang-check-args.cpp index 9ba5d45f50..66950ae103 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-autodetect-dir.cpp b/test/Tooling/clang-check-autodetect-dir.cpp index 2c395043bf..39a0c386fe 100644 --- a/test/Tooling/clang-check-autodetect-dir.cpp +++ b/test/Tooling/clang-check-autodetect-dir.cpp @@ -9,3 +9,5 @@ invalid; // REQUIRES: shell +// PR15590 +// XFAIL: win64 diff --git a/test/Tooling/clang-check-builtin-headers.cpp b/test/Tooling/clang-check-builtin-headers.cpp index 504d197ea9..ed2bea0d65 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 29b5abb4c9..c8113233fa 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-pwd.cpp b/test/Tooling/clang-check-pwd.cpp index 374c579245..463ed40b3e 100644 --- a/test/Tooling/clang-check-pwd.cpp +++ b/test/Tooling/clang-check-pwd.cpp @@ -9,3 +9,5 @@ invalid; // REQUIRES: shell +// PR15590 +// XFAIL: win64 diff --git a/test/Tooling/clang-check.cpp b/test/Tooling/clang-check.cpp index 91ab01b01b..56835b3bf9 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 a3eb7039c0..1e6bce113f 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/Tooling/pch.cpp b/test/Tooling/pch.cpp index 715c95dd55..40bc1e9731 100644 --- a/test/Tooling/pch.cpp +++ b/test/Tooling/pch.cpp @@ -6,12 +6,10 @@ // RUN: %clang -x c++-header %S/Inputs/pch.h -o %t1 // Use the generated pch and enforce a subsequent stat miss by using -// the test file with an unrelated include as second translation unit: -// Do not directly pipe into FileCheck, as that would hide errors from -// valgrind due to pipefail not being set in lit. -// RUN: clang-check "%S/Inputs/pch.cpp" "%s" -- -include-pch %t1 -I "%S" -c >%t2 2>&1 -// RUN: FileCheck %s < %t2 +// the test file with an unrelated include as second translation unit. +// Test for an non-empty file after clang-check is executed. +// RUN: clang-check -ast-dump "%S/Inputs/pch.cpp" "%s" -- -include-pch %t1 -I "%S" -c >%t2 2>&1 +// REQUIRES: shell +// RUN: test -s %t2 #include "Inputs/pch-fail.h" - -// CHECK: Processing diff --git a/test/Unit/lit.cfg b/test/Unit/lit.cfg index 8f27781523..d58337c8f7 100644 --- a/test/Unit/lit.cfg +++ b/test/Unit/lit.cfg @@ -28,6 +28,11 @@ if 'TMP' in os.environ: if 'TEMP' in os.environ: config.environment['TEMP'] = os.environ['TEMP'] +# Propagate path to symbolizer for ASan/MSan. +for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']: + if symbolizer in os.environ: + config.environment[symbolizer] = os.environ[symbolizer] + ### # Check that the object root is known. diff --git a/test/lit.cfg b/test/lit.cfg index f22b0376b4..6b0ad59c9f 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. @@ -83,7 +92,6 @@ if clang_obj_root is not None: lit.fatal('No LLVM tools dir set!') path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH'])) config.environment['PATH'] = path - llvm_libs_dir = getattr(config, 'llvm_libs_dir', None) if not llvm_libs_dir: lit.fatal('No LLVM libs dir set!') @@ -91,6 +99,11 @@ if clang_obj_root is not None: config.environment.get('LD_LIBRARY_PATH',''))) config.environment['LD_LIBRARY_PATH'] = path +# Propagate path to symbolizer for ASan/MSan. +for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']: + if symbolizer in os.environ: + config.environment[symbolizer] = os.environ[symbolizer] + ### # Check that the object root is known. @@ -215,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') @@ -290,3 +299,9 @@ if llc_props['enable_assertions']: if lit.util.which('xmllint'): config.available_features.add('xmllint') +# Sanitizers. +if config.llvm_use_sanitizer == "Address": + config.available_features.add("asan") +if (config.llvm_use_sanitizer == "Memory" or + config.llvm_use_sanitizer == "MemoryWithOrigins"): + config.available_features.add("msan") diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in index df90b81055..23eb8e228c 100644 --- a/test/lit.site.cfg.in +++ b/test/lit.site.cfg.in @@ -7,6 +7,7 @@ config.llvm_libs_dir = "@LLVM_LIBS_DIR@" config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" config.clang_obj_root = "@CLANG_BINARY_DIR@" config.target_triple = "@TARGET_TRIPLE@" +config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" # Support substitution of the tools and libs dirs with user parameters. This is # used when we can't determine the tool dir at configuration time. |