diff options
author | Pirama Arumuga Nainar <pirama@google.com> | 2015-05-06 11:48:57 -0700 |
---|---|---|
committer | Pirama Arumuga Nainar <pirama@google.com> | 2015-05-06 11:48:57 -0700 |
commit | 58878f85ab89b13e9eea4af3ccf055e42c557bc8 (patch) | |
tree | 3bf522a2cb819d02935c537ee23c8604b9e3f807 /test | |
parent | 13cb65defa5e5c4578d83b4f3ca5bdfc08a4e06f (diff) | |
download | clang-58878f85ab89b13e9eea4af3ccf055e42c557bc8.tar.gz |
Update aosp/master clang for rebase to r235153
Change-Id: Ia94bbcb6da7c75b6e7c2afedd1001094d62a7324
Diffstat (limited to 'test')
270 files changed, 8682 insertions, 3192 deletions
diff --git a/test/ARCMT/objcmt-property.m b/test/ARCMT/objcmt-property.m index 61739efe0a..1ea4109385 100644 --- a/test/ARCMT/objcmt-property.m +++ b/test/ARCMT/objcmt-property.m @@ -238,3 +238,11 @@ DEPRECATED @property (nonatomic, readonly) int Idelegate; @property (nonatomic, readonly) BOOL Bdelegate; @end + +// rdar://19372798 +@protocol NSObject @end +@protocol MyProtocol <NSObject> +- (id)readonlyProperty; +- (id)readWriteProperty; +- (void)setReadWriteProperty:(id)readWriteProperty; +@end diff --git a/test/ARCMT/objcmt-property.m.result b/test/ARCMT/objcmt-property.m.result index ec4ac85127..58f8ce2e07 100644 --- a/test/ARCMT/objcmt-property.m.result +++ b/test/ARCMT/objcmt-property.m.result @@ -211,3 +211,10 @@ DEPRECATED @property (nonatomic, readonly) int Idelegate; @property (nonatomic, readonly) BOOL Bdelegate; @end + +// rdar://19372798 +@protocol NSObject @end +@protocol MyProtocol <NSObject> +@property (nonatomic, readonly, strong) id readonlyProperty; +@property (nonatomic, strong) id readWriteProperty; +@end diff --git a/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp b/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp index 639790d31a..bca223b6e0 100644 --- a/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp +++ b/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp @@ -24,5 +24,16 @@ void testNewDeleteNoWarn() { int *p4 = new int; delete p4; - int j = *p4; // no-warning + int j = *p4; // no-warning +} + +void testUseZeroAllocNoWarn() { + int *p1 = (int *)operator new(0); + *p1 = 1; // no-warning + + int *p2 = (int *)operator new[](0); + p2[0] = 1; // no-warning + + int *p3 = new int[0]; + p3[0] = 1; // no-warning } diff --git a/test/Analysis/NewDelete-checker-test.cpp b/test/Analysis/NewDelete-checker-test.cpp index 3f28c2e8f2..443cb2e87e 100644 --- a/test/Analysis/NewDelete-checker-test.cpp +++ b/test/Analysis/NewDelete-checker-test.cpp @@ -87,6 +87,30 @@ void testNewInvalidationPlacement(PtrWrapper *w) { new (w) PtrWrapper(new int); // no warn } +//----------------------------------------- +// check for usage of zero-allocated memory +//----------------------------------------- + +void testUseZeroAlloc1() { + int *p = (int *)operator new(0); + *p = 1; // expected-warning {{Use of zero-allocated memory}} + delete p; +} + +int testUseZeroAlloc2() { + int *p = (int *)operator new[](0); + return p[0]; // expected-warning {{Use of zero-allocated memory}} + delete[] p; +} + +void f(int); + +void testUseZeroAlloc3() { + int *p = new int[0]; + f(*p); // expected-warning {{Use of zero-allocated memory}} + delete[] p; +} + //--------------- // other checks //--------------- diff --git a/test/Analysis/NewDelete-intersections.mm b/test/Analysis/NewDelete-intersections.mm index 7b3fb6eae7..cde8122b72 100644 --- a/test/Analysis/NewDelete-intersections.mm +++ b/test/Analysis/NewDelete-intersections.mm @@ -43,6 +43,11 @@ void testDeleteMalloced() { delete p2; // no warn } +void testUseZeroAllocatedMalloced() { + int *p1 = (int *)malloc(0); + *p1 = 1; // no warn +} + //----- Test free standard new void testFreeOpNew() { void *p = operator new(0); diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c index 5762061ba1..662df4c28b 100644 --- a/test/Analysis/malloc.c +++ b/test/Analysis/malloc.c @@ -200,6 +200,112 @@ void reallocfPtrZero1() { char *r = reallocf(0, 12); } // expected-warning {{Potential leak of memory pointed to by}} +//------------------- Check usage of zero-allocated memory --------------------- +void CheckUseZeroAllocatedNoWarn1() { + int *p = malloc(0); + free(p); // no warning +} + +void CheckUseZeroAllocatedNoWarn2() { + int *p = alloca(0); // no warning +} + +void CheckUseZeroAllocatedNoWarn3() { + int *p = malloc(0); + int *q = realloc(p, 8); // no warning + free(q); +} + +void CheckUseZeroAllocatedNoWarn4() { + int *p = realloc(0, 8); + *p = 1; // no warning + free(p); +} + +void CheckUseZeroAllocated1() { + int *p = malloc(0); + *p = 1; // expected-warning {{Use of zero-allocated memory}} + free(p); +} + +char CheckUseZeroAllocated2() { + char *p = alloca(0); + return *p; // expected-warning {{Use of zero-allocated memory}} +} + +void UseZeroAllocated(int *p) { + if (p) + *p = 7; // expected-warning {{Use of zero-allocated memory}} +} +void CheckUseZeroAllocated3() { + int *p = malloc(0); + UseZeroAllocated(p); +} + +void f(char); +void CheckUseZeroAllocated4() { + char *p = valloc(0); + f(*p); // expected-warning {{Use of zero-allocated memory}} + free(p); +} + +void CheckUseZeroAllocated5() { + int *p = calloc(0, 2); + *p = 1; // expected-warning {{Use of zero-allocated memory}} + free(p); +} + +void CheckUseZeroAllocated6() { + int *p = calloc(2, 0); + *p = 1; // expected-warning {{Use of zero-allocated memory}} + free(p); +} + +void CheckUseZeroAllocated7() { + int *p = realloc(0, 0); + *p = 1; //TODO: warn about use of zero-allocated memory + free(p); +} + +void CheckUseZeroAllocated8() { + int *p = malloc(8); + int *q = realloc(p, 0); + *q = 1; //TODO: warn about use of zero-allocated memory + free(q); +} + +void CheckUseZeroAllocated9() { + int *p = realloc(0, 0); + int *q = realloc(p, 0); + *q = 1; //TODO: warn about use of zero-allocated memory + free(q); +} + +void CheckUseZeroAllocatedPathNoWarn(_Bool b) { + int s = 0; + if (b) + s= 10; + + char *p = malloc(s); + + if (b) + *p = 1; // no warning + + free(p); +} + +void CheckUseZeroAllocatedPathWarn(_Bool b) { + int s = 10; + if (b) + s= 0; + + char *p = malloc(s); + + if (b) + *p = 1; // expected-warning {{Use of zero-allocated memory}} + + free(p); +} // This case tests that storing malloc'ed memory to a static variable which is // then returned is not leaked. In the absence of known contracts for functions diff --git a/test/Analysis/properties.m b/test/Analysis/properties.m index ca6f253d94..bf9424c8c2 100644 --- a/test/Analysis/properties.m +++ b/test/Analysis/properties.m @@ -376,61 +376,61 @@ void testOpaqueConsistency(OpaqueIntWrapper *w) { [_ownedProp retain]; [_ownedProp release]; [_ownedProp release]; - [_ownedProp release]; // expected-warning{{used after it is released}} + [_ownedProp release]; // FIXME-warning{{used after it is released}} } - (void)testOverreleaseUnownedIvar { [_unownedProp retain]; [_unownedProp release]; - [_unownedProp release]; // expected-warning{{not owned at this point by the caller}} + [_unownedProp release]; // FIXME-warning{{not owned at this point by the caller}} } - (void)testOverreleaseIvarOnly { [_ivarOnly retain]; [_ivarOnly release]; [_ivarOnly release]; - [_ivarOnly release]; // expected-warning{{used after it is released}} + [_ivarOnly release]; // FIXME-warning{{used after it is released}} } - (void)testOverreleaseReadonlyIvar { [_readonlyProp retain]; [_readonlyProp release]; [_readonlyProp release]; - [_readonlyProp release]; // expected-warning{{used after it is released}} + [_readonlyProp release]; // FIXME-warning{{used after it is released}} } - (void)testOverreleaseImplicitManualIvar { [_implicitManualProp retain]; [_implicitManualProp release]; [_implicitManualProp release]; - [_implicitManualProp release]; // expected-warning{{used after it is released}} + [_implicitManualProp release]; // FIXME-warning{{used after it is released}} } - (void)testOverreleaseImplicitSynthIvar { [_implicitSynthProp retain]; [_implicitSynthProp release]; - [_implicitSynthProp release]; // expected-warning{{not owned at this point by the caller}} + [_implicitSynthProp release]; // FIXME-warning{{not owned at this point by the caller}} } - (void)testOverreleaseCF { CFRetain(_cfProp); CFRelease(_cfProp); CFRelease(_cfProp); - CFRelease(_cfProp); // expected-warning{{used after it is released}} + CFRelease(_cfProp); // FIXME-warning{{used after it is released}} } - (void)testOverreleaseOwnedIvarUse { [_ownedProp retain]; [_ownedProp release]; [_ownedProp release]; - [_ownedProp myMethod]; // expected-warning{{used after it is released}} + [_ownedProp myMethod]; // FIXME-warning{{used after it is released}} } - (void)testOverreleaseIvarOnlyUse { [_ivarOnly retain]; [_ivarOnly release]; [_ivarOnly release]; - [_ivarOnly myMethod]; // expected-warning{{used after it is released}} + [_ivarOnly myMethod]; // FIXME-warning{{used after it is released}} } - (void)testOverreleaseCFUse { @@ -439,7 +439,7 @@ void testOpaqueConsistency(OpaqueIntWrapper *w) { CFRelease(_cfProp); extern void CFUse(CFTypeRef); - CFUse(_cfProp); // expected-warning{{used after it is released}} + CFUse(_cfProp); // FIXME-warning{{used after it is released}} } - (void)testOverreleaseOwnedIvarAutoreleaseOkay { @@ -459,14 +459,14 @@ void testOpaqueConsistency(OpaqueIntWrapper *w) { [_ownedProp release]; [_ownedProp autorelease]; [_ownedProp autorelease]; -} // expected-warning{{Object autoreleased too many times}} +} // FIXME-warning{{Object autoreleased too many times}} - (void)testOverreleaseIvarOnlyAutorelease { [_ivarOnly retain]; [_ivarOnly release]; [_ivarOnly autorelease]; [_ivarOnly autorelease]; -} // expected-warning{{Object autoreleased too many times}} +} // FIXME-warning{{Object autoreleased too many times}} - (void)testPropertyAccessThenReleaseOwned { id owned = [self.ownedProp retain]; @@ -486,7 +486,7 @@ void testOpaqueConsistency(OpaqueIntWrapper *w) { - (void)testPropertyAccessThenReleaseUnowned { id unowned = [self.unownedProp retain]; [unowned release]; - [_unownedProp release]; // expected-warning{{not owned}} + [_unownedProp release]; // FIXME-warning{{not owned}} } - (void)testPropertyAccessThenReleaseUnowned2 { @@ -494,7 +494,7 @@ void testOpaqueConsistency(OpaqueIntWrapper *w) { id unowned = [self.unownedProp retain]; [unowned release]; clang_analyzer_eval(unowned == fromIvar); // expected-warning{{TRUE}} - [fromIvar release]; // expected-warning{{not owned}} + [fromIvar release]; // FIXME-warning{{not owned}} } - (void)testPropertyAccessThenReleaseManual { @@ -557,7 +557,7 @@ void testOpaqueConsistency(OpaqueIntWrapper *w) { - (void)testPropertyAccessThenReleaseImplicitSynth { id prop = [self.implicitSynthProp retain]; [prop release]; - [_implicitSynthProp release]; // expected-warning{{not owned}} + [_implicitSynthProp release]; // FIXME-warning{{not owned}} } - (void)testPropertyAccessThenReleaseImplicitSynth2 { @@ -565,7 +565,7 @@ void testOpaqueConsistency(OpaqueIntWrapper *w) { id prop = [self.implicitSynthProp retain]; [prop release]; clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}} - [fromIvar release]; // expected-warning{{not owned}} + [fromIvar release]; // FIXME-warning{{not owned}} } - (id)getUnownedFromProperty { @@ -671,6 +671,14 @@ void testOpaqueConsistency(OpaqueIntWrapper *w) { } } +// rdar://problem/20335433 +- (void)retainIvarAndInvalidateSelf { + extern void invalidate(id); + [_unownedProp retain]; + invalidate(self); + [_unownedProp release]; // no-warning +} + @end #endif // non-ARC diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m index 23935b9d1d..6b51305c86 100644 --- a/test/Analysis/retain-release-path-notes.m +++ b/test/Analysis/retain-release-path-notes.m @@ -282,48 +282,48 @@ void CFAutoreleaseUnownedMixed() { } - (void)testOverreleaseUnownedIvar { - [_unownedProp retain]; // expected-note {{Object loaded from instance variable}} - // expected-note@-1 {{Reference count incremented. The object now has a +1 retain count}} - [_unownedProp release]; // expected-note {{Reference count decremented}} - [_unownedProp release]; // expected-note {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} - // expected-warning@-1 {{not owned at this point by the caller}} + [_unownedProp retain]; // FIXME-note {{Object loaded from instance variable}} + // FIXME-note@-1 {{Reference count incremented. The object now has a +1 retain count}} + [_unownedProp release]; // FIXME-note {{Reference count decremented}} + [_unownedProp release]; // FIXME-note {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} + // FIXME-warning@-1 {{not owned at this point by the caller}} } - (void)testOverreleaseOwnedIvarUse { - [_ownedProp retain]; // expected-note {{Object loaded from instance variable}} - // expected-note@-1 {{Reference count incremented. The object now has a +1 retain count}} - [_ownedProp release]; // expected-note {{Reference count decremented}} - [_ownedProp release]; // expected-note {{Strong instance variable relinquished. Object released}} - [_ownedProp myMethod]; // expected-note {{Reference-counted object is used after it is released}} - // expected-warning@-1 {{used after it is released}} + [_ownedProp retain]; // FIXME-note {{Object loaded from instance variable}} + // FIXME-note@-1 {{Reference count incremented. The object now has a +1 retain count}} + [_ownedProp release]; // FIXME-note {{Reference count decremented}} + [_ownedProp release]; // FIXME-note {{Strong instance variable relinquished. Object released}} + [_ownedProp myMethod]; // FIXME-note {{Reference-counted object is used after it is released}} + // FIXME-warning@-1 {{used after it is released}} } - (void)testOverreleaseIvarOnlyUse { - [_ivarOnly retain]; // expected-note {{Object loaded from instance variable}} - // expected-note@-1 {{Reference count incremented. The object now has a +1 retain count}} - [_ivarOnly release]; // expected-note {{Reference count decremented}} - [_ivarOnly release]; // expected-note {{Strong instance variable relinquished. Object released}} - [_ivarOnly myMethod]; // expected-note {{Reference-counted object is used after it is released}} - // expected-warning@-1 {{used after it is released}} + [_ivarOnly retain]; // FIXME-note {{Object loaded from instance variable}} + // FIXME-note@-1 {{Reference count incremented. The object now has a +1 retain count}} + [_ivarOnly release]; // FIXME-note {{Reference count decremented}} + [_ivarOnly release]; // FIXME-note {{Strong instance variable relinquished. Object released}} + [_ivarOnly myMethod]; // FIXME-note {{Reference-counted object is used after it is released}} + // FIXME-warning@-1 {{used after it is released}} } - (void)testOverreleaseOwnedIvarAutorelease { - [_ownedProp retain]; // expected-note {{Object loaded from instance variable}} - // expected-note@-1 {{Reference count incremented. The object now has a +1 retain count}} - [_ownedProp release]; // expected-note {{Reference count decremented}} - [_ownedProp autorelease]; // expected-note {{Object autoreleased}} - [_ownedProp autorelease]; // expected-note {{Object autoreleased}} - // expected-note@+1 {{Object was autoreleased 2 times but the object has a +0 retain count}} -} // expected-warning{{Object autoreleased too many times}} + [_ownedProp retain]; // FIXME-note {{Object loaded from instance variable}} + // FIXME-note@-1 {{Reference count incremented. The object now has a +1 retain count}} + [_ownedProp release]; // FIXME-note {{Reference count decremented}} + [_ownedProp autorelease]; // FIXME-note {{Object autoreleased}} + [_ownedProp autorelease]; // FIXME-note {{Object autoreleased}} + // FIXME-note@+1 {{Object was autoreleased 2 times but the object has a +0 retain count}} +} // FIXME-warning{{Object autoreleased too many times}} - (void)testOverreleaseIvarOnlyAutorelease { - [_ivarOnly retain]; // expected-note {{Object loaded from instance variable}} - // expected-note@-1 {{Reference count incremented. The object now has a +1 retain count}} - [_ivarOnly release]; // expected-note {{Reference count decremented}} - [_ivarOnly autorelease]; // expected-note {{Object autoreleased}} - [_ivarOnly autorelease]; // expected-note {{Object autoreleased}} - // expected-note@+1 {{Object was autoreleased 2 times but the object has a +0 retain count}} -} // expected-warning{{Object autoreleased too many times}} + [_ivarOnly retain]; // FIXME-note {{Object loaded from instance variable}} + // FIXME-note@-1 {{Reference count incremented. The object now has a +1 retain count}} + [_ivarOnly release]; // FIXME-note {{Reference count decremented}} + [_ivarOnly autorelease]; // FIXME-note {{Object autoreleased}} + [_ivarOnly autorelease]; // FIXME-note {{Object autoreleased}} + // FIXME-note@+1 {{Object was autoreleased 2 times but the object has a +0 retain count}} +} // FIXME-warning{{Object autoreleased too many times}} @end @@ -6260,1894 +6260,4 @@ void CFAutoreleaseUnownedMixed() { // 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>285</integer> -// 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>285</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>285</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>285</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>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>285</integer> -// CHECK-NEXT: <key>col</key><integer>4</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>285</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>285</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>Object loaded from instance variable</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object loaded from instance variable</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>285</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>285</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: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>285</integer> -// 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>285</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>285</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>285</integer> -// 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>285</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: <dict> -// CHECK-NEXT: <key>line</key><integer>285</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>285</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>Reference count incremented. The object now has a +1 retain count</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count incremented. The object now has 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>285</integer> -// 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>285</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>287</integer> -// 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>287</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>287</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>287</integer> -// 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>287</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: <dict> -// CHECK-NEXT: <key>line</key><integer>287</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>287</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>Reference count decremented</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count decremented</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>287</integer> -// 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>287</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>288</integer> -// 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>288</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>288</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>288</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>288</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>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: </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> -// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> -// CHECK-NEXT: <key>type</key><string>Bad release</string> -// CHECK-NEXT: <key>check_name</key><string>osx.cocoa.RetainCount</string> -// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string> -// CHECK-NEXT: <key>issue_context</key><string>testOverreleaseUnownedIvar</string> -// CHECK-NEXT: <key>issue_hash</key><string>4</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>288</integer> -// 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>293</integer> -// 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>293</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>293</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>293</integer> -// CHECK-NEXT: <key>col</key><integer>13</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>293</integer> -// CHECK-NEXT: <key>col</key><integer>4</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>293</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>293</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>Object loaded from instance variable</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object loaded from instance variable</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>293</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>293</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: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>293</integer> -// 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>293</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>293</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>293</integer> -// 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>293</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: <dict> -// CHECK-NEXT: <key>line</key><integer>293</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>293</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>Reference count incremented. The object now has a +1 retain count</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count incremented. The object now has 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>293</integer> -// 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>293</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>295</integer> -// 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>295</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>295</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>295</integer> -// 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>295</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: <dict> -// CHECK-NEXT: <key>line</key><integer>295</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>295</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>Reference count decremented</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count decremented</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>295</integer> -// 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>295</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>296</integer> -// 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>296</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>296</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>296</integer> -// 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>296</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: <dict> -// CHECK-NEXT: <key>line</key><integer>296</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>296</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>Strong instance variable relinquished. Object released</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Strong instance variable relinquished. Object 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>296</integer> -// 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>296</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>297</integer> -// 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>297</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>297</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>297</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>297</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>Reference-counted object is used after it is released</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference-counted object is used after it is released</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Reference-counted object is used after it is released</string> -// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> -// CHECK-NEXT: <key>type</key><string>Use-after-release</string> -// CHECK-NEXT: <key>check_name</key><string>osx.cocoa.RetainCount</string> -// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string> -// CHECK-NEXT: <key>issue_context</key><string>testOverreleaseOwnedIvarUse</string> -// CHECK-NEXT: <key>issue_hash</key><string>5</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>297</integer> -// 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>302</integer> -// 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>302</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>302</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>302</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>302</integer> -// CHECK-NEXT: <key>col</key><integer>4</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>302</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>302</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>Object loaded from instance variable</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object loaded from instance variable</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>302</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>302</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>302</integer> -// 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>302</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>302</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>302</integer> -// 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>302</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: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>302</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>302</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>Reference count incremented. The object now has a +1 retain count</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count incremented. The object now has 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>302</integer> -// 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>302</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>304</integer> -// 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>304</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>304</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>304</integer> -// 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>304</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: <dict> -// CHECK-NEXT: <key>line</key><integer>304</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>304</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>Reference count decremented</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count decremented</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>304</integer> -// 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>304</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>305</integer> -// 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>305</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>305</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>305</integer> -// 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>305</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: <dict> -// CHECK-NEXT: <key>line</key><integer>305</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>305</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>Strong instance variable relinquished. Object released</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Strong instance variable relinquished. Object 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>305</integer> -// 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>305</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>306</integer> -// 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>306</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>306</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>306</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>306</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>Reference-counted object is used after it is released</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference-counted object is used after it is released</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>description</key><string>Reference-counted object is used after it is released</string> -// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> -// CHECK-NEXT: <key>type</key><string>Use-after-release</string> -// CHECK-NEXT: <key>check_name</key><string>osx.cocoa.RetainCount</string> -// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string> -// CHECK-NEXT: <key>issue_context</key><string>testOverreleaseIvarOnlyUse</string> -// CHECK-NEXT: <key>issue_hash</key><string>5</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>306</integer> -// 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>311</integer> -// 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>311</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>311</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>311</integer> -// CHECK-NEXT: <key>col</key><integer>13</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>311</integer> -// CHECK-NEXT: <key>col</key><integer>4</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>311</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>311</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>Object loaded from instance variable</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object loaded from instance variable</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>311</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>311</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: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>311</integer> -// 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>311</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>311</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>311</integer> -// 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>311</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: <dict> -// CHECK-NEXT: <key>line</key><integer>311</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>311</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>Reference count incremented. The object now has a +1 retain count</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count incremented. The object now has 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>311</integer> -// 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>311</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>313</integer> -// 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>313</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>313</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>313</integer> -// 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>313</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: <dict> -// CHECK-NEXT: <key>line</key><integer>313</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>313</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>Reference count decremented</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count decremented</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>313</integer> -// 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>313</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>314</integer> -// 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>314</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>314</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>314</integer> -// 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>314</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: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>314</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>314</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>Object autoreleased</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object autoreleased</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>314</integer> -// 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>314</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>315</integer> -// 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>315</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>315</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>315</integer> -// 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>315</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: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>315</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>315</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>Object autoreleased</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object autoreleased</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>315</integer> -// 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>315</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>317</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>317</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>317</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>Object was autoreleased 2 times but the object has a +0 retain count</string> -// CHECK-NEXT: <key>message</key> -// 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 autoreleased too many times</string> -// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> -// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string> -// CHECK-NEXT: <key>check_name</key><string>osx.cocoa.RetainCount</string> -// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string> -// CHECK-NEXT: <key>issue_context</key><string>testOverreleaseOwnedIvarAutorelease</string> -// CHECK-NEXT: <key>issue_hash</key><string>7</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>317</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>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>320</integer> -// 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>320</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>320</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>320</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>320</integer> -// CHECK-NEXT: <key>col</key><integer>4</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>320</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>320</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>Object loaded from instance variable</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object loaded from instance variable</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>320</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>320</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>320</integer> -// 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>320</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>320</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>320</integer> -// 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>320</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: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>320</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>320</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>Reference count incremented. The object now has a +1 retain count</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count incremented. The object now has 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>320</integer> -// 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>320</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>322</integer> -// 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>322</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>322</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>322</integer> -// 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>322</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: <dict> -// CHECK-NEXT: <key>line</key><integer>322</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>322</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>Reference count decremented</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Reference count decremented</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>322</integer> -// 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>322</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>323</integer> -// 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>323</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>323</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>323</integer> -// 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>323</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: <dict> -// CHECK-NEXT: <key>line</key><integer>323</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>323</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>Object autoreleased</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object autoreleased</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>323</integer> -// 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>323</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>324</integer> -// 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>324</integer> -// CHECK-NEXT: <key>col</key><integer>3</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>324</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>324</integer> -// 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>324</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: <dict> -// CHECK-NEXT: <key>line</key><integer>324</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>324</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>Object autoreleased</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Object autoreleased</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>324</integer> -// 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>324</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>326</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>326</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>326</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>Object was autoreleased 2 times but the object has a +0 retain count</string> -// CHECK-NEXT: <key>message</key> -// 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 autoreleased too many times</string> -// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> -// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string> -// CHECK-NEXT: <key>check_name</key><string>osx.cocoa.RetainCount</string> -// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string> -// CHECK-NEXT: <key>issue_context</key><string>testOverreleaseIvarOnlyAutorelease</string> -// CHECK-NEXT: <key>issue_hash</key><string>7</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>326</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> diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp index e03c2164ba..11c17f3272 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp @@ -14,3 +14,6 @@ struct X0 { void mem8(int (*fp)(int) = (int (*)(int = 17))0); // expected-error{{default arguments can only be specified for parameters in a function declaration}} }; + +template <typename... Ts> +void defaultpack(Ts... = 0) {} // expected-error{{parameter pack cannot have a default argument}} diff --git a/test/CXX/drs/dr3xx.cpp b/test/CXX/drs/dr3xx.cpp index cea4d64e7e..5ac4f013b7 100644 --- a/test/CXX/drs/dr3xx.cpp +++ b/test/CXX/drs/dr3xx.cpp @@ -170,9 +170,9 @@ namespace dr308 { // dr308: yes void f() { try { throw D(); - } catch (const A&) { + } catch (const A&) { // expected-note {{for type 'const dr308::A &'}} // unreachable - } catch (const B&) { + } catch (const B&) { // expected-warning {{exception of type 'const dr308::B &' will be caught by earlier handler}} // get here instead } } diff --git a/test/CXX/drs/dr7xx.cpp b/test/CXX/drs/dr7xx.cpp new file mode 100644 index 0000000000..fe4a2dc5ee --- /dev/null +++ b/test/CXX/drs/dr7xx.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +namespace dr777 { // dr777: 3.7 +#if __cplusplus >= 201103L +template <typename... T> +void f(int i = 0, T ...args) {} +void ff() { f(); } + +template <typename... T> +void g(int i = 0, T ...args, T ...args2) {} + +template <typename... T> +void h(int i = 0, T ...args, int j = 1) {} +#endif +} + +// expected-no-diagnostics diff --git a/test/CXX/special/class.dtor/p10-0x.cpp b/test/CXX/special/class.dtor/p10-0x.cpp index 029cbd6ceb..3b8a0ad4d6 100644 --- a/test/CXX/special/class.dtor/p10-0x.cpp +++ b/test/CXX/special/class.dtor/p10-0x.cpp @@ -27,9 +27,9 @@ void a(const A *x, int i, int *pi) { y->~decltype(A())(); // expected-error{{use of undeclared identifier 'y'}} typedef int *intp; - i->~decltype(int())(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}} + i->~decltype(int())(); // expected-error{{member reference type 'int' is not a pointer; did you mean to use '.'?}} i.~decltype(int())(); - i->~decltype(intp())(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}} \ + i->~decltype(intp())(); // expected-error{{member reference type 'int' is not a pointer; did you mean to use '.'?}} \ expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}} i.~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}} pi->~decltype(int())(); diff --git a/test/CXX/temp/temp.decls/temp.mem/p5.cpp b/test/CXX/temp/temp.decls/temp.mem/p5.cpp index 8bcd773ee9..1e061fa33d 100644 --- a/test/CXX/temp/temp.decls/temp.mem/p5.cpp +++ b/test/CXX/temp/temp.decls/temp.mem/p5.cpp @@ -55,8 +55,8 @@ template double Foo::As2(); // Partial ordering with conversion function templates. struct X0 { template<typename T> operator T*() { - T x = 1; - x = 17; // expected-error{{read-only variable is not assignable}} + T x = 1; // expected-note{{variable 'x' declared const here}} + x = 17; // expected-error{{cannot assign to variable 'x' with const-qualified type 'const int'}} } template<typename T> operator T*() const; // expected-note{{explicit instantiation refers here}} diff --git a/test/CodeGen/2007-02-25-C-DotDotDot.c b/test/CodeGen/2007-02-25-C-DotDotDot.c index 1c3a3df570..ade052ec6b 100644 --- a/test/CodeGen/2007-02-25-C-DotDotDot.c +++ b/test/CodeGen/2007-02-25-C-DotDotDot.c @@ -3,7 +3,7 @@ // Make sure the call to foo is compiled as: // call float @foo() // not -// call float (...)* bitcast (float ()* @foo to float (...)*)( ) +// call float (...) bitcast (float ()* @foo to float (...)*)( ) static float foo() { return 0.0; } // CHECK: call float @foo diff --git a/test/CodeGen/2008-07-29-override-alias-decl.c b/test/CodeGen/2008-07-29-override-alias-decl.c index 0c2d0c6ca5..84fac34f3c 100644 --- a/test/CodeGen/2008-07-29-override-alias-decl.c +++ b/test/CodeGen/2008-07-29-override-alias-decl.c @@ -14,6 +14,6 @@ int h() { return f(); } -// CHECK: [[call:%.*]] = call i32 (...)* @f() +// CHECK: [[call:%.*]] = call i32 (...) @f() // CHECK: ret i32 [[call]] diff --git a/test/CodeGen/arm-abi-vector.c b/test/CodeGen/arm-abi-vector.c index 468acdf91c..88bf593ed2 100644 --- a/test/CodeGen/arm-abi-vector.c +++ b/test/CodeGen/arm-abi-vector.c @@ -37,9 +37,9 @@ double varargs_vec_2i(int fixed, ...) { double test_2i(__int2 *in) { // CHECK: test_2i -// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_2i(i32 3, <2 x i32> {{%.*}}) +// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_2i(i32 3, <2 x i32> {{%.*}}) // APCS-GNU: test_2i -// APCS-GNU: call double (i32, ...)* @varargs_vec_2i(i32 3, <2 x i32> {{%.*}}) +// APCS-GNU: call double (i32, ...) @varargs_vec_2i(i32 3, <2 x i32> {{%.*}}) return varargs_vec_2i(3, *in); } @@ -63,9 +63,9 @@ double varargs_vec_3c(int fixed, ...) { double test_3c(__char3 *in) { // CHECK: test_3c -// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_3c(i32 3, i32 {{%.*}}) +// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_3c(i32 3, i32 {{%.*}}) // APCS-GNU: test_3c -// APCS-GNU: call double (i32, ...)* @varargs_vec_3c(i32 3, i32 {{%.*}}) +// APCS-GNU: call double (i32, ...) @varargs_vec_3c(i32 3, i32 {{%.*}}) return varargs_vec_3c(3, *in); } @@ -94,9 +94,9 @@ double varargs_vec_5c(int fixed, ...) { double test_5c(__char5 *in) { // CHECK: test_5c -// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> {{%.*}}) +// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_5c(i32 5, <2 x i32> {{%.*}}) // APCS-GNU: test_5c -// APCS-GNU: call double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> {{%.*}}) +// APCS-GNU: call double (i32, ...) @varargs_vec_5c(i32 5, <2 x i32> {{%.*}}) return varargs_vec_5c(5, *in); } @@ -128,9 +128,9 @@ double varargs_vec_9c(int fixed, ...) { double test_9c(__char9 *in) { // CHECK: test_9c -// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> {{%.*}}) +// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_9c(i32 9, <4 x i32> {{%.*}}) // APCS-GNU: test_9c -// APCS-GNU: call double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> {{%.*}}) +// APCS-GNU: call double (i32, ...) @varargs_vec_9c(i32 9, <4 x i32> {{%.*}}) return varargs_vec_9c(9, *in); } @@ -156,9 +156,9 @@ double varargs_vec_19c(int fixed, ...) { double test_19c(__char19 *in) { // CHECK: test_19c -// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}}) +// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}}) // APCS-GNU: test_19c -// APCS-GNU: call double (i32, ...)* @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}}) +// APCS-GNU: call double (i32, ...) @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}}) return varargs_vec_19c(19, *in); } @@ -187,9 +187,9 @@ double varargs_vec_3s(int fixed, ...) { double test_3s(__short3 *in) { // CHECK: test_3s -// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_3s(i32 3, <2 x i32> {{%.*}}) +// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_3s(i32 3, <2 x i32> {{%.*}}) // APCS-GNU: test_3s -// APCS-GNU: call double (i32, ...)* @varargs_vec_3s(i32 3, <2 x i32> {{%.*}}) +// APCS-GNU: call double (i32, ...) @varargs_vec_3s(i32 3, <2 x i32> {{%.*}}) return varargs_vec_3s(3, *in); } @@ -221,9 +221,9 @@ double varargs_vec_5s(int fixed, ...) { double test_5s(__short5 *in) { // CHECK: test_5s -// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> {{%.*}}) +// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_5s(i32 5, <4 x i32> {{%.*}}) // APCS-GNU: test_5s -// APCS-GNU: call double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> {{%.*}}) +// APCS-GNU: call double (i32, ...) @varargs_vec_5s(i32 5, <4 x i32> {{%.*}}) return varargs_vec_5s(5, *in); } @@ -256,8 +256,8 @@ double varargs_struct(int fixed, ...) { double test_struct(StructWithVec* d) { // CHECK: test_struct -// CHECK: call arm_aapcscc double (i32, ...)* @varargs_struct(i32 3, [2 x i64] {{%.*}}) +// CHECK: call arm_aapcscc double (i32, ...) @varargs_struct(i32 3, [2 x i64] {{%.*}}) // APCS-GNU: test_struct -// APCS-GNU: call double (i32, ...)* @varargs_struct(i32 3, [2 x i64] {{%.*}}) +// APCS-GNU: call double (i32, ...) @varargs_struct(i32 3, [2 x i64] {{%.*}}) return varargs_struct(3, *d); } diff --git a/test/CodeGen/arm-homogenous.c b/test/CodeGen/arm-homogenous.c index 3426d995ca..42a9bc1c16 100644 --- a/test/CodeGen/arm-homogenous.c +++ b/test/CodeGen/arm-homogenous.c @@ -184,7 +184,7 @@ extern void takes_struct_of_four_doubles_variadic(double a, struct_of_four_doubl void test_struct_of_four_doubles_variadic(void) { // CHECK: test_struct_of_four_doubles_variadic -// CHECK: call arm_aapcs_vfpcc void (double, [4 x i64], [4 x i64], double, ...)* @takes_struct_of_four_doubles_variadic(double {{.*}}, [4 x i64] {{.*}}, [4 x i64] {{.*}}, double {{.*}}) +// CHECK: call arm_aapcs_vfpcc void (double, [4 x i64], [4 x i64], double, ...) @takes_struct_of_four_doubles_variadic(double {{.*}}, [4 x i64] {{.*}}, [4 x i64] {{.*}}, double {{.*}}) takes_struct_of_four_doubles_variadic(3.0, g_s4d, g_s4d, 4.0); } diff --git a/test/CodeGen/arm64-abi-vector.c b/test/CodeGen/arm64-abi-vector.c index f4895c1cb2..4566c41790 100644 --- a/test/CodeGen/arm64-abi-vector.c +++ b/test/CodeGen/arm64-abi-vector.c @@ -29,7 +29,7 @@ double varargs_vec_3c(int fixed, ...) { double test_3c(__char3 *in) { // CHECK: test_3c -// CHECK: call double (i32, ...)* @varargs_vec_3c(i32 3, i32 {{%.*}}) +// CHECK: call double (i32, ...) @varargs_vec_3c(i32 3, i32 {{%.*}}) return varargs_vec_3c(3, *in); } @@ -49,7 +49,7 @@ double varargs_vec_4c(int fixed, ...) { double test_4c(__char4 *in) { // CHECK: test_4c -// CHECK: call double (i32, ...)* @varargs_vec_4c(i32 4, i32 {{%.*}}) +// CHECK: call double (i32, ...) @varargs_vec_4c(i32 4, i32 {{%.*}}) return varargs_vec_4c(4, *in); } @@ -69,7 +69,7 @@ double varargs_vec_5c(int fixed, ...) { double test_5c(__char5 *in) { // CHECK: test_5c -// CHECK: call double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> {{%.*}}) +// CHECK: call double (i32, ...) @varargs_vec_5c(i32 5, <2 x i32> {{%.*}}) return varargs_vec_5c(5, *in); } @@ -91,7 +91,7 @@ double varargs_vec_9c(int fixed, ...) { double test_9c(__char9 *in) { // CHECK: test_9c -// CHECK: call double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> {{%.*}}) +// CHECK: call double (i32, ...) @varargs_vec_9c(i32 9, <4 x i32> {{%.*}}) return varargs_vec_9c(9, *in); } @@ -112,7 +112,7 @@ double varargs_vec_19c(int fixed, ...) { double test_19c(__char19 *in) { // CHECK: test_19c -// CHECK: call double (i32, ...)* @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}}) +// CHECK: call double (i32, ...) @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}}) return varargs_vec_19c(19, *in); } @@ -132,7 +132,7 @@ double varargs_vec_3s(int fixed, ...) { double test_3s(__short3 *in) { // CHECK: test_3s -// CHECK: call double (i32, ...)* @varargs_vec_3s(i32 3, <2 x i32> {{%.*}}) +// CHECK: call double (i32, ...) @varargs_vec_3s(i32 3, <2 x i32> {{%.*}}) return varargs_vec_3s(3, *in); } @@ -154,7 +154,7 @@ double varargs_vec_5s(int fixed, ...) { double test_5s(__short5 *in) { // CHECK: test_5s -// CHECK: call double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> {{%.*}}) +// CHECK: call double (i32, ...) @varargs_vec_5s(i32 5, <4 x i32> {{%.*}}) return varargs_vec_5s(5, *in); } @@ -176,7 +176,7 @@ double varargs_vec_3i(int fixed, ...) { double test_3i(__int3 *in) { // CHECK: test_3i -// CHECK: call double (i32, ...)* @varargs_vec_3i(i32 3, <4 x i32> {{%.*}}) +// CHECK: call double (i32, ...) @varargs_vec_3i(i32 3, <4 x i32> {{%.*}}) return varargs_vec_3i(3, *in); } @@ -198,7 +198,7 @@ double varargs_vec_5i(int fixed, ...) { double test_5i(__int5 *in) { // CHECK: test_5i -// CHECK: call double (i32, ...)* @varargs_vec_5i(i32 5, <5 x i32>* {{%.*}}) +// CHECK: call double (i32, ...) @varargs_vec_5i(i32 5, <5 x i32>* {{%.*}}) return varargs_vec_5i(5, *in); } @@ -220,7 +220,7 @@ double varargs_vec_3d(int fixed, ...) { double test_3d(__double3 *in) { // CHECK: test_3d -// CHECK: call double (i32, ...)* @varargs_vec_3d(i32 3, <3 x double>* {{%.*}}) +// CHECK: call double (i32, ...) @varargs_vec_3d(i32 3, <3 x double>* {{%.*}}) return varargs_vec_3d(3, *in); } @@ -285,7 +285,7 @@ double test(__char3 *c3, __char5 *c5, __char9 *c9, __char19 *c19, __short3 *s3, __short5 *s5, __int3 *i3, __int5 *i5, __double3 *d3) { double ret = varargs_vec(3, *c3, *c5, *c9, *c19, *s3, *s5, *i3, *i5, *d3); -// CHECK: call double (i32, ...)* @varargs_vec(i32 3, i32 {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, <19 x i8>* {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, <4 x i32> {{%.*}}, <5 x i32>* {{%.*}}, <3 x double>* {{%.*}}) +// CHECK: call double (i32, ...) @varargs_vec(i32 3, i32 {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, <19 x i8>* {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, <4 x i32> {{%.*}}, <5 x i32>* {{%.*}}, <3 x double>* {{%.*}}) return ret; } diff --git a/test/CodeGen/arm64-arguments.c b/test/CodeGen/arm64-arguments.c index 5c56fd4749..c276350da9 100644 --- a/test/CodeGen/arm64-arguments.c +++ b/test/CodeGen/arm64-arguments.c @@ -641,7 +641,7 @@ float test_hfa(int n, ...) { float test_hfa_call(struct HFA *a) { // CHECK-LABEL: define float @test_hfa_call(%struct.HFA* %a) -// CHECK: call float (i32, ...)* @test_hfa(i32 1, [4 x float] {{.*}}) +// CHECK: call float (i32, ...) @test_hfa(i32 1, [4 x float] {{.*}}) test_hfa(1, *a); } diff --git a/test/CodeGen/avx512f-builtins.c b/test/CodeGen/avx512f-builtins.c index 89f8a535ee..340beb8f01 100644 --- a/test/CodeGen/avx512f-builtins.c +++ b/test/CodeGen/avx512f-builtins.c @@ -633,3 +633,112 @@ __mmask8 test_mm512_mask_cmp_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) // CHECK: @llvm.x86.avx512.mask.ucmp.q.512(<8 x i64> {{.*}}, <8 x i64> {{.*}}, i8 3, i8 {{.*}}) return (__mmask8)_mm512_mask_cmp_epu64_mask(__u, __a, __b, 3); } + +__m512i test_mm512_mask_and_epi32(__m512i __src,__mmask16 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_mask_and_epi32 + // CHECK: @llvm.x86.avx512.mask.pand.d.512 + return _mm512_mask_and_epi32(__src, __k,__a, __b); +} + +__m512i test_mm512_maskz_and_epi32(__mmask16 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_maskz_and_epi32 + // CHECK: @llvm.x86.avx512.mask.pand.d.512 + return _mm512_maskz_and_epi32(__k,__a, __b); +} + +__m512i test_mm512_mask_and_epi64(__m512i __src,__mmask8 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_mask_and_epi64 + // CHECK: @llvm.x86.avx512.mask.pand.q.512 + return _mm512_mask_and_epi64(__src, __k,__a, __b); +} + +__m512i test_mm512_maskz_and_epi64(__mmask8 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_maskz_and_epi64 + // CHECK: @llvm.x86.avx512.mask.pand.q.512 + return _mm512_maskz_and_epi64(__k,__a, __b); +} + +__m512i test_mm512_mask_or_epi32(__m512i __src,__mmask16 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_mask_or_epi32 + // CHECK: @llvm.x86.avx512.mask.por.d.512 + return _mm512_mask_or_epi32(__src, __k,__a, __b); +} + +__m512i test_mm512_maskz_or_epi32(__mmask16 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_maskz_or_epi32 + // CHECK: @llvm.x86.avx512.mask.por.d.512 + return _mm512_maskz_or_epi32(__k,__a, __b); +} + +__m512i test_mm512_mask_or_epi64(__m512i __src,__mmask8 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_mask_or_epi64 + // CHECK: @llvm.x86.avx512.mask.por.q.512 + return _mm512_mask_or_epi64(__src, __k,__a, __b); +} + +__m512i test_mm512_maskz_or_epi64(__mmask8 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_maskz_or_epi64 + // CHECK: @llvm.x86.avx512.mask.por.q.512 + return _mm512_maskz_or_epi64(__k,__a, __b); +} + +__m512i test_mm512_mask_xor_epi32(__m512i __src,__mmask16 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_mask_xor_epi32 + // CHECK: @llvm.x86.avx512.mask.pxor.d.512 + return _mm512_mask_xor_epi32(__src, __k,__a, __b); +} + +__m512i test_mm512_maskz_xor_epi32(__mmask16 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_maskz_xor_epi32 + // CHECK: @llvm.x86.avx512.mask.pxor.d.512 + return _mm512_maskz_xor_epi32(__k,__a, __b); +} + +__m512i test_mm512_mask_xor_epi64(__m512i __src,__mmask8 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_mask_xor_epi64 + // CHECK: @llvm.x86.avx512.mask.pxor.q.512 + return _mm512_mask_xor_epi64(__src, __k,__a, __b); +} + +__m512i test_mm512_maskz_xor_epi64(__mmask8 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_maskz_xor_epi64 + // CHECK: @llvm.x86.avx512.mask.pxor.q.512 + return _mm512_maskz_xor_epi64(__k,__a, __b); +} + +__m512i test_mm512_and_epi32(__m512i __src,__mmask16 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_and_epi32 + // CHECK: and <8 x i64> + return _mm512_and_epi32(__a, __b); +} + +__m512i test_mm512_and_epi64(__m512i __src,__mmask8 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_and_epi64 + // CHECK: and <8 x i64> + return _mm512_and_epi64(__a, __b); +} + +__m512i test_mm512_or_epi32(__m512i __src,__mmask16 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_or_epi32 + // CHECK: or <8 x i64> + return _mm512_or_epi32(__a, __b); +} + +__m512i test_mm512_or_epi64(__m512i __src,__mmask8 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_or_epi64 + // CHECK: or <8 x i64> + return _mm512_or_epi64(__a, __b); +} + +__m512i test_mm512_xor_epi32(__m512i __src,__mmask16 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_xor_epi32 + // CHECK: xor <8 x i64> + return _mm512_xor_epi32(__a, __b); +} + +__m512i test_mm512_xor_epi64(__m512i __src,__mmask8 __k, __m512i __a, __m512i __b) { + // CHECK-LABEL: @test_mm512_xor_epi64 + // CHECK: xor <8 x i64> + return _mm512_xor_epi64(__a, __b); +} + diff --git a/test/CodeGen/blocks-seq.c b/test/CodeGen/blocks-seq.c index a7851d66d5..b3e672976c 100644 --- a/test/CodeGen/blocks-seq.c +++ b/test/CodeGen/blocks-seq.c @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s // CHECK: [[Vi:%.+]] = alloca %struct.__block_byref_i, align 8 -// CHECK: call i32 (...)* @rhs() +// CHECK: call i32 (...) @rhs() // CHECK: [[V7:%.+]] = getelementptr inbounds %struct.__block_byref_i, %struct.__block_byref_i* [[Vi]], i32 0, i32 1 // CHECK: load %struct.__block_byref_i*, %struct.__block_byref_i** [[V7]] -// CHECK: call i32 (...)* @rhs() +// CHECK: call i32 (...) @rhs() // CHECK: [[V11:%.+]] = getelementptr inbounds %struct.__block_byref_i, %struct.__block_byref_i* [[Vi]], i32 0, i32 1 // CHECK: load %struct.__block_byref_i*, %struct.__block_byref_i** [[V11]] diff --git a/test/CodeGen/builtin-assume.c b/test/CodeGen/builtin-assume.c index 8f83f17377..19afec69e7 100644 --- a/test/CodeGen/builtin-assume.c +++ b/test/CodeGen/builtin-assume.c @@ -1,25 +1,44 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple i386-mingw32 -fms-extensions -emit-llvm -o - %s | FileCheck %s +int nonconst(void); +int isconst(void) __attribute__((const)); +int ispure(void) __attribute__((pure)); + // CHECK-LABEL: @test1 int test1(int *a, int i) { // CHECK: store i32* %a, i32** [[A_ADDR:%.+]], align // CHECK: [[A:%.+]] = load i32*, i32** [[A_ADDR]] // CHECK: [[CMP:%.+]] = icmp ne i32* [[A]], null // CHECK: call void @llvm.assume(i1 [[CMP]]) + +// CHECK: [[CALL:%.+]] = call i32 @isconst() +// CHECK: [[BOOL:%.+]] = icmp ne i32 [[CALL]], 0 +// CHECK: call void @llvm.assume(i1 [[BOOL]]) + +// CHECK: [[CALLPURE:%.+]] = call i32 @ispure() +// CHECK: [[BOOLPURE:%.+]] = icmp ne i32 [[CALLPURE]], 0 +// CHECK: call void @llvm.assume(i1 [[BOOLPURE]]) #ifdef _MSC_VER __assume(a != 0) + __assume(isconst()); + __assume(ispure()); #else __builtin_assume(a != 0); + __builtin_assume(isconst()); + __builtin_assume(ispure()); #endif // Nothing is generated for an assume with side effects... // CHECK-NOT: load i32*, i32** %i.addr // CHECK-NOT: call void @llvm.assume +// CHECK-NOT: call i32 @nonconst() #ifdef _MSC_VER __assume(++i != 0) + __assume(nonconst()); #else __builtin_assume(++i != 0); + __builtin_assume(nonconst()); #endif return a[0]; diff --git a/test/CodeGen/builtin-expect.c b/test/CodeGen/builtin-expect.c index 21c3adedbd..884110cbe9 100644 --- a/test/CodeGen/builtin-expect.c +++ b/test/CodeGen/builtin-expect.c @@ -23,9 +23,9 @@ int main() { // CHECK-LABEL: define i32 @main() // CHECK: call void @isigprocmask() -// CHECK: [[C:%.*]] = call i64 (...)* @bar() +// CHECK: [[C:%.*]] = call i64 (...) @bar() // CHECK_O0: call void @isigprocmask() -// CHECK_O0: [[C:%.*]] = call i64 (...)* @bar() +// CHECK_O0: [[C:%.*]] = call i64 (...) @bar() // CHECK_O0-NOT: call i64 @llvm.expect diff --git a/test/CodeGen/builtins-ppc-crypto-diag.c b/test/CodeGen/builtins-ppc-crypto-diag.c deleted file mode 100644 index 4408ab48a1..0000000000 --- a/test/CodeGen/builtins-ppc-crypto-diag.c +++ /dev/null @@ -1,47 +0,0 @@ -// REQUIRES: powerpc-registered-target -// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T1LW -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T1 -// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T1MW -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T1 -// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T2LW -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T2 -// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T2MW -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T2 -// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T1LD -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T1 -// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T1MD -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T1 -// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T2LD -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T2 -// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T2MD -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T2 -#include <altivec.h> - -#define W_INIT { 0x01020304, 0x05060708, \ - 0x090A0B0C, 0x0D0E0F10 }; -#define D_INIT { 0x0102030405060708, \ - 0x090A0B0C0D0E0F10 }; -vector unsigned int test_vshasigmaw_or(void) -{ - vector unsigned int a = W_INIT -#ifdef _T1LW // Arg1 too large - vector unsigned int b = __builtin_crypto_vshasigmaw(a, 2, 15); -#elif defined(_T1MW) // Arg1 negative - vector unsigned int c = __builtin_crypto_vshasigmaw(a, -1, 15); -#elif defined(_T2LW) // Arg2 too large - vector unsigned int d = __builtin_crypto_vshasigmaw(a, 0, 85); -#elif defined(_T2MW) // Arg1 negative - vector unsigned int e = __builtin_crypto_vshasigmaw(a, 1, -15); -#endif - return __builtin_crypto_vshasigmaw(a, 1, 15); -} - -vector unsigned long long test_vshasigmad_or(void) -{ - vector unsigned long long a = D_INIT -#ifdef _T1LD // Arg1 too large - vector unsigned long long b = __builtin_crypto_vshasigmad(a, 2, 15); -#elif defined(_T1MD) // Arg1 negative - vector unsigned long long c = __builtin_crypto_vshasigmad(a, -1, 15); -#elif defined(_T2LD) // Arg2 too large - vector unsigned long long d = __builtin_crypto_vshasigmad(a, 0, 85); -#elif defined(_T2MD) // Arg1 negative - vector unsigned long long e = __builtin_crypto_vshasigmad(a, 1, -15); -#endif - return __builtin_crypto_vshasigmad(a, 0, 15); -} - -// CHECK-T1: error: argument out of range (should be 0-1). -// CHECK-T2: error: argument out of range (should be 0-15). diff --git a/test/CodeGen/builtins-ppc-p7-disabled.c b/test/CodeGen/builtins-ppc-p7-disabled.c new file mode 100644 index 0000000000..9ccedd2ce8 --- /dev/null +++ b/test/CodeGen/builtins-ppc-p7-disabled.c @@ -0,0 +1,33 @@ +// REQUIRES: powerpc-registered-target +// RUN: not %clang_cc1 -triple powerpc64-unknown-unknown \ +// RUN: -target-cpu pwr6 -emit-llvm %s -o - 2>&1 \ +// RUN: | FileCheck %s + +// RUN: not %clang_cc1 -triple powerpc-unknown-unknown -emit-llvm %s -o - 2>&1 \ +// RUN: -target-cpu pwr7 | FileCheck %s -check-prefix=CHECK-32 + +void call_p7_builtins(void) +{ + int a = __builtin_divwe(33, 11); + unsigned int b = __builtin_divweu(33U, 11U); + unsigned long long d = __builtin_divde(33ULL, 11ULL); + unsigned long long e = __builtin_divdeu(33ULL, 11ULL); + unsigned long long f = __builtin_bpermd(33ULL, 11ULL); +} + +// CHECK: error: this builtin is only valid on POWER7 or later CPUs +// CHECK: __builtin_divwe +// CHECK: error: this builtin is only valid on POWER7 or later CPUs +// CHECK: __builtin_divweu +// CHECK: error: this builtin is only valid on POWER7 or later CPUs +// CHECK: __builtin_divde +// CHECK: error: this builtin is only valid on POWER7 or later CPUs +// CHECK: __builtin_divdeu +// CHECK: error: this builtin is only valid on POWER7 or later CPUs +// CHECK: __builtin_bpermd +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __builtin_divde +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __builtin_divdeu +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __builtin_bpermd diff --git a/test/CodeGen/builtins-ppc-p7.c b/test/CodeGen/builtins-ppc-p7.c new file mode 100644 index 0000000000..f584410308 --- /dev/null +++ b/test/CodeGen/builtins-ppc-p7.c @@ -0,0 +1,52 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu pwr7 \ +// RUN: -emit-llvm %s -o - | FileCheck %s + +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr8 \ +// RUN: -emit-llvm %s -o - | FileCheck %s + +// CHECK-LABEL: define signext i32 @test_divwe +int test_divwe(void) +{ + int a = 74; + int b = 32; + return __builtin_divwe(a, b); +// CHECK @llvm.ppc.divwe +} + +// CHECK-LABEL: define zeroext i32 @test_divweu +unsigned int test_divweu(void) +{ + unsigned int a = 74; + unsigned int b = 32; + return __builtin_divweu(a, b); +// CHECK @llvm.ppc.divweu +} + +// CHECK-LABEL: define i64 @test_divde +long long test_divde(void) +{ + long long a = 74LL; + long long b = 32LL; + return __builtin_divde(a, b); +// CHECK @llvm.ppc.divde +} + +// CHECK-LABEL: define i64 @test_divdeu +unsigned long long test_divdeu(void) +{ + unsigned long long a = 74ULL; + unsigned long long b = 32ULL; + return __builtin_divdeu(a, b); +// CHECK @llvm.ppc.divdeu +} + +// CHECK-LABEL: define i64 @test_bpermd +long long test_bpermd(void) +{ + long long a = 74LL; + long long b = 32LL; + return __builtin_bpermd(a, b); +// CHECK @llvm.ppc.bpermd +} + diff --git a/test/CodeGen/builtins-systemz-error.c b/test/CodeGen/builtins-systemz-error.c new file mode 100644 index 0000000000..73431b0a32 --- /dev/null +++ b/test/CodeGen/builtins-systemz-error.c @@ -0,0 +1,9 @@ +// REQUIRES: systemz-registered-target +// RUN: %clang_cc1 -target-cpu zEC12 -triple s390x-unknown-unknown \ +// RUN: -Wall -Wno-unused -Werror -fsyntax-only -verify %s + +void test1(void) { + __builtin_tabort (0); // expected-error {{invalid transaction abort code}} + __builtin_tabort (255); // expected-error {{invalid transaction abort code}} +} + diff --git a/test/CodeGen/builtins-systemz.c b/test/CodeGen/builtins-systemz.c new file mode 100644 index 0000000000..f5de7009ac --- /dev/null +++ b/test/CodeGen/builtins-systemz.c @@ -0,0 +1,144 @@ +// REQUIRES: systemz-registered-target +// RUN: %clang_cc1 -target-cpu zEC12 -triple s390x-ibm-linux -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -target-cpu zEC12 -triple s390x-ibm-linux -Wall -Wno-unused -Werror -emit-llvm -x c++ %s -o - | FileCheck %s + +#include <stdint.h> +#include <htmintrin.h> + +int global = 0; +uint64_t g; +struct __htm_tdb global_tdb; + +void test_htm1(struct __htm_tdb *tdb, int reg, int *mem, uint64_t *mem64) { +// CHECK-LABEL: test_htm1 + + __builtin_tbegin ((void *)0); +// CHECK: call i32 @llvm.s390.tbegin(i8* null, i32 65292) + __builtin_tbegin ((void *)0x12345678); +// CHECK: call i32 @llvm.s390.tbegin(i8* inttoptr (i64 305419896 to i8*), i32 65292) + __builtin_tbegin (tdb); +// CHECK: call i32 @llvm.s390.tbegin(i8* %{{.*}}, i32 65292) + __builtin_tbegin (&global_tdb); +// CHECK: call i32 @llvm.s390.tbegin(i8* getelementptr inbounds (%struct.__htm_tdb, %struct.__htm_tdb* @global_tdb, i32 0, i32 0), i32 65292) + + __builtin_tbegin_nofloat ((void *)0); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* null, i32 65292) + __builtin_tbegin_nofloat ((void *)0x12345678); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* inttoptr (i64 305419896 to i8*), i32 65292) + __builtin_tbegin_nofloat (tdb); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* %{{.*}}, i32 65292) + __builtin_tbegin_nofloat (&global_tdb); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* getelementptr inbounds (%struct.__htm_tdb, %struct.__htm_tdb* @global_tdb, i32 0, i32 0), i32 65292) + + __builtin_tbegin_retry ((void *)0, 6); +// CHECK: call i32 @llvm.s390.tbegin(i8* null, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry ((void *)0x12345678, 6); +// CHECK: call i32 @llvm.s390.tbegin(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry (tdb, 6); +// CHECK: call i32 @llvm.s390.tbegin(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry (&global_tdb, 6); +// CHECK: call i32 @llvm.s390.tbegin(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + + __builtin_tbegin_retry_nofloat ((void *)0, 6); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* null, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry_nofloat ((void *)0x12345678, 6); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry_nofloat (tdb, 6); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry_nofloat (&global_tdb, 6); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + + __builtin_tbeginc (); +// CHECK: call void @llvm.s390.tbeginc(i8* null, i32 65288) + + __builtin_tabort (256); +// CHECK: call void @llvm.s390.tabort(i64 256) + __builtin_tabort (-1); +// CHECK: call void @llvm.s390.tabort(i64 -1) + __builtin_tabort (reg); +// CHECK: call void @llvm.s390.tabort(i64 %{{.*}}) + + __builtin_tend(); +// CHECK: call i32 @llvm.s390.tend() + + int n = __builtin_tx_nesting_depth(); +// CHECK: call i32 @llvm.s390.etnd() + + __builtin_non_tx_store (mem64, 0); +// CHECK: call void @llvm.s390.ntstg(i64 0, i64* %{{.*}}) + const uint64_t val_var = 0x1122334455667788; + __builtin_non_tx_store (mem64, val_var); +// CHECK: call void @llvm.s390.ntstg(i64 1234605616436508552, i64* %{{.*}}) + __builtin_non_tx_store (mem64, (uint64_t)reg); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* %{{.*}}) + __builtin_non_tx_store (mem64, g); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* %{{.*}}) + __builtin_non_tx_store ((uint64_t *)0, 0); +// CHECK: call void @llvm.s390.ntstg(i64 0, i64* null) + __builtin_non_tx_store ((uint64_t *)0x12345678, 0); +// CHECK: call void @llvm.s390.ntstg(i64 0, i64* inttoptr (i64 305419896 to i64*)) + __builtin_non_tx_store (&g, 23); +// CHECK: call void @llvm.s390.ntstg(i64 23, i64* @g) + __builtin_non_tx_store (&g, reg); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* @g) + __builtin_non_tx_store (&g, *mem); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* @g) + __builtin_non_tx_store (&g, global); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* @g) + + __builtin_tx_assist (0); +// CHECK: call void @llvm.s390.ppa.txassist(i32 0) + __builtin_tx_assist (1); +// CHECK: call void @llvm.s390.ppa.txassist(i32 1) + __builtin_tx_assist (reg); +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tx_assist (*mem); +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tx_assist (global); +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) +} + +#include <htmxlintrin.h> + +void test_htmxl1(void) { +// CHECK-LABEL: test_htmxl1 + + struct __htm_tdb tdb_struct; + void * const tdb = &tdb_struct; + long result; + unsigned char code; + + result = __TM_simple_begin (); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* null, i32 65292) + result = __TM_begin (tdb); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* %{{.*}}, i32 65292) + result = __TM_end (); +// CHECK: call i32 @llvm.s390.tend() + __TM_abort (); +// CHECK: call void @llvm.s390.tabort(i64 256) + __TM_named_abort (42); +// CHECK: call void @llvm.s390.tabort(i64 %{{.*}}) + __TM_non_transactional_store (&g, 42); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* %{{.*}}) + result = __TM_nesting_depth (tdb); +// CHECK: call i32 @llvm.s390.etnd() + + result = __TM_is_user_abort (tdb); + result = __TM_is_named_user_abort (tdb, &code); + result = __TM_is_illegal (tdb); + result = __TM_is_footprint_exceeded (tdb); + result = __TM_is_nested_too_deep (tdb); + result = __TM_is_conflict (tdb); + result = __TM_is_failure_persistent (result); + result = __TM_failure_address (tdb); + result = __TM_failure_code (tdb); +} + diff --git a/test/CodeGen/call.c b/test/CodeGen/call.c index ef327751b3..723911158c 100644 --- a/test/CodeGen/call.c +++ b/test/CodeGen/call.c @@ -18,7 +18,7 @@ void JS_ReportErrorNumber(JSErrorCallback errorCallback, ...); void Interpret() { JS_ReportErrorNumber(js_GetErrorMessage, 0); - // CHECK: call void ({{.*}}, ...)* @JS_ReportErrorNumber({{.*}}@js_GetErrorMessage + // CHECK: call void ({{.*}}, ...) @JS_ReportErrorNumber({{.*}}@js_GetErrorMessage } diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c index 1ed288b57d..a438658875 100644 --- a/test/CodeGen/catch-undef-behavior.c +++ b/test/CodeGen/catch-undef-behavior.c @@ -380,7 +380,7 @@ void call_nonnull_variadic(int a, int *b) { // CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg // CHECK-UBSAN-NOT: __ubsan_handle_nonnull_arg - // CHECK-COMMON: call void (i32, ...)* @nonnull_variadic + // CHECK-COMMON: call void (i32, ...) @nonnull_variadic nonnull_variadic(a, b); } diff --git a/test/CodeGen/exceptions-seh-finally.c b/test/CodeGen/exceptions-seh-finally.c index eeadf0d5ec..a594aaac05 100644 --- a/test/CodeGen/exceptions-seh-finally.c +++ b/test/CodeGen/exceptions-seh-finally.c @@ -17,30 +17,20 @@ void basic_finally(void) { // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[invoke_cont]] -// CHECK: store i8 0, i8* %[[abnormal:[^ ]*]] -// CHECK: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] -// CHECK: call void @cleanup() -// CHECK: load i8, i8* %[[abnormal]] -// CHECK: icmp eq -// CHECK: br i1 %{{.*}}, label %[[finallycont:[^ ]*]], label %[[resumecont:[^ ]*]] -// -// CHECK: [[finallycont]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i1 zeroext false, i8* %[[fp]]) // CHECK-NEXT: ret void // // CHECK: [[lpad]] // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: store i8 1, i8* %[[abnormal]] -// CHECK: br label %[[finally]] -// -// CHECK: [[resumecont]] -// CHECK: br label %[[ehresume:[^ ]*]] -// -// CHECK: [[ehresume]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i1 zeroext true, i8* %[[fp]]) // CHECK: resume { i8*, i32 } +// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: call void @cleanup() + // Mostly check that we don't double emit 'r' which would crash. void decl_in_finally(void) { __try { @@ -67,10 +57,11 @@ l: // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[invoke_cont]] -// CHECK: store i8 0, i8* %[[abnormal:[^ ]*]] -// CHECK: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@label_in_finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: ret void + +// CHECK: define internal void @"\01?fin$0@0@label_in_finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) // CHECK: br label %[[l:[^ ]*]] // // CHECK: [[l]] @@ -93,32 +84,22 @@ void use_abnormal_termination(void) { // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[invoke_cont]] -// CHECK: store i8 0, i8* %[[abnormal:[^ ]*]] -// CHECK: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] -// CHECK: load i8, i8* %[[abnormal]] -// CHECK: zext i8 %{{.*}} to i32 -// CHECK: store i32 %{{.*}}, i32* @crashed -// CHECK: load i8, i8* %[[abnormal]] -// CHECK: icmp eq -// CHECK: br i1 %{{.*}}, label %[[finallycont:[^ ]*]], label %[[resumecont:[^ ]*]] -// -// CHECK: [[finallycont]] -// CHECK-NEXT: ret void +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: ret void // // CHECK: [[lpad]] // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: store i8 1, i8* %[[abnormal]] -// CHECK: br label %[[finally]] -// -// CHECK: [[resumecont]] -// CHECK: br label %[[ehresume:[^ ]*]] -// -// CHECK: [[ehresume]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"(i1 zeroext true, i8* %[[fp]]) // CHECK: resume { i8*, i32 } +// CHECK: define internal void @"\01?fin$0@0@use_abnormal_termination@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: %[[abnormal_zext:[^ ]*]] = zext i1 %abnormal_termination to i32 +// CHECK: store i32 %[[abnormal_zext]], i32* @crashed +// CHECK-NEXT: ret void + void noreturn_noop_finally() { __try { __noop(); @@ -128,12 +109,13 @@ void noreturn_noop_finally() { } // CHECK-LABEL: define void @noreturn_noop_finally() -// CHECK: store i8 0, i8* % -// CHECK: br label %[[finally:[^ ]*]] -// CHECK: [[finally]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@noreturn_noop_finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: ret void + +// CHECK: define internal void @"\01?fin$0@0@noreturn_noop_finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) // CHECK: call void @abort() -// CHECK-NEXT: unreachable -// CHECK-NOT: load +// CHECK: unreachable void noreturn_finally() { __try { @@ -148,18 +130,20 @@ void noreturn_finally() { // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[cont]] -// CHECK: store i8 0, i8* % -// CHECK: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] -// CHECK: call void @abort() -// CHECK-NEXT: unreachable +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: ret void // // CHECK: [[lpad]] // CHECK: landingpad // CHECK-NEXT: cleanup -// CHECK: store i8 1, i8* % -// CHECK: br label %[[finally]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"(i1 zeroext true, i8* %[[fp]]) +// CHECK: resume { i8*, i32 } + +// CHECK: define internal void @"\01?fin$0@0@noreturn_finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: call void @abort() +// CHECK: unreachable int finally_with_return() { __try { @@ -168,15 +152,15 @@ int finally_with_return() { } } // CHECK-LABEL: define i32 @finally_with_return() -// CHECK: store i8 0, i8* % -// CHECK-NEXT: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] -// CHECK-NEXT: br label %[[finallycont:[^ ]*]] -// -// CHECK: [[finallycont]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@finally_with_return@@"(i1 zeroext false, i8* %[[fp]]) // CHECK-NEXT: ret i32 42 +// CHECK: define internal void @"\01?fin$0@0@finally_with_return@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK-NOT: br i1 +// CHECK-NOT: br label +// CHECK: ret void + int nested___finally___finally() { __try { __try { @@ -188,38 +172,28 @@ int nested___finally___finally() { } return 0; } + // CHECK-LABEL: define i32 @nested___finally___finally -// CHECK: store i8 0, i8* % -// CHECK-NEXT: br label %[[finally:[^ ]*]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // -// CHECK: [[finally]] -// CHECK-NEXT: store i32 1, i32* % -// CHECK-NEXT: store i32 1, i32* % -// CHECK-NEXT: br label %[[cleanup:[^ ]*]] +// CHECK: [[outercont]] +// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK-NEXT: ret i32 0 // -// The finally's unreachable continuation block: -// CHECK: store i32 0, i32* % -// CHECK-NEXT: br label %[[cleanup]] -// -// CHECK: [[cleanup]] -// CHECK-NEXT: store i8 0, i8* % -// CHECK-NEXT: br label %[[outerfinally:[^ ]*]] -// -// CHECK: [[outerfinally]] -// CHECK-NEXT: br label %[[finallycont:[^ ]*]] -// -// CHECK: [[finallycont]] -// CHECK-NEXT: %[[dest:[^ ]*]] = load i32, i32* % -// CHECK-NEXT: switch i32 %[[dest]] -// CHECK-NEXT: i32 0, label %[[cleanupcont:[^ ]*]] -// -// CHECK: [[cleanupcont]] -// CHECK-NEXT: store i32 0, i32* % -// CHECK-NEXT: br label %[[return:[^ ]*]] -// -// CHECK: [[return]] -// CHECK-NEXT: %[[reg:[^ ]*]] = load i32, i32* % -// CHECK-NEXT: ret i32 %[[reg]] +// CHECK: [[lpad]] +// CHECK-NEXT: landingpad +// CHECK-NEXT: cleanup +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext true, i8* %[[fp]]) + +// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: ret void + +// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: unreachable int nested___finally___finally_with_eh_edge() { __try { @@ -234,58 +208,35 @@ int nested___finally___finally_with_eh_edge() { return 912; } // CHECK-LABEL: define i32 @nested___finally___finally_with_eh_edge -// CHECK: invoke void @might_crash() #3 -// CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad:[^ ]*]] -// -// CHECK: [[invokecont]] -// CHECK-NEXT: store i8 0, i8* %[[abnormal:[^ ]*]] -// CHECK-NEXT: br label %[[finally:[^ ]*]] - -// CHECK: [[finally]] -// CHECK-NEXT: store i32 899, i32* % -// CHECK-NEXT: store i32 1, i32* % -// CHECK-NEXT: br label %[[cleanup:[^ ]*]] -// -// The inner finally's unreachable continuation block: -// CHECK: store i32 0, i32* % -// CHECK-NEXT: br label %[[cleanup]] -// -// CHECK: [[cleanup]] -// CHECK-NEXT: store i8 0, i8* % -// CHECK-NEXT: br label %[[outerfinally:[^ ]*]] -// -// CHECK: [[outerfinally]] -// CHECK-NEXT: %[[abnormallocal:[^ ]*]] = load i8, i8* %[[abnormal]] -// CHECK-NEXT: %[[reg:[^ ]*]] = icmp eq i8 %[[abnormallocal]], 0 -// CHECK-NEXT: br i1 %[[reg]], label %[[finallycont:[^ ]*]], label %[[finallyresume:[^ ]*]] -// -// CHECK: [[finallycont]] -// CHECK-NEXT: %[[dest:[^ ]*]] = load i32, i32* % -// CHECK-NEXT: switch i32 %[[dest]] -// CHECK-NEXT: i32 0, label %[[cleanupcont:[^ ]*]] +// CHECK: invoke void @might_crash() +// CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad1:[^ ]*]] // -// CHECK: [[cleanupcont]] -// CHECK-NEXT: store i32 912, i32* % -// CHECK-NEXT: br label %[[return:[^ ]*]] +// [[invokecont]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]] // +// CHECK: [[outercont]] +// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK-NEXT: ret i32 912 // -// CHECK: [[lpad]] +// CHECK: [[lpad1]] // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: store i8 1, i8* %[[abnormal]] -// CHECK: br label %[[finally]] -// -// The inner finally's unreachable resume block: -// CHECK: store i8 1, i8* %[[abnormal]] -// CHECK-NEXT: br label %[[outerfinally]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext true, i8* %[[fp]]) +// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad2]] // -// CHECK: [[finallyresume]] -// CHECK-NEXT: br label %[[ehresume:[^ ]*]] -// -// CHECK: [[return]] -// CHECK-NEXT: %[[reg:[^ ]*]] = load i32, i32* % -// CHECK-NEXT: ret i32 %[[reg]] -// -// The ehresume block, not reachable either. -// CHECK: [[ehresume]] +// CHECK: [[lpad2]] +// CHECK-NEXT: landingpad +// CHECK-NEXT: cleanup +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext true, i8* %[[fp]]) // CHECK: resume + +// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: ret void + +// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: unreachable diff --git a/test/CodeGen/exceptions-seh-leave.c b/test/CodeGen/exceptions-seh-leave.c index 0d38439c9b..793501a9fe 100644 --- a/test/CodeGen/exceptions-seh-leave.c +++ b/test/CodeGen/exceptions-seh-leave.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s -void g(); +void g(void); ////////////////////////////////////////////////////////////////////////////// // __leave with __except @@ -38,7 +38,7 @@ int __leave_with___except() { return 1; } // CHECK-LABEL: define i32 @__leave_with___except() -// CHECK: invoke void bitcast (void (...)* @g to void ()*)() +// CHECK: invoke void @g() // CHECK-NEXT: to label %[[cont:.*]] unwind label %{{.*}} // For __excepts, instead of an explicit __try.__leave label, we could use // use invoke.cont as __leave jump target instead. However, not doing this @@ -74,8 +74,8 @@ int __leave_with___finally_simple() { // CHECK-NEXT: br label %[[tryleave:[^ ]*]] // CHECK-NOT: store i32 23 // CHECK: [[tryleave]] -// CHECK-NEXT: store i8 0, i8* % -// CHECK-NEXT: br label % +// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally_simple@@"(i1 zeroext false, i8* %[[fp]]) // __finally block doesn't return, __finally.cont doesn't exist. int __leave_with___finally_noreturn() { @@ -94,8 +94,8 @@ int __leave_with___finally_noreturn() { // CHECK-NEXT: br label %[[tryleave:[^ ]*]] // CHECK-NOT: store i32 23 // CHECK: [[tryleave]] -// CHECK-NEXT: store i8 0, i8* % -// CHECK-NEXT: br label % +// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally_noreturn@@"(i1 zeroext false, i8* %[[fp]]) // The "normal" case. int __leave_with___finally() { @@ -110,7 +110,7 @@ int __leave_with___finally() { return 1; } // CHECK-LABEL: define i32 @__leave_with___finally() -// CHECK: invoke void bitcast (void (...)* @g to void ()*)() +// CHECK: invoke void @g() // CHECK-NEXT: to label %[[cont:.*]] unwind label %{{.*}} // For __finally, there needs to be an explicit __try.__leave, because // abnormal.termination.slot needs to be set there. @@ -118,8 +118,8 @@ int __leave_with___finally() { // CHECK-NEXT: br label %[[tryleave:[^ ]*]] // CHECK-NOT: store i32 23 // CHECK: [[tryleave]] -// CHECK-NEXT: store i8 0, i8* % -// CHECK-NEXT: br label % +// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally@@"(i1 zeroext false, i8* %[[fp]]) ////////////////////////////////////////////////////////////////////////////// @@ -142,45 +142,37 @@ int nested___except___finally() { } return 1; } -// The order of basic blocks in the below doesn't matter. // CHECK-LABEL: define i32 @nested___except___finally() -// CHECK-LABEL: invoke void bitcast (void (...)* @g to void ()*)() -// CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] - -// CHECK: [[g1_cont]] -// CHECK-NEXT: store i8 0, i8* %[[abnormal:[^ ]*]] -// CHECK-NEXT: br label %[[finally:[^ ]*]] +// CHECK-LABEL: invoke void @g() +// CHECK-NEXT: to label %[[g1_cont1:.*]] unwind label %[[g1_lpad:.*]] -// CHECK: [[finally]] -// CHECK-NEXT: invoke void bitcast (void (...)* @g to void ()*)() -// CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] - -// CHECK: [[g2_cont]] -// CHECK-NEXT: br label %[[tryleave:[^ ]*]] -// CHECK-NOT: store i32 23 +// CHECK: [[g1_cont1]] +// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: invoke void @"\01?fin$0@0@nested___except___finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK-NEXT: to label %[[fin_cont:.*]] unwind label %[[g2_lpad:.*]] -// Unused __finally continuation block +// CHECK: [[fin_cont]] // CHECK: store i32 51, i32* % -// CHECK-NEXT: br label %[[tryleave]] - -// CHECK: [[tryleave]] // CHECK-NEXT: br label %[[trycont:[^ ]*]] // CHECK: [[g1_lpad]] -// CHECK: store i8 1, i8* % -// CHECK-NEXT: br label %[[finally]] +// CHECK-NEXT: landingpad +// CHECK-NEXT: catch i8* null +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: invoke void @"\01?fin$0@0@nested___except___finally@@"(i1 zeroext true, i8* %[[fp]]) +// CHECK-NEXT: to label %[[g1_resume:.*]] unwind label %[[g2_lpad]] // CHECK: [[g2_lpad]] -// CHECK-NOT: %[[abnormal]] -// CHECK: br label %[[except:[^ ]*]] - -// CHECK: [[except]] -// CHECK-NEXT: br label %[[trycont]] +// CHECK: br label %[[trycont]] // CHECK: [[trycont]] // CHECK-NEXT: ret i32 1 +// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___except___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: call void @g() +// CHECK: unreachable + int nested___except___except() { int myres = 0; __try { @@ -202,7 +194,7 @@ int nested___except___except() { // The order of basic blocks in the below doesn't matter. // CHECK-LABEL: define i32 @nested___except___except() -// CHECK-LABEL: invoke void bitcast (void (...)* @g to void ()*)() +// CHECK-LABEL: invoke void @g() // CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] // CHECK: [[g1_cont]] @@ -213,7 +205,7 @@ int nested___except___except() { // CHECK: br label %[[except:[^ ]*]] // CHECK: [[except]] -// CHECK-NEXT: invoke void bitcast (void (...)* @g to void ()*)() #3 +// CHECK-NEXT: invoke void @g() // CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] // CHECK: [[g2_cont]] @@ -256,7 +248,7 @@ int nested___finally___except() { // The order of basic blocks in the below doesn't matter. // CHECK-LABEL: define i32 @nested___finally___except() -// CHECK-LABEL: invoke void bitcast (void (...)* @g to void ()*)() +// CHECK-LABEL: invoke void @g() // CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] // CHECK: [[g1_cont]] @@ -266,7 +258,7 @@ int nested___finally___except() { // CHECK: br label %[[except:[^ ]*]] // CHECK: [[except]] -// CHECK-NEXT: invoke void bitcast (void (...)* @g to void ()*)() +// CHECK-NEXT: invoke void @g() // CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] // CHECK: [[g2_cont]] @@ -274,31 +266,25 @@ int nested___finally___except() { // CHECK-NOT: 23 // CHECK: [[g2_lpad]] -// CHECK: store i8 1, i8* %[[abnormal:[^ ]*]] -// CHECK-NEXT: br label %[[finally:[^ ]*]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___except@@"(i1 zeroext true, i8* %[[fp]]) +// CHECK-NEXT: br label %[[ehresume:[^ ]*]] // CHECK: [[trycont]] // CHECK: store i32 51, i32* % // CHECK-NEXT: br label %[[tryleave]] // CHECK: [[tryleave]] -// CHECK-NEXT: store i8 0, i8* %[[abnormal]] -// CHECK-NEXT: br label %[[finally:[^ ]*]] - -// CHECK: [[finally]] -// CHECK-NEXT: %[[abnormallocal:[^ ]*]] = load i8, i8* %[[abnormal]] -// CHECK-NEXT: %[[reg:[^ ]*]] = icmp eq i8 %[[abnormallocal]], 0 -// CHECK-NEXT: br i1 %[[reg]], label %[[finallycont:[^ ]*]], label %[[finallyresume:[^ ]*]] - -// CHECK: [[finallycont]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___except@@"(i1 zeroext false, i8* %[[fp]]) // CHECK-NEXT: ret i32 1 -// CHECK: [[finallyresume]] -// CHECK-NEXT: br label %[[ehresume:[^ ]*]] - // CHECK: [[ehresume]] // CHECK: resume +// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___except@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: ret void + int nested___finally___finally() { int myres = 0; __try { @@ -320,51 +306,44 @@ int nested___finally___finally() { // The order of basic blocks in the below doesn't matter. // CHECK-LABEL: define i32 @nested___finally___finally() -// CHECK-LABEL: invoke void bitcast (void (...)* @g to void ()*)() +// CHECK-LABEL: invoke void @g() // CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] // CHECK: [[g1_cont]] // CHECK: store i32 16, i32* %[[myres:[^ ]*]], -// CHECK: store i8 0, i8* %[[abnormal:[^ ]*]] -// CHECK-NEXT: br label %[[finally:[^ ]*]] - -// CHECK: [[finally]] -// CHECK-NEXT: invoke void bitcast (void (...)* @g to void ()*)() #3 -// CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] - -// CHECK: [[g2_cont]] -// CHECK-NEXT: br label %[[tryleave:[^ ]*]] -// CHECK-NOT: store i32 23 +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: invoke void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK-NEXT: to label %[[finally_cont:.*]] unwind label %[[g2_lpad:.*]] -// There's an unreachable block for the skipped `myres = 51`. +// CHECK: [[finally_cont]] // CHECK: store i32 51, i32* %[[myres]] -// CHECK-NEXT: br label %[[tryleave]] - -// CHECK: [[tryleave]] -// CHECK-NEXT: store i8 0, i8* %[[abnormal]] -// CHECK-NEXT: br label %[[outerfinally:[^ ]*]] - -// CHECK: [[outerfinally]] -// CHECK-NEXT: %[[abnormallocal:[^ ]*]] = load i8, i8* %[[abnormal]] -// CHECK-NEXT: %[[reg:[^ ]*]] = icmp eq i8 %[[abnormallocal]], 0 -// CHECK-NEXT: br i1 %[[reg]], label %[[finallycont:[^ ]*]], label %[[finallyresume:[^ ]*]] - -// CHECK: [[finallycont]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext false, i8* %[[fp]]) // CHECK-NEXT: ret i32 1 // CHECK: [[g1_lpad]] -// CHECK: store i8 1, i8* %[[abnormal]] -// CHECK-NEXT: br label %[[finally:[^ ]*]] +// CHECK-NEXT: landingpad +// CHECK-NEXT: cleanup +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: invoke void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext true, i8* %[[fp]]) +// CHECK-NEXT: to label %[[finally_cont2:.*]] unwind label %[[g2_lpad]] // CHECK: [[g2_lpad]] -// CHECK: br label %[[ehcleanup:[^ ]*]] +// CHECK-NEXT: landingpad +// CHECK-NEXT: cleanup +// CHECK: br label %[[ehcleanup:.*]] + +// CHECK: [[finally_cont2]] +// CHECK: br label %[[ehcleanup]] // CHECK: [[ehcleanup]] -// CHECK-NEXT: store i8 1, i8* %[[abnormal]] -// CHECK-NEXT: br label %[[outerfinally]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext true, i8* %[[fp]]) +// CHECK: resume -// CHECK: [[finallyresume]] -// CHECK-NEXT: br label %[[ehresume:[^ ]*]] +// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: ret void -// CHECK: [[ehresume]] -// CHECK: resume +// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: call void @g() +// CHECK: unreachable diff --git a/test/CodeGen/exceptions-seh.c b/test/CodeGen/exceptions-seh.c index 2d9d4b1f01..9a273ced56 100644 --- a/test/CodeGen/exceptions-seh.c +++ b/test/CodeGen/exceptions-seh.c @@ -118,8 +118,6 @@ int nested_try(void) { // CHECK: [[inner_try_cont]] // CHECK: br label %[[outer_try_cont]] -// FIXME: This lowering of __finally can't actually work, it will have to -// change. static unsigned g = 0; void basic_finally(void) { ++g; @@ -138,24 +136,23 @@ void basic_finally(void) { // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[cont]] -// CHECK: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] -// CHECK: load i32, i32* @g -// CHECK: add i32 %{{.*}}, -1 -// CHECK: store i32 %{{.*}}, i32* @g -// CHECK: icmp eq -// CHECK: br i1 %{{.*}}, label -// +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i1 zeroext false, i8* %[[fp]]) // CHECK: ret void // // CHECK: [[lpad]] // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) // CHECK-NEXT: cleanup -// CHECK: br label %[[finally]] -// +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i1 zeroext true, i8* %[[fp]]) // CHECK: resume +// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: load i32, i32* @g, align 4 +// CHECK: add i32 %{{.*}}, -1 +// CHECK: store i32 %{{.*}}, i32* @g, align 4 +// CHECK: ret void + int returns_int(void); int except_return(void) { __try { diff --git a/test/CodeGen/finite-math.c b/test/CodeGen/finite-math.c index fd8fcf6fad..8365b56fe5 100644 --- a/test/CodeGen/finite-math.c +++ b/test/CodeGen/finite-math.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -ffinite-math-only -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FINITE // RUN: %clang_cc1 -fno-signed-zeros -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=NSZ +// RUN: %clang_cc1 -freciprocal-math -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=RECIP float f0, f1, f2; @@ -8,6 +9,7 @@ void foo(void) { // FINITE: fadd nnan ninf // NSZ: fadd nsz + // RECIP: fadd arcp f0 = f1 + f2; // CHECK: ret diff --git a/test/CodeGen/mangle-windows.c b/test/CodeGen/mangle-windows.c index 4a108751aa..db39425da8 100644 --- a/test/CodeGen/mangle-windows.c +++ b/test/CodeGen/mangle-windows.c @@ -1,15 +1,26 @@ // RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s // RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-mingw32 | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-windows-msvc-elf | FileCheck %s --check-prefix=ELF32 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s --check-prefix=X64 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-mingw32 | FileCheck %s --check-prefix=X64 +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc-elf | FileCheck %s --check-prefix=ELF64 + +// CHECK: target datalayout = "e-m:x-{{.*}}" +// X64: target datalayout = "e-m:w-{{.*}}" +// ELF32: target datalayout = "e-m:e-{{.*}}" +// ELF64: target datalayout = "e-m:e-{{.*}}" void __stdcall f1(void) {} // CHECK: define x86_stdcallcc void @"\01_f1@0" // X64: define void @f1( +// ELF32: define x86_stdcallcc void @"\01_f1@0" +// ELF64: define void @f1( void __fastcall f2(void) {} // CHECK: define x86_fastcallcc void @"\01@f2@0" // X64: define void @f2( +// ELF32: define x86_fastcallcc void @"\01@f2@0" +// ELF64: define void @f2( void __stdcall f3() {} // CHECK: define x86_stdcallcc void @"\01_f3@0" @@ -46,10 +57,14 @@ void f12(void) {} void __vectorcall v1(void) {} // CHECK: define x86_vectorcallcc void @"\01v1@@0"( // X64: define x86_vectorcallcc void @"\01v1@@0"( +// ELF32: define x86_vectorcallcc void @"\01v1@@0"( +// ELF64: define x86_vectorcallcc void @"\01v1@@0"( void __vectorcall v2(char a) {} // CHECK: define x86_vectorcallcc void @"\01v2@@4"( // X64: define x86_vectorcallcc void @"\01v2@@8"( +// ELF32: define x86_vectorcallcc void @"\01v2@@4"( +// ELF64: define x86_vectorcallcc void @"\01v2@@8"( void __vectorcall v3(short a) {} // CHECK: define x86_vectorcallcc void @"\01v3@@4"( diff --git a/test/CodeGen/mcount.c b/test/CodeGen/mcount.c index 5c608bcd36..99dc90795b 100644 --- a/test/CodeGen/mcount.c +++ b/test/CodeGen/mcount.c @@ -1,8 +1,18 @@ // RUN: %clang_cc1 -pg -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -pg -triple powerpc-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PPC %s -// RUN: %clang_cc1 -pg -triple powerpc64-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PPC %s -// RUN: %clang_cc1 -pg -triple powerpc64le-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PPC %s +// RUN: %clang_cc1 -pg -triple powerpc-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple powerpc64-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple powerpc64le-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple i386-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple x86_64-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple arm-netbsd-eabi -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple aarch64-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple mips-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple powerpc-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple powerpc64-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple powerpc64le-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple sparc-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s +// RUN: %clang_cc1 -pg -triple sparc64-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s void foo(void) { // CHECK: call void @mcount() -// CHECK-PPC: call void @_mcount() +// CHECK-PREFIXED: call void @_mcount() } diff --git a/test/CodeGen/mips-inline-asm.c b/test/CodeGen/mips-inline-asm.c new file mode 100644 index 0000000000..2cfa41c98d --- /dev/null +++ b/test/CodeGen/mips-inline-asm.c @@ -0,0 +1,19 @@ +// REQUIRES: mips-registered-target +// RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm -o - %s | FileCheck %s + +int data; + +void m () { + asm("lw $1, %0" :: "m"(data)); + // CHECK: call void asm sideeffect "lw $$1, $0", "*m,~{$1}"(i32* @data) +} + +void ZC () { + asm("ll $1, %0" :: "ZC"(data)); + // CHECK: call void asm sideeffect "ll $$1, $0", "*^ZC,~{$1}"(i32* @data) +} + +void R () { + asm("lw $1, %0" :: "R"(data)); + // CHECK: call void asm sideeffect "lw $$1, $0", "*R,~{$1}"(i32* @data) +} diff --git a/test/CodeGen/mips-unsupported-nan.c b/test/CodeGen/mips-unsupported-nan.c new file mode 100644 index 0000000000..14a36fc029 --- /dev/null +++ b/test/CodeGen/mips-unsupported-nan.c @@ -0,0 +1,25 @@ +// RUN: %clang -target mipsel-unknown-linux -mnan=2008 -march=mips2 -emit-llvm -S %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MIPS2 -check-prefix=CHECK-NANLEGACY %s +// RUN: %clang -target mips64el-unknown-linux -mnan=2008 -march=mips3 -emit-llvm -S %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MIPS3 -check-prefix=CHECK-NANLEGACY %s +// RUN: %clang -target mips64el-unknown-linux -mnan=2008 -march=mips4 -emit-llvm -S %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MIPS4 -check-prefix=CHECK-NANLEGACY %s +// RUN: %clang -target mipsel-unknown-linux -mnan=2008 -march=mips32 -emit-llvm -S %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MIPS32 -check-prefix=CHECK-NANLEGACY %s +// RUN: %clang -target mipsel-unknown-linux -mnan=2008 -march=mips32r2 -emit-llvm -S %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MIPS32R2 -check-prefix=CHECK-NANLEGACY %s +// RUN: %clang -target mipsel-unknown-linux -mnan=2008 -march=mips32r3 -emit-llvm -S %s -o - 2>&1 | FileCheck -check-prefix=CHECK-NOT-MIPS32R3 -check-prefix=CHECK-NAN2008 %s +// RUN: %clang -target mipsel-unknown-linux -mnan=legacy -march=mips32r6 -emit-llvm -S %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MIPS32R6 -check-prefix=CHECK-NAN2008 %s +// RUN: %clang -target mips64el-unknown-linux -mnan=2008 -march=mips64 -emit-llvm -S %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MIPS64 -check-prefix=CHECK-NANLEGACY %s +// RUN: %clang -target mips64el-unknown-linux -mnan=2008 -march=mips64r2 -emit-llvm -S %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MIPS64R2 -check-prefix=CHECK-NANLEGACY %s +// RUN: %clang -target mips64el-unknown-linux -mnan=legacy -march=mips64r6 -emit-llvm -S %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MIPS64R6 -check-prefix=CHECK-NAN2008 %s + +// CHECK-MIPS2: warning: ignoring '-mnan=2008' option because the 'mips2' architecture does not support it +// CHECK-MIPS3: warning: ignoring '-mnan=2008' option because the 'mips3' architecture does not support it +// CHECK-MIPS4: warning: ignoring '-mnan=2008' option because the 'mips4' architecture does not support it +// CHECK-MIPS32: warning: ignoring '-mnan=2008' option because the 'mips32' architecture does not support it +// CHECK-MIPS32R2: warning: ignoring '-mnan=2008' option because the 'mips32r2' architecture does not support it +// CHECK-MIPS32R3: warning: ignoring '-mnan=2008' option because the 'mips32r3' architecture does not support it +// CHECK-MIPS32R6: warning: ignoring '-mnan=legacy' option because the 'mips32r6' architecture does not support it +// CHECK-MIPS64: warning: ignoring '-mnan=2008' option because the 'mips64' architecture does not support it +// CHECK-MIPS64R2: warning: ignoring '-mnan=2008' option because the 'mips64r2' architecture does not support it +// CHECK-MIPS64R6: warning: ignoring '-mnan=legacy' option because the 'mips64r6' architecture does not support it +// CHECK-NANLEGACY: float 0x7FF4000000000000 +// CHECK-NAN2008: float 0x7FF8000000000000 + +float f = __builtin_nan(""); diff --git a/test/CodeGen/mrtd.c b/test/CodeGen/mrtd.c index f929d4c26b..8d2aeeec49 100644 --- a/test/CodeGen/mrtd.c +++ b/test/CodeGen/mrtd.c @@ -23,6 +23,6 @@ void quux(int a1, int a2, int a3) { qux(a1, a2, a3); } // CHECK-LABEL: define x86_stdcallcc void @quux -// CHECK: call void (i32, ...)* @qux +// CHECK: call void (i32, ...) @qux // CHECK: attributes [[NUW]] = { nounwind{{.*}} } diff --git a/test/CodeGen/ms-declspecs.c b/test/CodeGen/ms-declspecs.c index 328fc835d3..c32733e65f 100644 --- a/test/CodeGen/ms-declspecs.c +++ b/test/CodeGen/ms-declspecs.c @@ -5,6 +5,12 @@ const __declspec(selectany) int x2 = 2; // CHECK: @x1 = weak_odr global i32 1, comdat, align 4 // CHECK: @x2 = weak_odr constant i32 2, comdat, align 4 +// selectany turns extern variable declarations into definitions. +__declspec(selectany) int x3; +extern __declspec(selectany) int x4; +// CHECK: @x3 = weak_odr global i32 0, comdat, align 4 +// CHECK: @x4 = weak_odr global i32 0, comdat, align 4 + struct __declspec(align(16)) S { char x; }; diff --git a/test/CodeGen/ms-declspecs.cpp b/test/CodeGen/ms-declspecs.cpp new file mode 100644 index 0000000000..decf5d6fcb --- /dev/null +++ b/test/CodeGen/ms-declspecs.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -o - | FileCheck %s + +// selectany turns extern "C" variable declarations into definitions. +extern __declspec(selectany) int x1; +extern "C" __declspec(selectany) int x2; +extern "C++" __declspec(selectany) int x3; +extern "C" { +__declspec(selectany) int x4; +} +__declspec(selectany) int x5; +// CHECK: @"\01?x1@@3HA" = weak_odr global i32 0, comdat, align 4 +// CHECK: @x2 = weak_odr global i32 0, comdat, align 4 +// CHECK: @"\01?x3@@3HA" = weak_odr global i32 0, comdat, align 4 +// CHECK: @x4 = weak_odr global i32 0, comdat, align 4 +// CHECK: @"\01?x5@@3HA" = weak_odr global i32 0, comdat, align 4 diff --git a/test/CodeGen/ms-setjmp.c b/test/CodeGen/ms-setjmp.c index 78928bb716..675c8dda27 100644 --- a/test/CodeGen/ms-setjmp.c +++ b/test/CodeGen/ms-setjmp.c @@ -14,7 +14,7 @@ jmp_buf jb; int test_setjmp() { return _setjmp(jb); // I386-LABEL: define i32 @test_setjmp - // I386: %[[call:.*]] = call i32 (i8*, i32, ...)* @_setjmp3(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i32 0) + // I386: %[[call:.*]] = call i32 (i8*, i32, ...) @_setjmp3(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i32 0) // I386-NEXT: ret i32 %[[call]] // X64-LABEL: define i32 @test_setjmp diff --git a/test/CodeGen/nvptx-cpus.c b/test/CodeGen/nvptx-cpus.c index c9c7680d67..015f52946e 100644 --- a/test/CodeGen/nvptx-cpus.c +++ b/test/CodeGen/nvptx-cpus.c @@ -2,6 +2,7 @@ // 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 +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_37 -O3 -S -o %t %s -emit-llvm // Make sure clang accepts all supported architectures. diff --git a/test/CodeGen/pr5406.c b/test/CodeGen/pr5406.c index 0f04a8e069..69038ac07f 100644 --- a/test/CodeGen/pr5406.c +++ b/test/CodeGen/pr5406.c @@ -6,7 +6,7 @@ typedef struct { char x[3]; } A0; void foo (int i, ...); -// CHECK: call void (i32, ...)* @foo(i32 1, [1 x i32] {{.*}}) +// CHECK: call void (i32, ...) @foo(i32 1, [1 x i32] {{.*}}) int main (void) { A0 a3; diff --git a/test/CodeGen/systemz-abi-vector.c b/test/CodeGen/systemz-abi-vector.c new file mode 100644 index 0000000000..06c5f3f8bd --- /dev/null +++ b/test/CodeGen/systemz-abi-vector.c @@ -0,0 +1,245 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// Vector types + +typedef __attribute__((vector_size(1))) char v1i8; + +typedef __attribute__((vector_size(2))) char v2i8; +typedef __attribute__((vector_size(2))) short v1i16; + +typedef __attribute__((vector_size(4))) char v4i8; +typedef __attribute__((vector_size(4))) short v2i16; +typedef __attribute__((vector_size(4))) int v1i32; +typedef __attribute__((vector_size(4))) float v1f32; + +typedef __attribute__((vector_size(8))) char v8i8; +typedef __attribute__((vector_size(8))) short v4i16; +typedef __attribute__((vector_size(8))) int v2i32; +typedef __attribute__((vector_size(8))) long long v1i64; +typedef __attribute__((vector_size(8))) float v2f32; +typedef __attribute__((vector_size(8))) double v1f64; + +typedef __attribute__((vector_size(16))) char v16i8; +typedef __attribute__((vector_size(16))) short v8i16; +typedef __attribute__((vector_size(16))) int v4i32; +typedef __attribute__((vector_size(16))) long long v2i64; +typedef __attribute__((vector_size(16))) __int128 v1i128; +typedef __attribute__((vector_size(16))) float v4f32; +typedef __attribute__((vector_size(16))) double v2f64; +typedef __attribute__((vector_size(16))) long double v1f128; + +typedef __attribute__((vector_size(32))) char v32i8; + +v1i8 pass_v1i8(v1i8 arg) { return arg; } +// CHECK-LABEL: define void @pass_v1i8(<1 x i8>* noalias sret %{{.*}}, <1 x i8>*) + +v2i8 pass_v2i8(v2i8 arg) { return arg; } +// CHECK-LABEL: define void @pass_v2i8(<2 x i8>* noalias sret %{{.*}}, <2 x i8>*) + +v4i8 pass_v4i8(v4i8 arg) { return arg; } +// CHECK-LABEL: define void @pass_v4i8(<4 x i8>* noalias sret %{{.*}}, <4 x i8>*) + +v8i8 pass_v8i8(v8i8 arg) { return arg; } +// CHECK-LABEL: define void @pass_v8i8(<8 x i8>* noalias sret %{{.*}}, <8 x i8>*) + +v16i8 pass_v16i8(v16i8 arg) { return arg; } +// CHECK-LABEL: define void @pass_v16i8(<16 x i8>* noalias sret %{{.*}}, <16 x i8>*) + +v32i8 pass_v32i8(v32i8 arg) { return arg; } +// CHECK-LABEL: define void @pass_v32i8(<32 x i8>* noalias sret %{{.*}}, <32 x i8>*) + +v1i16 pass_v1i16(v1i16 arg) { return arg; } +// CHECK-LABEL: define void @pass_v1i16(<1 x i16>* noalias sret %{{.*}}, <1 x i16>*) + +v2i16 pass_v2i16(v2i16 arg) { return arg; } +// CHECK-LABEL: define void @pass_v2i16(<2 x i16>* noalias sret %{{.*}}, <2 x i16>*) + +v4i16 pass_v4i16(v4i16 arg) { return arg; } +// CHECK-LABEL: define void @pass_v4i16(<4 x i16>* noalias sret %{{.*}}, <4 x i16>*) + +v8i16 pass_v8i16(v8i16 arg) { return arg; } +// CHECK-LABEL: define void @pass_v8i16(<8 x i16>* noalias sret %{{.*}}, <8 x i16>*) + +v1i32 pass_v1i32(v1i32 arg) { return arg; } +// CHECK-LABEL: define void @pass_v1i32(<1 x i32>* noalias sret %{{.*}}, <1 x i32>*) + +v2i32 pass_v2i32(v2i32 arg) { return arg; } +// CHECK-LABEL: define void @pass_v2i32(<2 x i32>* noalias sret %{{.*}}, <2 x i32>*) + +v4i32 pass_v4i32(v4i32 arg) { return arg; } +// CHECK-LABEL: define void @pass_v4i32(<4 x i32>* noalias sret %{{.*}}, <4 x i32>*) + +v1i64 pass_v1i64(v1i64 arg) { return arg; } +// CHECK-LABEL: define void @pass_v1i64(<1 x i64>* noalias sret %{{.*}}, <1 x i64>*) + +v2i64 pass_v2i64(v2i64 arg) { return arg; } +// CHECK-LABEL: define void @pass_v2i64(<2 x i64>* noalias sret %{{.*}}, <2 x i64>*) + +v1i128 pass_v1i128(v1i128 arg) { return arg; } +// CHECK-LABEL: define void @pass_v1i128(<1 x i128>* noalias sret %{{.*}}, <1 x i128>*) + +v1f32 pass_v1f32(v1f32 arg) { return arg; } +// CHECK-LABEL: define void @pass_v1f32(<1 x float>* noalias sret %{{.*}}, <1 x float>*) + +v2f32 pass_v2f32(v2f32 arg) { return arg; } +// CHECK-LABEL: define void @pass_v2f32(<2 x float>* noalias sret %{{.*}}, <2 x float>*) + +v4f32 pass_v4f32(v4f32 arg) { return arg; } +// CHECK-LABEL: define void @pass_v4f32(<4 x float>* noalias sret %{{.*}}, <4 x float>*) + +v1f64 pass_v1f64(v1f64 arg) { return arg; } +// CHECK-LABEL: define void @pass_v1f64(<1 x double>* noalias sret %{{.*}}, <1 x double>*) + +v2f64 pass_v2f64(v2f64 arg) { return arg; } +// CHECK-LABEL: define void @pass_v2f64(<2 x double>* noalias sret %{{.*}}, <2 x double>*) + +v1f128 pass_v1f128(v1f128 arg) { return arg; } +// CHECK-LABEL: define void @pass_v1f128(<1 x fp128>* noalias sret %{{.*}}, <1 x fp128>*) + + +// Accessing variable argument lists + +v1i8 va_v1i8(__builtin_va_list l) { return __builtin_va_arg(l, v1i8); } +// CHECK-LABEL: define void @va_v1i8(<1 x i8>* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}) +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <1 x i8>** +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <1 x i8>** +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <1 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <1 x i8>*, <1 x i8>** [[VA_ARG_ADDR]] +// CHECK: ret void + +v2i8 va_v2i8(__builtin_va_list l) { return __builtin_va_arg(l, v2i8); } +// CHECK-LABEL: define void @va_v2i8(<2 x i8>* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}) +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <2 x i8>** +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <2 x i8>** +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <2 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <2 x i8>*, <2 x i8>** [[VA_ARG_ADDR]] +// CHECK: ret void + +v4i8 va_v4i8(__builtin_va_list l) { return __builtin_va_arg(l, v4i8); } +// CHECK-LABEL: define void @va_v4i8(<4 x i8>* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}) +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <4 x i8>** +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <4 x i8>** +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <4 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <4 x i8>*, <4 x i8>** [[VA_ARG_ADDR]] +// CHECK: ret void + +v8i8 va_v8i8(__builtin_va_list l) { return __builtin_va_arg(l, v8i8); } +// CHECK-LABEL: define void @va_v8i8(<8 x i8>* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}) +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <8 x i8>** +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <8 x i8>** +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <8 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <8 x i8>*, <8 x i8>** [[VA_ARG_ADDR]] +// CHECK: ret void + +v16i8 va_v16i8(__builtin_va_list l) { return __builtin_va_arg(l, v16i8); } +// CHECK-LABEL: define void @va_v16i8(<16 x i8>* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}) +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <16 x i8>** +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <16 x i8>** +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <16 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <16 x i8>*, <16 x i8>** [[VA_ARG_ADDR]] +// CHECK: ret void + +v32i8 va_v32i8(__builtin_va_list l) { return __builtin_va_arg(l, v32i8); } +// CHECK-LABEL: define void @va_v32i8(<32 x i8>* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}) +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <32 x i8>** +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <32 x i8>** +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <32 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <32 x i8>*, <32 x i8>** [[VA_ARG_ADDR]] +// CHECK: ret void + diff --git a/test/CodeGen/systemz-abi.c b/test/CodeGen/systemz-abi.c new file mode 100644 index 0000000000..5599c79e90 --- /dev/null +++ b/test/CodeGen/systemz-abi.c @@ -0,0 +1,586 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// Scalar types + +char pass_char(char arg) { return arg; } +// CHECK-LABEL: define signext i8 @pass_char(i8 signext %{{.*}}) + +short pass_short(short arg) { return arg; } +// CHECK-LABEL: define signext i16 @pass_short(i16 signext %{{.*}}) + +int pass_int(int arg) { return arg; } +// CHECK-LABEL: define signext i32 @pass_int(i32 signext %{{.*}}) + +long pass_long(long arg) { return arg; } +// CHECK-LABEL: define i64 @pass_long(i64 %{{.*}}) + +long long pass_longlong(long long arg) { return arg; } +// CHECK-LABEL: define i64 @pass_longlong(i64 %{{.*}}) + +__int128 pass_int128(__int128 arg) { return arg; } +// CHECK-LABEL: define void @pass_int128(i128* noalias sret %{{.*}}, i128*) + +float pass_float(float arg) { return arg; } +// CHECK-LABEL: define float @pass_float(float %{{.*}}) + +double pass_double(double arg) { return arg; } +// CHECK-LABEL: define double @pass_double(double %{{.*}}) + +long double pass_longdouble(long double arg) { return arg; } +// CHECK-LABEL: define void @pass_longdouble(fp128* noalias sret %{{.*}}, fp128*) + + +// Complex types + +_Complex char pass_complex_char(_Complex char arg) { return arg; } +// CHECK-LABEL: define void @pass_complex_char({ i8, i8 }* noalias sret %{{.*}}, { i8, i8 }* %{{.*}}arg) + +_Complex short pass_complex_short(_Complex short arg) { return arg; } +// CHECK-LABEL: define void @pass_complex_short({ i16, i16 }* noalias sret %{{.*}}, { i16, i16 }* %{{.*}}arg) + +_Complex int pass_complex_int(_Complex int arg) { return arg; } +// CHECK-LABEL: define void @pass_complex_int({ i32, i32 }* noalias sret %{{.*}}, { i32, i32 }* %{{.*}}arg) + +_Complex long pass_complex_long(_Complex long arg) { return arg; } +// CHECK-LABEL: define void @pass_complex_long({ i64, i64 }* noalias sret %{{.*}}, { i64, i64 }* %{{.*}}arg) + +_Complex long long pass_complex_longlong(_Complex long long arg) { return arg; } +// CHECK-LABEL: define void @pass_complex_longlong({ i64, i64 }* noalias sret %{{.*}}, { i64, i64 }* %{{.*}}arg) + +_Complex float pass_complex_float(_Complex float arg) { return arg; } +// CHECK-LABEL: define void @pass_complex_float({ float, float }* noalias sret %{{.*}}, { float, float }* %{{.*}}arg) + +_Complex double pass_complex_double(_Complex double arg) { return arg; } +// CHECK-LABEL: define void @pass_complex_double({ double, double }* noalias sret %{{.*}}, { double, double }* %{{.*}}arg) + +_Complex long double pass_complex_longdouble(_Complex long double arg) { return arg; } +// CHECK-LABEL: define void @pass_complex_longdouble({ fp128, fp128 }* noalias sret %{{.*}}, { fp128, fp128 }* %{{.*}}arg) + + +// Aggregate types + +struct agg_1byte { char a[1]; }; +struct agg_1byte pass_agg_1byte(struct agg_1byte arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_1byte(%struct.agg_1byte* noalias sret %{{.*}}, i8 %{{.*}}) + +struct agg_2byte { char a[2]; }; +struct agg_2byte pass_agg_2byte(struct agg_2byte arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_2byte(%struct.agg_2byte* noalias sret %{{.*}}, i16 %{{.*}}) + +struct agg_3byte { char a[3]; }; +struct agg_3byte pass_agg_3byte(struct agg_3byte arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_3byte(%struct.agg_3byte* noalias sret %{{.*}}, %struct.agg_3byte* %{{.*}}) + +struct agg_4byte { char a[4]; }; +struct agg_4byte pass_agg_4byte(struct agg_4byte arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_4byte(%struct.agg_4byte* noalias sret %{{.*}}, i32 %{{.*}}) + +struct agg_5byte { char a[5]; }; +struct agg_5byte pass_agg_5byte(struct agg_5byte arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_5byte(%struct.agg_5byte* noalias sret %{{.*}}, %struct.agg_5byte* %{{.*}}) + +struct agg_6byte { char a[6]; }; +struct agg_6byte pass_agg_6byte(struct agg_6byte arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_6byte(%struct.agg_6byte* noalias sret %{{.*}}, %struct.agg_6byte* %{{.*}}) + +struct agg_7byte { char a[7]; }; +struct agg_7byte pass_agg_7byte(struct agg_7byte arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_7byte(%struct.agg_7byte* noalias sret %{{.*}}, %struct.agg_7byte* %{{.*}}) + +struct agg_8byte { char a[8]; }; +struct agg_8byte pass_agg_8byte(struct agg_8byte arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_8byte(%struct.agg_8byte* noalias sret %{{.*}}, i64 %{{.*}}) + +struct agg_16byte { char a[16]; }; +struct agg_16byte pass_agg_16byte(struct agg_16byte arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_16byte(%struct.agg_16byte* noalias sret %{{.*}}, %struct.agg_16byte* %{{.*}}) + + +// Float-like aggregate types + +struct agg_float { float a; }; +struct agg_float pass_agg_float(struct agg_float arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_float(%struct.agg_float* noalias sret %{{.*}}, float %{{.*}}) + +struct agg_double { double a; }; +struct agg_double pass_agg_double(struct agg_double arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_double(%struct.agg_double* noalias sret %{{.*}}, double %{{.*}}) + +struct agg_longdouble { long double a; }; +struct agg_longdouble pass_agg_longdouble(struct agg_longdouble arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_longdouble(%struct.agg_longdouble* noalias sret %{{.*}}, %struct.agg_longdouble* %{{.*}}) + +struct agg_float_a8 { float a __attribute__((aligned (8))); }; +struct agg_float_a8 pass_agg_float_a8(struct agg_float_a8 arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_float_a8(%struct.agg_float_a8* noalias sret %{{.*}}, double %{{.*}}) + +struct agg_float_a16 { float a __attribute__((aligned (16))); }; +struct agg_float_a16 pass_agg_float_a16(struct agg_float_a16 arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_float_a16(%struct.agg_float_a16* noalias sret %{{.*}}, %struct.agg_float_a16* %{{.*}}) + + +// Verify that the following are *not* float-like aggregate types + +struct agg_nofloat1 { float a; float b; }; +struct agg_nofloat1 pass_agg_nofloat1(struct agg_nofloat1 arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_nofloat1(%struct.agg_nofloat1* noalias sret %{{.*}}, i64 %{{.*}}) + +struct agg_nofloat2 { float a; int b; }; +struct agg_nofloat2 pass_agg_nofloat2(struct agg_nofloat2 arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_nofloat2(%struct.agg_nofloat2* noalias sret %{{.*}}, i64 %{{.*}}) + +struct agg_nofloat3 { float a; int : 0; }; +struct agg_nofloat3 pass_agg_nofloat3(struct agg_nofloat3 arg) { return arg; } +// CHECK-LABEL: define void @pass_agg_nofloat3(%struct.agg_nofloat3* noalias sret %{{.*}}, i32 %{{.*}}) + + +// Accessing variable argument lists + +int va_int(__builtin_va_list l) { return __builtin_va_arg(l, int); } +// CHECK-LABEL: define signext i32 @va_int(%struct.__va_list_tag* %{{.*}}) +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 20 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to i32* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 4 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to i32* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi i32* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[RET:%[^ ]+]] = load i32, i32* [[VA_ARG_ADDR]] +// CHECK: ret i32 [[RET]] + +long va_long(__builtin_va_list l) { return __builtin_va_arg(l, long); } +// CHECK-LABEL: define i64 @va_long(%struct.__va_list_tag* %{{.*}}) +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to i64* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to i64* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi i64* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[RET:%[^ ]+]] = load i64, i64* [[VA_ARG_ADDR]] +// CHECK: ret i64 [[RET]] + +long long va_longlong(__builtin_va_list l) { return __builtin_va_arg(l, long long); } +// CHECK-LABEL: define i64 @va_longlong(%struct.__va_list_tag* %{{.*}}) +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to i64* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to i64* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi i64* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[RET:%[^ ]+]] = load i64, i64* [[VA_ARG_ADDR]] +// CHECK: ret i64 [[RET]] + +double va_double(__builtin_va_list l) { return __builtin_va_arg(l, double); } +// CHECK-LABEL: define double @va_double(%struct.__va_list_tag* %{{.*}}) +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 1 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 4 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 128 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to double* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to double* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi double* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[RET:%[^ ]+]] = load double, double* [[VA_ARG_ADDR]] +// CHECK: ret double [[RET]] + +long double va_longdouble(__builtin_va_list l) { return __builtin_va_arg(l, long double); } +// CHECK-LABEL: define void @va_longdouble(fp128* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}) +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to fp128** +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to fp128** +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi fp128** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[INDIRECT_ARG:%[^ ]+]] = load fp128*, fp128** [[VA_ARG_ADDR]] +// CHECK: [[RET:%[^ ]+]] = load fp128, fp128* [[INDIRECT_ARG]] +// CHECK: store fp128 [[RET]], fp128* %{{.*}} +// CHECK: ret void + +_Complex char va_complex_char(__builtin_va_list l) { return __builtin_va_arg(l, _Complex char); } +// CHECK-LABEL: define void @va_complex_char({ i8, i8 }* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to { i8, i8 }** +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to { i8, i8 }** +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi { i8, i8 }** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[INDIRECT_ARG:%[^ ]+]] = load { i8, i8 }*, { i8, i8 }** [[VA_ARG_ADDR]] +// CHECK: ret void + +struct agg_1byte va_agg_1byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_1byte); } +// CHECK-LABEL: define void @va_agg_1byte(%struct.agg_1byte* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 23 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_1byte* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 7 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_1byte* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_1byte* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: ret void + +struct agg_2byte va_agg_2byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_2byte); } +// CHECK-LABEL: define void @va_agg_2byte(%struct.agg_2byte* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 22 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_2byte* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 6 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_2byte* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_2byte* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: ret void + +struct agg_3byte va_agg_3byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_3byte); } +// CHECK-LABEL: define void @va_agg_3byte(%struct.agg_3byte* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_3byte** +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_3byte** +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_3byte** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[INDIRECT_ARG:%[^ ]+]] = load %struct.agg_3byte*, %struct.agg_3byte** [[VA_ARG_ADDR]] +// CHECK: ret void + +struct agg_4byte va_agg_4byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_4byte); } +// CHECK-LABEL: define void @va_agg_4byte(%struct.agg_4byte* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 20 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_4byte* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 4 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_4byte* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_4byte* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: ret void + +struct agg_8byte va_agg_8byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_8byte); } +// CHECK-LABEL: define void @va_agg_8byte(%struct.agg_8byte* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_8byte* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_8byte* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_8byte* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: ret void + +struct agg_float va_agg_float(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_float); } +// CHECK-LABEL: define void @va_agg_float(%struct.agg_float* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 1 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 4 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 128 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_float* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 4 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_float* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_float* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: ret void + +struct agg_double va_agg_double(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_double); } +// CHECK-LABEL: define void @va_agg_double(%struct.agg_double* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 1 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 4 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 128 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_double* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_double* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_double* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: ret void + +struct agg_longdouble va_agg_longdouble(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_longdouble); } +// CHECK-LABEL: define void @va_agg_longdouble(%struct.agg_longdouble* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_longdouble** +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_longdouble** +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_longdouble** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[INDIRECT_ARG:%[^ ]+]] = load %struct.agg_longdouble*, %struct.agg_longdouble** [[VA_ARG_ADDR]] +// CHECK: ret void + +struct agg_float_a8 va_agg_float_a8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_float_a8); } +// CHECK-LABEL: define void @va_agg_float_a8(%struct.agg_float_a8* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 1 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 4 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 128 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_float_a8* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_float_a8* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_float_a8* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: ret void + +struct agg_float_a16 va_agg_float_a16(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_float_a16); } +// CHECK-LABEL: define void @va_agg_float_a16(%struct.agg_float_a16* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_float_a16** +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_float_a16** +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_float_a16** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: [[INDIRECT_ARG:%[^ ]+]] = load %struct.agg_float_a16*, %struct.agg_float_a16** [[VA_ARG_ADDR]] +// CHECK: ret void + +struct agg_nofloat1 va_agg_nofloat1(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_nofloat1); } +// CHECK-LABEL: define void @va_agg_nofloat1(%struct.agg_nofloat1* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_nofloat1* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_nofloat1* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_nofloat1* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: ret void + +struct agg_nofloat2 va_agg_nofloat2(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_nofloat2); } +// CHECK-LABEL: define void @va_agg_nofloat2(%struct.agg_nofloat2* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_nofloat2* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_nofloat2* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_nofloat2* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: ret void + +struct agg_nofloat3 va_agg_nofloat3(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_nofloat3); } +// CHECK-LABEL: define void @va_agg_nofloat3(%struct.agg_nofloat3* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}} +// CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 +// CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] +// CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 +// CHECK: br i1 [[FITS_IN_REGS]], +// CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 +// CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 20 +// CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 +// CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] +// CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] +// CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_nofloat3* +// CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 +// CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] +// CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 +// CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 4 +// CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_nofloat3* +// CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 +// CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] +// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_nofloat3* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] +// CHECK: ret void + diff --git a/test/CodeGen/systemz-abi.cpp b/test/CodeGen/systemz-abi.cpp new file mode 100644 index 0000000000..0249e9f63c --- /dev/null +++ b/test/CodeGen/systemz-abi.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -emit-llvm -x c++ -o - %s | FileCheck %s + +// For compatibility with GCC, this structure is passed in an FPR in C++, +// but passed in a GPR in C (checked in systemz-abi.c). + +struct agg_float_cpp { float a; int : 0; }; +struct agg_float_cpp pass_agg_float_cpp(struct agg_float_cpp arg) { return arg; } +// CHECK-LABEL: define void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret %{{.*}}, float %{{.*}}) + diff --git a/test/CodeGen/target-data.c b/test/CodeGen/target-data.c index 4cb717606f..05fe7def56 100644 --- a/test/CodeGen/target-data.c +++ b/test/CodeGen/target-data.c @@ -66,7 +66,7 @@ // RUN: FileCheck %s -check-prefix=X86_64-NACL // X86_64-NACL: target datalayout = "e-m:e-p:32:32-i64:64-n8:16:32:64-S128" -// RUN: %clang_cc1 -triple arm-nacl-gnueabi -o - -emit-llvm %s | \ +// RUN: %clang_cc1 -triple arm-nacl -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=ARM-NACL // ARM-NACL: target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128" diff --git a/test/CodeGen/variadic-null-win64.c b/test/CodeGen/variadic-null-win64.c index 4f57e7b39f..3e079cbf8e 100644 --- a/test/CodeGen/variadic-null-win64.c +++ b/test/CodeGen/variadic-null-win64.c @@ -12,6 +12,6 @@ void f(const char *f) { v(f, 1, 2, 3, NULL); } // WINDOWS: define void @f(i8* %f) -// WINDOWS: call void (i8*, ...)* @v(i8* {{.*}}, i32 1, i32 2, i32 3, i64 0) +// WINDOWS: call void (i8*, ...) @v(i8* {{.*}}, i32 1, i32 2, i32 3, i64 0) // LINUX: define void @f(i8* %f) -// LINUX: call void (i8*, ...)* @v(i8* {{.*}}, i32 1, i32 2, i32 3, i32 0) +// LINUX: call void (i8*, ...) @v(i8* {{.*}}, i32 1, i32 2, i32 3, i32 0) diff --git a/test/CodeGen/x86_32-arguments-darwin.c b/test/CodeGen/x86_32-arguments-darwin.c index 422e030537..1536631fb0 100644 --- a/test/CodeGen/x86_32-arguments-darwin.c +++ b/test/CodeGen/x86_32-arguments-darwin.c @@ -236,7 +236,7 @@ v4i32 f55(v4i32 arg) { return arg+arg; } // CHECK: <8 x i32> %a10, %struct.s56_5* byval align 4, // CHECK: <4 x double> %a12, %struct.s56_6* byval align 4) -// CHECK: call void (i32, ...)* @f56_0(i32 1, +// CHECK: call void (i32, ...) @f56_0(i32 1, // CHECK: i32 %{{[^ ]*}}, %struct.s56_0* byval align 4 %{{[^ ]*}}, // CHECK: i64 %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}}, // CHECK: i64 %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}}, diff --git a/test/CodeGen/x86_32-arguments-linux.c b/test/CodeGen/x86_32-arguments-linux.c index 1a8c600129..02eac51216 100644 --- a/test/CodeGen/x86_32-arguments-linux.c +++ b/test/CodeGen/x86_32-arguments-linux.c @@ -10,7 +10,7 @@ // CHECK: <8 x i32> %a10, %struct.s56_5* byval align 4, // CHECK: <4 x double> %a12, %struct.s56_6* byval align 4) -// CHECK: call void (i32, ...)* @f56_0(i32 1, +// CHECK: call void (i32, ...) @f56_0(i32 1, // CHECK: i32 %{{.*}}, %struct.s56_0* byval align 4 %{{[^ ]*}}, // CHECK: i64 %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}}, // CHECK: <1 x double> %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}}, diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c index a0e30c6dea..f52629c651 100644 --- a/test/CodeGen/x86_64-arguments.c +++ b/test/CodeGen/x86_64-arguments.c @@ -404,7 +404,7 @@ void test49(double d, double e) { // CHECK-LABEL: define void @test49( // CHECK: [[T0:%.*]] = load double, double* // CHECK-NEXT: [[T1:%.*]] = load double, double* -// CHECK-NEXT: call void (double, ...)* @test49_helper(double [[T0]], double [[T1]]) +// CHECK-NEXT: call void (double, ...) @test49_helper(double [[T0]], double [[T1]]) void test50_helper(); void test50(double d, double e) { @@ -413,7 +413,7 @@ void test50(double d, double e) { // CHECK-LABEL: define void @test50( // CHECK: [[T0:%.*]] = load double, double* // CHECK-NEXT: [[T1:%.*]] = load double, double* -// CHECK-NEXT: call void (double, double, ...)* bitcast (void (...)* @test50_helper to void (double, double, ...)*)(double [[T0]], double [[T1]]) +// CHECK-NEXT: call void (double, double, ...) bitcast (void (...)* @test50_helper to void (double, double, ...)*)(double [[T0]], double [[T1]]) struct test51_s { __uint128_t intval; }; void test51(struct test51_s *s, __builtin_va_list argList) { diff --git a/test/CodeGenCXX/auto-variable-template.cpp b/test/CodeGenCXX/auto-variable-template.cpp new file mode 100644 index 0000000000..265d81dd35 --- /dev/null +++ b/test/CodeGenCXX/auto-variable-template.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++14 %s -triple=x86_64-linux -emit-llvm -o - | FileCheck %s + +struct f { + void operator()() const {} +}; + +template <typename T> auto vtemplate = f{}; + +int main() { vtemplate<int>(); } + +// CHECK: @_Z9vtemplateIiE = linkonce_odr global %struct.f undef, comdat + +// CHECK: define i32 @main() +// CHECK: call void @_ZNK1fclEv(%struct.f* @_Z9vtemplateIiE) diff --git a/test/CodeGenCXX/call-with-static-chain.cpp b/test/CodeGenCXX/call-with-static-chain.cpp index 7cf929189f..ac1149b52e 100644 --- a/test/CodeGenCXX/call-with-static-chain.cpp +++ b/test/CodeGenCXX/call-with-static-chain.cpp @@ -21,7 +21,7 @@ A &f4(); void test() { A a; - // CHECK32: call i32 bitcast (i32 (%struct.A*, %struct.A*, %struct.A*, %struct.A*)* @f1 to i32 (i8*, %struct.A*, %struct.A*, %struct.A*, %struct.A*)*)(i8* nest bitcast (i32 (%struct.A*, %struct.A*, %struct.A*, %struct.A*)* @f1 to i8*) + // CHECK32: call i32 bitcast (i32 (i32, i32, i32, i32, i32, i32, i32, i32)* @f1 to i32 (i8*, i32, i32, i32, i32, i32, i32, i32, i32)*)(i8* nest bitcast (i32 (i32, i32, i32, i32, i32, i32, i32, i32)* @f1 to i8*) // CHECK64: call i32 bitcast (i32 (i64, i64, i64, i64, i64, i64, %struct.A*)* @f1 to i32 (i8*, i64, i64, i64, i64, i64, i64, %struct.A*)*)(i8* nest bitcast (i32 (i64, i64, i64, i64, i64, i64, %struct.A*)* @f1 to i8*) __builtin_call_with_static_chain(f1(a, a, a, a), f1); diff --git a/test/CodeGenCXX/cfi-nvcall.cpp b/test/CodeGenCXX/cfi-nvcall.cpp new file mode 100644 index 0000000000..b0db478c9d --- /dev/null +++ b/test/CodeGenCXX/cfi-nvcall.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-nvcall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-nvcall,cfi-cast-strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-STRICT %s + +struct A { + virtual void f(); +}; + +struct B : A { + int i; + void g(); +}; + +struct C : A { + void g(); +}; + +// CHECK-LABEL: @bg +// CHECK-STRICT-LABEL: @bg +extern "C" void bg(B *b) { + // CHECK: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") + // CHECK-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") + b->g(); +} + +// CHECK-LABEL: @cg +// CHECK-STRICT-LABEL: @cg +extern "C" void cg(C *c) { + // http://clang.llvm.org/docs/ControlFlowIntegrity.html#strictness + // In this case C's layout is the same as its base class, so we allow + // c to be of type A in non-strict mode. + + // CHECK: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1A") + // CHECK-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1C") + c->g(); +} diff --git a/test/CodeGenCXX/cfi-vptr.cpp b/test/CodeGenCXX/cfi-vcall.cpp index 545f22c3c7..bfbbceaa1a 100644 --- a/test/CodeGenCXX/cfi-vptr.cpp +++ b/test/CodeGenCXX/cfi-vcall.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vptr -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck %s struct A { A(); @@ -49,7 +49,7 @@ void af(A *a) { // CHECK: define internal void @_Z2dfPN12_GLOBAL__N_11DE void df(D *d) { - // CHECK: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"[{{.*}}cfi-vptr.cpp]N12_GLOBAL__N_11DE") + // CHECK: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"[{{.*}}cfi-vcall.cpp]N12_GLOBAL__N_11DE") d->f(); } @@ -67,7 +67,7 @@ void foo() { // CHECK-DAG: !{!"1A", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} // CHECK-DAG: !{!"1B", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} // CHECK-DAG: !{!"1C", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 72} -// CHECK-DAG: !{!"[{{.*}}cfi-vptr.cpp]N12_GLOBAL__N_11DE", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} +// CHECK-DAG: !{!"[{{.*}}cfi-vcall.cpp]N12_GLOBAL__N_11DE", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} // CHECK-DAG: !{!"1A", [5 x i8*]* @_ZTV1B, i64 32} // CHECK-DAG: !{!"1B", [5 x i8*]* @_ZTV1B, i64 32} // CHECK-DAG: !{!"1A", [5 x i8*]* @_ZTV1C, i64 32} diff --git a/test/CodeGenCXX/compound-literals.cpp b/test/CodeGenCXX/compound-literals.cpp index 4f8cf10467..ce7d047f72 100644 --- a/test/CodeGenCXX/compound-literals.cpp +++ b/test/CodeGenCXX/compound-literals.cpp @@ -28,7 +28,7 @@ int f() { // CHECK-LABEL: define i32 @_Z1gv() int g() { - // CHECK: store [2 x i32]* @{{.*}}, [2 x i32]** [[V:%[a-z0-9.]+]] + // CHECK: store [2 x i32]* %{{[a-z0-9.]+}}, [2 x i32]** [[V:%[a-z0-9.]+]] const int (&v)[2] = (int [2]) {1,2}; // CHECK: [[A:%[a-z0-9.]+]] = load [2 x i32]*, [2 x i32]** [[V]] diff --git a/test/CodeGenCXX/conditional-gnu-ext.cpp b/test/CodeGenCXX/conditional-gnu-ext.cpp index 174c67b82f..b073e0cc66 100644 --- a/test/CodeGenCXX/conditional-gnu-ext.cpp +++ b/test/CodeGenCXX/conditional-gnu-ext.cpp @@ -5,7 +5,7 @@ extern "C" int printf(...); void test0() { -// CHECK: call i32 (...)* @printf({{.*}}, i8* inttoptr (i64 3735928559 to i8*)) +// CHECK: call i32 (...) @printf({{.*}}, i8* inttoptr (i64 3735928559 to i8*)) printf("%p\n", (void *)0xdeadbeef ? : (void *)0xaaaaaa); } diff --git a/test/CodeGenCXX/convert-to-fptr.cpp b/test/CodeGenCXX/convert-to-fptr.cpp index c3be9627ba..283493ea94 100644 --- a/test/CodeGenCXX/convert-to-fptr.cpp +++ b/test/CodeGenCXX/convert-to-fptr.cpp @@ -38,5 +38,5 @@ int main() return 0; } -// CHECK: call i32 (i32)* (%struct.A*)* @_ZN1AcvPFiiEEv -// CHECK: call i32 (i32)* (%struct.B*)* @_ZN1BcvRFiiEEv +// CHECK: call i32 (i32)* @_ZN1AcvPFiiEEv +// CHECK: call i32 (i32)* @_ZN1BcvRFiiEEv diff --git a/test/CodeGenCXX/cxx0x-initializer-references.cpp b/test/CodeGenCXX/cxx0x-initializer-references.cpp index d4a8f20f35..318c8ea0d7 100644 --- a/test/CodeGenCXX/cxx0x-initializer-references.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-references.cpp @@ -79,3 +79,33 @@ namespace reference { } } + +namespace PR23165 { +struct AbstractClass { + virtual void foo() const = 0; +}; + +struct ChildClass : public AbstractClass { + virtual void foo() const {} +}; + +void helper(const AbstractClass ¶m) { + param.foo(); +} + +void foo() { +// CHECK-LABEL: @_ZN7PR231653fooEv +// CHECK: call {{.*}} @_ZN7PR2316510ChildClassC1Ev +// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE + helper(ChildClass()); +} + +struct S { struct T { int a; } t; mutable int b; }; +void f() { +// CHECK-LABEL: _ZN7PR231651fEv +// CHECK: alloca +// CHECK: alloca +// CHECK: store + const S::T &r = S().t; +} +} diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp index 1131ca9fa3..6d5d3971bd 100644 --- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -510,7 +510,7 @@ namespace B19773010 { void PR22940_helper(const pair<void*, int>&) { } void PR22940() { // CHECK-LABEL: @_ZN9B197730107PR22940Ev - // CHECK-NOT: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev( + // CHECK: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev( // CHECK: call {{.*}} @_ZN9B1977301014PR22940_helperERKNS_4pairIPviEE( PR22940_helper(pair<void*, int>()); } diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp index c6ab232a76..b7bd675602 100644 --- a/test/CodeGenCXX/dllexport.cpp +++ b/test/CodeGenCXX/dllexport.cpp @@ -490,7 +490,7 @@ struct CtorWithClosure { // M32-DAG: %[[this_addr:.*]] = alloca %struct.CtorWithClosure*, align 4 // M32-DAG: store %struct.CtorWithClosure* %this, %struct.CtorWithClosure** %[[this_addr]], align 4 // M32-DAG: %[[this:.*]] = load %struct.CtorWithClosure*, %struct.CtorWithClosure** %[[this_addr]] -// M32-DAG: call %struct.CtorWithClosure* (%struct.CtorWithClosure*, ...)* @"\01??0CtorWithClosure@@QAA@ZZ"(%struct.CtorWithClosure* %[[this]]) +// M32-DAG: call %struct.CtorWithClosure* (%struct.CtorWithClosure*, ...) @"\01??0CtorWithClosure@@QAA@ZZ"(%struct.CtorWithClosure* %[[this]]) // M32-DAG: ret void }; @@ -507,7 +507,7 @@ struct __declspec(dllexport) ClassWithClosure { // M32-DAG: %[[this_addr:.*]] = alloca %struct.ClassWithClosure*, align 4 // M32-DAG: store %struct.ClassWithClosure* %this, %struct.ClassWithClosure** %[[this_addr]], align 4 // M32-DAG: %[[this:.*]] = load %struct.ClassWithClosure*, %struct.ClassWithClosure** %[[this_addr]] -// M32-DAG: call %struct.ClassWithClosure* (%struct.ClassWithClosure*, ...)* @"\01??0ClassWithClosure@@QAA@ZZ"(%struct.ClassWithClosure* %[[this]]) +// M32-DAG: call %struct.ClassWithClosure* (%struct.ClassWithClosure*, ...) @"\01??0ClassWithClosure@@QAA@ZZ"(%struct.ClassWithClosure* %[[this]]) // M32-DAG: ret void }; diff --git a/test/CodeGenCXX/exceptions-seh-filter-captures.cpp b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp new file mode 100644 index 0000000000..5df418a13a --- /dev/null +++ b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \ +// RUN: -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | \ +// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CXXEH + +extern "C" int basic_filter(int v, ...); +extern "C" void might_crash(); + +extern "C" void test_freefunc(int p1) { + int l1 = 13; + static int s1 = 42; + __try { + might_crash(); + } __except(basic_filter(p1, l1, s1)) { + } +} + +// CHECK-LABEL: define void @test_freefunc(i32 %p1) +// CHECK: @llvm.frameescape(i32* %[[p1_ptr:[^, ]*]], i32* %[[l1_ptr:[^, ]*]]) +// CHECK: store i32 %p1, i32* %[[p1_ptr]], align 4 +// CHECK: store i32 13, i32* %[[l1_ptr]], align 4 +// CHECK: invoke void @might_crash() + +// CHECK-LABEL: define internal i32 @"\01?filt$0@0@test_freefunc@@"(i8* %exception_pointers, i8* %frame_pointer) +// CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 0) +// CHECK: %[[p1_ptr:[^ ]*]] = bitcast i8* %[[p1_i8]] to i32* +// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 1) +// CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32* +// CHECK: %[[s1:[^ ]*]] = load i32, i32* @"\01?s1@?1??test_freefunc@@9@4HA", align 4 +// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]] +// CHECK: %[[p1:[^ ]*]] = load i32, i32* %[[p1_ptr]] +// CHECK: call i32 (i32, ...) @basic_filter(i32 %[[p1]], i32 %[[l1]], i32 %[[s1]]) + +struct S { + int m1; + void test_method(void); +}; + +void S::test_method() { + int l1 = 13; + __try { + might_crash(); + } __except(basic_filter(l1)) { + // FIXME: Test capturing 'this' and 'm1'. + } +} + +// CHECK-LABEL: define void @"\01?test_method@S@@QEAAXXZ"(%struct.S* %this) +// CHECK: @llvm.frameescape(i32* %[[l1_addr:[^, ]*]]) +// CHECK: store i32 13, i32* %[[l1_addr]], align 4 +// CHECK: invoke void @might_crash() + +// CHECK-LABEL: define internal i32 @"\01?filt$0@0@test_method@S@@"(i8* %exception_pointers, i8* %frame_pointer) +// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (%struct.S*)* @"\01?test_method@S@@QEAAXXZ" to i8*), i8* %frame_pointer, i32 0) +// CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32* +// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]] +// CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]]) + +void test_lambda() { + int l1 = 13; + auto lambda = [&]() { + int l2 = 42; + __try { + might_crash(); + } __except(basic_filter(l2)) { + // FIXME: Test 'l1' when we can capture the lambda's 'this' decl. + } + }; + lambda(); +} + +// CHECK-LABEL: define internal void @"\01??R<lambda_0>@?test_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this) +// CHECK: @llvm.frameescape(i32* %[[l2_addr:[^, ]*]]) +// CHECK: store i32 42, i32* %[[l2_addr]], align 4 +// CHECK: invoke void @might_crash() + +// CHECK-LABEL: define internal i32 @"\01?filt$0@0@?R<lambda_0>@?test_lambda@@YAXXZ@"(i8* %exception_pointers, i8* %frame_pointer) +// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?test_lambda@@YAXXZ@QEBAXXZ" to i8*), i8* %frame_pointer, i32 0) +// CHECK: %[[l2_ptr:[^ ]*]] = bitcast i8* %[[l2_i8]] to i32* +// CHECK: %[[l2:[^ ]*]] = load i32, i32* %[[l2_ptr]] +// CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l2]]) diff --git a/test/CodeGenCXX/exceptions-seh.cpp b/test/CodeGenCXX/exceptions-seh.cpp index 5f93cb1be3..cb5f6dfad9 100644 --- a/test/CodeGenCXX/exceptions-seh.cpp +++ b/test/CodeGenCXX/exceptions-seh.cpp @@ -5,6 +5,7 @@ // RUN: -o - -mconstructor-aliases -O1 -disable-llvm-optzns | \ // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX +extern "C" unsigned long _exception_code(); extern "C" void might_throw(); struct HasCleanup { @@ -95,4 +96,47 @@ void use_seh_in_lambda() { // CHECK: invoke void @might_throw() #[[NOINLINE]] // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +static int my_unique_global; + +extern "C" inline void use_seh_in_inline_func() { + __try { + might_throw(); + } __except(_exception_code() == 424242) { + } + __try { + might_throw(); + } __finally { + my_unique_global = 1234; + } +} + +void use_inline() { + use_seh_in_inline_func(); +} + +// CHECK-LABEL: define linkonce_odr void @use_seh_in_inline_func() #{{[0-9]+}} comdat { +// CHECK: invoke void @might_throw() +// +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK-NEXT: catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_seh_in_inline_func@@" to i8*) +// +// CHECK: invoke void @might_throw() +// +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: ret void +// +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK-NEXT: cleanup +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i1 zeroext true, i8* %[[fp]]) + +// CHECK-LABEL: define internal i32 @"\01?filt$0@0@use_seh_in_inline_func@@"(i8* %exception_pointers, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func) +// CHECK: icmp eq i32 %{{.*}}, 424242 +// CHECK: zext i1 %{{.*}} to i32 +// CHECK: ret i32 + +// CHECK-LABEL: define internal void @"\01?fin$0@0@use_seh_in_inline_func@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func) +// CHECK: store i32 1234, i32* @my_unique_global + // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} } diff --git a/test/CodeGenCXX/mangle-lambdas.cpp b/test/CodeGenCXX/mangle-lambdas.cpp index 1b784f322e..8e2db0311b 100644 --- a/test/CodeGenCXX/mangle-lambdas.cpp +++ b/test/CodeGenCXX/mangle-lambdas.cpp @@ -1,10 +1,5 @@ // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s -w | FileCheck %s -// CHECK: @_ZZZN7PR12917IJicdEEC1EicdEd1_NKUlvE_clEvE1n = linkonce_odr global i32 0 -// CHECK: @_ZZZN7PR12917IJicdEEC1EicdEd0_NKUlvE_clEvE1n = linkonce_odr global i32 0 -// CHECK: @_ZZZN7PR12917IJicdEEC1EicdEd_NKUlvE_clEvE1n = linkonce_odr global i32 0 -// CHECK: @_ZZNK7PR12917IJiiEE1nMUlvE_clEvE1n = linkonce_odr global i32 0 - // CHECK-LABEL: define linkonce_odr void @_Z11inline_funci inline void inline_func(int n) { // CHECK: call i32 @_ZZ11inline_funciENKUlvE_clEv @@ -164,23 +159,6 @@ void use_func_template() { func_template<int>(); } - -template<typename...T> struct PR12917 { - PR12917(T ...t = []{ static int n = 0; return ++n; }()); - - static int n[3]; -}; -template<typename...T> int PR12917<T...>::n[3] = { - []{ static int n = 0; return ++n; }() -}; - -// CHECK: call i32 @_ZZN7PR12917IJicdEEC1EicdEd1_NKUlvE_clEv( -// CHECK: call i32 @_ZZN7PR12917IJicdEEC1EicdEd0_NKUlvE_clEv( -// CHECK: call i32 @_ZZN7PR12917IJicdEEC1EicdEd_NKUlvE_clEv( -// CHECK: call void @_ZN7PR12917IJicdEEC1Eicd( -PR12917<int, char, double> pr12917; -int *pr12917_p = PR12917<int, int>::n; - namespace std { struct type_info; } diff --git a/test/CodeGenCXX/mangle-ms-cxx14.cpp b/test/CodeGenCXX/mangle-ms-cxx14.cpp index a3a86851f7..51627dd89e 100644 --- a/test/CodeGenCXX/mangle-ms-cxx14.cpp +++ b/test/CodeGenCXX/mangle-ms-cxx14.cpp @@ -35,10 +35,10 @@ auto TemplateFuncionWithLocalLambda(T) { return LocalLambdaWithLocalType(); } -// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?3@XZ@A" -// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?3@XZ@A" -// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?3@XZ@A" -// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?3@XZ@A" +// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A" +// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A" +// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A" +// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A" // CHECK: "\01??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z" -// CHECK: "\01??R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?1@XZ" +// CHECK: "\01??R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?1@XZ" auto ValueFromTemplateFuncionWithLocalLambda = TemplateFuncionWithLocalLambda(0); diff --git a/test/CodeGenCXX/member-functions.cpp b/test/CodeGenCXX/member-functions.cpp index 1d2a60dfdc..58f709c333 100644 --- a/test/CodeGenCXX/member-functions.cpp +++ b/test/CodeGenCXX/member-functions.cpp @@ -16,7 +16,7 @@ void test1() { // CHECK: call void @_ZN1C1fEv c.f(); - // CHECK: call void (%struct.C*, i32, ...)* @_ZN1C1gEiz + // CHECK: call void (%struct.C*, i32, ...) @_ZN1C1gEiz c.g(1, 2, 3); } diff --git a/test/CodeGenCXX/microsoft-abi-eh-catch.cpp b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp index f0e2033451..292fad2e4d 100644 --- a/test/CodeGenCXX/microsoft-abi-eh-catch.cpp +++ b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp @@ -48,6 +48,18 @@ extern "C" void catch_int() { // WIN64: call void @handle_exception(i8* %[[e_i8]]) // WIN64: call void @llvm.eh.endcatch() +extern "C" void catch_int_unnamed() { + try { + might_throw(); + } catch (int) { + } +} + +// WIN64-LABEL: define void @catch_int_unnamed() +// WIN64: landingpad { i8*, i32 } +// WIN64: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* null) +// WIN64: call void @llvm.eh.endcatch() + struct A { A(); A(const A &o); @@ -96,3 +108,11 @@ extern "C" void catch_a_ref() { // WIN64: %[[eptr_i8:[^ ]*]] = bitcast %struct.A* %[[eptr]] to i8* // WIN64: call void @handle_exception(i8* %[[eptr_i8]]) // WIN64: call void @llvm.eh.endcatch() + +extern "C" void fn_with_exc_spec() throw(int) { + might_throw(); +} + +// WIN64-LABEL: define void @fn_with_exc_spec() +// WIN64: call void @might_throw() +// WIN64-NEXT: ret void diff --git a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp index 642d8e23fa..68f1430ace 100644 --- a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp +++ b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp @@ -165,6 +165,29 @@ C::C() { foo(); } // WIN32: getelementptr inbounds i8, i8* %{{.*}}, i64 4 // WIN32-NOT: load // WIN32: bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::A"* -// WIN32: invoke x86_thiscallcc void @"\01??1A@crash_on_partial_destroy@@UAE@XZ" +// WIN32: call x86_thiscallcc void @"\01??1A@crash_on_partial_destroy@@UAE@XZ" // WIN32: } } + +namespace dont_call_terminate { +struct C { + ~C(); +}; +void g(); +void f() { + C c; + g(); +} + +// WIN32-LABEL: define void @"\01?f@dont_call_terminate@@YAXXZ"() +// WIN32: invoke void @"\01?g@dont_call_terminate@@YAXXZ"() +// WIN32-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] +// +// WIN32: [[cont]] +// WIN32: call x86_thiscallcc void @"\01??1C@dont_call_terminate@@QAE@XZ"({{.*}}) +// +// WIN32: [[lpad]] +// WIN32-NEXT: landingpad +// WIN32-NEXT: cleanup +// WIN32: call x86_thiscallcc void @"\01??1C@dont_call_terminate@@QAE@XZ"({{.*}}) +} diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp index 77843592b7..f1bff39c64 100644 --- a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp +++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp @@ -623,7 +623,7 @@ void (C::*getmp())() { // CHECK: load void (%"struct.Test4::C"*, ...)**, void (%"struct.Test4::C"*, ...)*** %{{.*}} // CHECK: getelementptr inbounds void (%"struct.Test4::C"*, ...)*, void (%"struct.Test4::C"*, ...)** %{{.*}}, i64 0 // CHECK-NOT: getelementptr -// CHECK: musttail call x86_thiscallcc void (%"struct.Test4::C"*, ...)* % +// CHECK: musttail call x86_thiscallcc void (%"struct.Test4::C"*, ...) % } diff --git a/test/CodeGenCXX/microsoft-abi-methods.cpp b/test/CodeGenCXX/microsoft-abi-methods.cpp index aa3141c7d3..e58d1033e1 100644 --- a/test/CodeGenCXX/microsoft-abi-methods.cpp +++ b/test/CodeGenCXX/microsoft-abi-methods.cpp @@ -42,7 +42,7 @@ void call_vararg_method() { C instance; instance.vararg_method("Hello"); // Make sure that the call uses the right calling convention: -// CHECK: call void (%class.C*, i8*, ...)* @"\01?vararg_method@C@@QAAXPBDZZ" +// CHECK: call void (%class.C*, i8*, ...) @"\01?vararg_method@C@@QAAXPBDZZ" // CHECK: ret // Make sure that the definition uses the right calling convention: diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp index a4eaa1cfbc..4c2d8506af 100644 --- a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp +++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp @@ -101,12 +101,12 @@ Big big_return() { return Big(); } void small_arg(Small s) {} -// LINUX-LABEL: define void @_Z9small_arg5Small(%struct.Small* byval align 4 %s) +// LINUX-LABEL: define void @_Z9small_arg5Small(i32 %s.0) // 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-LABEL: define void @_Z10medium_arg6Medium(%struct.Medium* byval align 4 %s) +// LINUX-LABEL: define void @_Z10medium_arg6Medium(i32 %s.0, i32 %s.1) // 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) @@ -229,7 +229,7 @@ class Class { // WIN64: define linkonce_odr void @"\01?thiscall_method_arg@Class@@QEAAXUEmptyWithCtor@@@Z"(%class.Class* %this, i8 %s.coerce) void thiscall_method_arg(Small s) {} - // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Small(%class.Class* %this, %struct.Small* byval align 4 %s) + // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Small(%class.Class* %this, i32 %s.0) // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUSmall@@@Z"(%class.Class* %this, %struct.Small* byval align 4 %s) // WIN64: define linkonce_odr void @"\01?thiscall_method_arg@Class@@QEAAXUSmall@@@Z"(%class.Class* %this, i32 %s.coerce) diff --git a/test/CodeGenCXX/microsoft-abi-structors.cpp b/test/CodeGenCXX/microsoft-abi-structors.cpp index 5ca0bb9bc4..594dea473e 100644 --- a/test/CodeGenCXX/microsoft-abi-structors.cpp +++ b/test/CodeGenCXX/microsoft-abi-structors.cpp @@ -420,7 +420,7 @@ void construct_b() { // CHECK-LABEL: define void @"\01?construct_b@test1@@YAXXZ"() // CHECK: call x86_thiscallcc %"struct.test1::B"* @"\01??0B@test1@@QAE@PAH@Z" // CHECK: (%"struct.test1::B"* {{.*}}, i32* {{.*}}, i32 1) -// CHECK: call %"struct.test1::B"* (%"struct.test1::B"*, i32, i8*, ...)* @"\01??0B@test1@@QAA@PBDZZ" +// CHECK: call %"struct.test1::B"* (%"struct.test1::B"*, i32, i8*, ...) @"\01??0B@test1@@QAA@PBDZZ" // CHECK: (%"struct.test1::B"* {{.*}}, i32 1, i8* {{.*}}, i32 1, i32 2) } diff --git a/test/CodeGenCXX/microsoft-abi-throw.cpp b/test/CodeGenCXX/microsoft-abi-throw.cpp index 080a98e0d9..080f1a025c 100644 --- a/test/CodeGenCXX/microsoft-abi-throw.cpp +++ b/test/CodeGenCXX/microsoft-abi-throw.cpp @@ -16,6 +16,9 @@ // CHECK-DAG: @"_CT??_R0?AUVariadic@@@8??_OVariadic@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor14* @"\01??_R0?AUVariadic@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Variadic*, %struct.Variadic*)* @"\01??_OVariadic@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat // CHECK-DAG: @"_CT??_R0?AUTemplateWithDefault@@@8??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor25* @"\01??_R0?AUTemplateWithDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.TemplateWithDefault*, %struct.TemplateWithDefault*)* @"\01??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat // CHECK-DAG: @"_CTA2$$T" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0$$T@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat +// CHECK-DAG: @"_CT??_R0P6AXXZ@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0P6AXXZ@8" to i8*), i32 0, i32 -1, i32 0, i32 4, i8* null }, section ".xdata", comdat +// CHECK-DAG: @_CTA1P6AXXZ = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0P6AXXZ@84"] }, section ".xdata", comdat +// CHECK-DAG: @_TI1P6AXXZ = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1P6AXXZ to i8*) }, section ".xdata", comdat struct N { ~N(); }; @@ -104,3 +107,9 @@ void *GetExceptionInfo_test0() { // CHECK: ret i8* bitcast (%eh.ThrowInfo* @_TI1H to i8*) return std::__GetExceptionInfo(0); } + +void *GetExceptionInfo_test1() { +// CHECK-LABEL: @"\01?GetExceptionInfo_test1@@YAPAXXZ" +// CHECK: ret i8* bitcast (%eh.ThrowInfo* @_TI1P6AXXZ to i8*) + return std::__GetExceptionInfo<void (*)()>(&h); +} diff --git a/test/CodeGenCXX/microsoft-abi-try-throw.cpp b/test/CodeGenCXX/microsoft-abi-try-throw.cpp index c7bbcf2888..fed3976171 100644 --- a/test/CodeGenCXX/microsoft-abi-try-throw.cpp +++ b/test/CodeGenCXX/microsoft-abi-try-throw.cpp @@ -6,7 +6,7 @@ // THROW-DAG: @_CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0H@84"] }, section ".xdata", comdat // THROW-DAG: @_TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1H to i8*) }, section ".xdata", comdat -// TRY-DAG: @llvm.eh.handlermapentry.const.PAH = private unnamed_addr constant %eh.HandlerMapEntry { i32 1, i8* bitcast (%rtti.TypeDescriptor4* @"\01??_R0PAH@8" to i8*) }, section "llvm.metadata" +// TRY-DAG: @llvm.eh.handlertype.PAH.1 = private unnamed_addr constant %eh.CatchHandlerType { i32 1, i8* bitcast (%rtti.TypeDescriptor4* @"\01??_R0PAH@8" to i8*) }, section "llvm.metadata" void external(); @@ -21,7 +21,7 @@ int main() { external(); // TRY: invoke void @"\01?external@@YAXXZ" } catch (int) { rv = 1; - // TRY: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* %{{.*}}) + // TRY: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* null) // TRY: call void @llvm.eh.endcatch() } #endif @@ -41,7 +41,7 @@ void qual_catch() { external(); } catch (const int *) { } - // TRY: catch %eh.HandlerMapEntry* @llvm.eh.handlermapentry.const.PAH - // TRY: call i32 @llvm.eh.typeid.for(i8* bitcast (%eh.HandlerMapEntry* @llvm.eh.handlermapentry.const.PAH to i8*)) + // TRY: catch %eh.CatchHandlerType* @llvm.eh.handlertype.PAH.1 + // TRY: call i32 @llvm.eh.typeid.for(i8* bitcast (%eh.CatchHandlerType* @llvm.eh.handlertype.PAH.1 to i8*)) } #endif diff --git a/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp index fe6468620b..f6f75835c6 100644 --- a/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp +++ b/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp @@ -71,7 +71,7 @@ void f() { // CHECK32: comdat // CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 0 // CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] -// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK32-NEXT: ret void // CHECK32: } // @@ -81,7 +81,7 @@ void f() { // CHECK64: comdat // CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 0 // CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] -// CHECK64: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK64-NEXT: ret void // CHECK64: } @@ -90,7 +90,7 @@ void f() { // CHECK32: #[[ATTR]] comdat // CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 1 // CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] -// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK32-NEXT: ret void // CHECK32: } // @@ -98,7 +98,7 @@ void f() { // CHECK64: #[[ATTR]] comdat // CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 1 // CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] -// CHECK64: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK64-NEXT: ret void // CHECK64: } @@ -107,7 +107,7 @@ void f() { // CHECK32: #[[ATTR]] comdat // CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 2 // CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] -// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK32-NEXT: ret void // CHECK32: } // @@ -115,7 +115,7 @@ void f() { // CHECK64: #[[ATTR]] comdat // CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 2 // CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] -// CHECK64: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK64-NEXT: ret void // CHECK64: } @@ -124,7 +124,7 @@ void f() { // CHECK32: #[[ATTR]] // CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0 // CHECK32: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]] -// CHECK32: musttail call x86_thiscallcc void (%"struct.(anonymous namespace)::D"*, ...)* [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...) +// CHECK32: musttail call x86_thiscallcc void (%"struct.(anonymous namespace)::D"*, ...) [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...) // CHECK32-NEXT: ret void // CHECK32: } // @@ -132,7 +132,7 @@ void f() { // CHECK64: #[[ATTR]] // CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0 // CHECK64: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]] -// CHECK64: musttail call void (%"struct.(anonymous namespace)::D"*, ...)* [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...) +// CHECK64: musttail call void (%"struct.(anonymous namespace)::D"*, ...) [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...) // CHECK64-NEXT: ret void // CHECK64: } @@ -141,14 +141,14 @@ void f() { // CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$BM@AE"(%struct.C* %this, ...) {{.*}} comdat // CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 3 // CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] -// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK32-NEXT: ret void // CHECK32: } // // CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BBI@AA"(%struct.C* %this, ...) {{.*}} comdat // CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 3 // CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] -// CHECK64: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK64: ret void // CHECK64: } @@ -156,14 +156,14 @@ void f() { // CHECK32-LABEL: define linkonce_odr void @"\01??_9C@@$BBA@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 { // CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 4 // CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] -// CHECK32: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK32: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK32: ret void // CHECK32: } // // CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BCA@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 { // CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 4 // CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] -// CHECK64: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK64: ret void // CHECK64: } diff --git a/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp b/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp index 0b00ef5b58..f8a12e64c6 100644 --- a/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp +++ b/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp @@ -24,7 +24,7 @@ void f(C *c) { // CHECK: call x86_thiscallcc void bitcast (void (%"struct.num_params::C"*, ...)* @"\01??_9C@num_params@@$BA@AE" to void (%"struct.num_params::C"*, i32, i32)*)(%"struct.num_params::C"* %{{.*}}, i32 0, i32 0) // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@num_params@@$BA@AE"(%"struct.num_params::C"* %this, ...) {{.*}} comdat -// CHECK: musttail call x86_thiscallcc void (%"struct.num_params::C"*, ...)* %{{.*}}(%"struct.num_params::C"* %{{.*}}, ...) +// CHECK: musttail call x86_thiscallcc void (%"struct.num_params::C"*, ...) %{{.*}}(%"struct.num_params::C"* %{{.*}}, ...) // CHECK-NEXT: ret void namespace i64_return { @@ -46,7 +46,7 @@ long long f(C *c) { // CHECK: call x86_thiscallcc i64 bitcast (void (%"struct.i64_return::C"*, ...)* @"\01??_9C@i64_return@@$BA@AE" to i64 (%"struct.i64_return::C"*)*)(%"struct.i64_return::C"* %{{.*}}) // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@i64_return@@$BA@AE"(%"struct.i64_return::C"* %this, ...) {{.*}} comdat -// CHECK: musttail call x86_thiscallcc void (%"struct.i64_return::C"*, ...)* %{{.*}}(%"struct.i64_return::C"* %{{.*}}, ...) +// CHECK: musttail call x86_thiscallcc void (%"struct.i64_return::C"*, ...) %{{.*}}(%"struct.i64_return::C"* %{{.*}}, ...) // CHECK-NEXT: ret void namespace sret { @@ -68,7 +68,7 @@ void f(C *c) { // CHECK: call x86_thiscallcc void bitcast (void (%"struct.sret::C"*, ...)* @"\01??_9C@sret@@$BA@AE" to void (%"struct.sret::C"*, %"struct.sret::Big"*)*)(%"struct.sret::C"* %{{.*}}, %"struct.sret::Big"* sret %{{.*}}) // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@sret@@$BA@AE"(%"struct.sret::C"* %this, ...) {{.*}} comdat -// CHECK: musttail call x86_thiscallcc void (%"struct.sret::C"*, ...)* %{{.*}}(%"struct.sret::C"* %{{.*}}, ...) +// CHECK: musttail call x86_thiscallcc void (%"struct.sret::C"*, ...) %{{.*}}(%"struct.sret::C"* %{{.*}}, ...) // CHECK-NEXT: ret void namespace cdecl_inalloca { @@ -97,5 +97,5 @@ void f(C *c) { // CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"\01??_9C@cdecl_inalloca@@$BA@AA" to void (<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>*)*)(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>* inalloca %{{.*}}) // CHECK-LABEL: define linkonce_odr void @"\01??_9C@cdecl_inalloca@@$BA@AA"(%"struct.cdecl_inalloca::C"* %this, ...) {{.*}} comdat -// CHECK: musttail call void (%"struct.cdecl_inalloca::C"*, ...)* %{{.*}}(%"struct.cdecl_inalloca::C"* %{{.*}}, ...) +// CHECK: musttail call void (%"struct.cdecl_inalloca::C"*, ...) %{{.*}}(%"struct.cdecl_inalloca::C"* %{{.*}}, ...) // CHECK-NEXT: ret void diff --git a/test/CodeGenCXX/static-data-member-single-emission.cpp b/test/CodeGenCXX/static-data-member-single-emission.cpp new file mode 100644 index 0000000000..8c04fab193 --- /dev/null +++ b/test/CodeGenCXX/static-data-member-single-emission.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +template <typename T> +struct HasStaticInit { +static const int index; +}; +extern "C" +int the_count = 0; +template <typename T> +const int HasStaticInit<T>::index = the_count++; + +template <typename T> int func_tmpl1() { return HasStaticInit<T>::index; } +template <typename T> int func_tmpl2() { return HasStaticInit<T>::index; } +template <typename T> int func_tmpl3() { return HasStaticInit<T>::index; } +void useit() { + func_tmpl1<int>(); + func_tmpl2<int>(); + func_tmpl3<int>(); +} + +// Throw in a final explicit instantiation to see that it doesn't screw things +// up. +template struct HasStaticInit<int>; + +// There should only be one entry, not 3. +// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] + +// There should only be one update to @the_count. +// CHECK-NOT: store i32 %{{.*}}, i32* @the_count +// CHECK: store i32 %{{.*}}, i32* @the_count +// CHECK-NOT: store i32 %{{.*}}, i32* @the_count diff --git a/test/CodeGenCXX/switch-case-folding-2.cpp b/test/CodeGenCXX/switch-case-folding-2.cpp index 930bfeb64d..b0bbf3282a 100644 --- a/test/CodeGenCXX/switch-case-folding-2.cpp +++ b/test/CodeGenCXX/switch-case-folding-2.cpp @@ -18,4 +18,4 @@ int main(void) { return test(5); } -// CHECK: call i32 (i8*, ...)* @_Z6printfPKcz +// CHECK: call i32 (i8*, ...) @_Z6printfPKcz diff --git a/test/CodeGenCXX/unknown-anytype.cpp b/test/CodeGenCXX/unknown-anytype.cpp index fe10b13daa..42ed472380 100644 --- a/test/CodeGenCXX/unknown-anytype.cpp +++ b/test/CodeGenCXX/unknown-anytype.cpp @@ -24,15 +24,15 @@ int test1() { extern "C" __unknown_anytype test2_any(...); float test2() { - // X86_64: call float (double, ...)* @test2_any(double {{[^,]+}}) - // I386: call float (double, ...)* @test2_any(double {{[^,]+}}) + // X86_64: call float (double, ...) @test2_any(double {{[^,]+}}) + // I386: call float (double, ...) @test2_any(double {{[^,]+}}) return (float) test2_any(0.5f); } extern "C" __unknown_anytype test2a_any(...); float test2a() { - // X86_64: call float (float, ...)* @test2a_any(float {{[^,]+}}) - // I386: call float (float, ...)* @test2a_any(float {{[^,]+}}) + // X86_64: call float (float, ...) @test2a_any(float {{[^,]+}}) + // I386: call float (float, ...) @test2a_any(float {{[^,]+}}) return (float) test2a_any((float) 0.5f); } @@ -119,7 +119,7 @@ void test10() { extern "C" __unknown_anytype malloc(...); void test11() { void *s = (void*)malloc(12); - // COMMON: call i8* (i32, ...)* @malloc(i32 12) + // COMMON: call i8* (i32, ...) @malloc(i32 12) void *d = (void*)malloc(435); - // COMMON: call i8* (i32, ...)* @malloc(i32 435) + // COMMON: call i8* (i32, ...) @malloc(i32 435) } diff --git a/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp b/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp index 450860e1e6..530a4284b4 100644 --- a/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp +++ b/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp @@ -13,14 +13,14 @@ void test(X x) { // CHECK-LABEL: define void @"\01?test@@YAXUX@@@Z" // X86: %[[argmem:[^ ]*]] = alloca inalloca <{ %struct.X }> - // X86: call void (<{ %struct.X }>*, ...)* bitcast (void (...)* @"\01?vararg@@YAXZZ" to void (<{ %struct.X }>*, ...)*)(<{ %struct.X }>* inalloca %[[argmem]]) + // X86: call void (<{ %struct.X }>*, ...) bitcast (void (...)* @"\01?vararg@@YAXZZ" to void (<{ %struct.X }>*, ...)*)(<{ %struct.X }>* inalloca %[[argmem]]) // X64: alloca %struct.X // X64: %[[agg:[^ ]*]] = alloca %struct.X // X64: %[[valptr:[^ ]*]] = getelementptr %struct.X, %struct.X* %[[agg]], i32 0, i32 0 // X64: %[[val:[^ ]*]] = load i32, i32* %[[valptr]] - // X64: call void (...)* @"\01?vararg@@YAXZZ"(i32 %[[val]]) + // X64: call void (...) @"\01?vararg@@YAXZZ"(i32 %[[val]]) // CHECK-NOT: llvm.trap vararg(x); diff --git a/test/CodeGenCXX/varargs.cpp b/test/CodeGenCXX/varargs.cpp index 3159dc68af..1ea072e2eb 100644 --- a/test/CodeGenCXX/varargs.cpp +++ b/test/CodeGenCXX/varargs.cpp @@ -12,7 +12,7 @@ namespace test0 { return -1; } - // CHECK: call i32 (...)* @_ZN5test05test1Ez(i32 0) + // CHECK: call i32 (...) @_ZN5test05test1Ez(i32 0) void test() { test1(0); } @@ -38,6 +38,6 @@ namespace test1 { // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T0]], i8* [[T1]], i64 8, i32 4, i1 false) // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[TMP]] to i64* // CHECK-NEXT: [[T1:%.*]] = load i64, i64* [[T0]], align 1 - // CHECK-NEXT: call void (...)* @_ZN5test13fooEz(i64 [[T1]]) + // CHECK-NEXT: call void (...) @_ZN5test13fooEz(i64 [[T1]]) // CHECK-NEXT: ret void } diff --git a/test/CodeGenCXX/vla-lambda-capturing.cpp b/test/CodeGenCXX/vla-lambda-capturing.cpp index 27d263b727..f2332bf0dc 100644 --- a/test/CodeGenCXX/vla-lambda-capturing.cpp +++ b/test/CodeGenCXX/vla-lambda-capturing.cpp @@ -22,7 +22,7 @@ typedef __INTPTR_TYPE__ intptr_t; // CHECK: store [[INTPTR_T]]* %{{.+}}, [[INTPTR_T]]** [[CAP_BUFFER_ADDR]] // CHECK: [[CAP_N_REF:%.+]] = getelementptr inbounds [[CAP_TYPE1]], [[CAP_TYPE1]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 2 // CHECK: store [[INTPTR_T]]* [[N_ADDR]], [[INTPTR_T]]** [[CAP_N_REF]] -// CHECK: call void [[G_LAMBDA:@.+]]([[CAP_TYPE1]]* [[CAP_ARG]]) +// CHECK: call{{( x86_thiscallcc)?}} void [[G_LAMBDA:@.+]]([[CAP_TYPE1]]* [[CAP_ARG]]) // CHECK: ret void void g(intptr_t n) { intptr_t buffer[n]; @@ -88,7 +88,7 @@ int main() { // CHECK: store [[INTPTR_T]] [[SIZE]], [[INTPTR_T]]* [[CAP_SIZE_REF]] // CHECK: [[CAP_BUFFER_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]], [[CAP_TYPE2]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1 // CHECK: store [[INTPTR_T]]* [[BUFFER_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER_ADDR_REF]] -// CHECK: call void [[F_INT_LAMBDA:@.+]]([[CAP_TYPE2]]* [[CAP_ARG]]) +// CHECK: call{{( x86_thiscallcc)?}} void [[F_INT_LAMBDA:@.+]]([[CAP_TYPE2]]* [[CAP_ARG]]) // CHECK: call void @llvm.stackrestore( // CHECK: ret void // CHECK: void [[B_INT]]([[INTPTR_T]] @@ -107,11 +107,11 @@ int main() { // CHECK: store [[INTPTR_T]]* [[BUFFER1_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER1_ADDR_REF]] // CHECK: [[CAP_BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 4 // CHECK: store [[INTPTR_T]]* [[BUFFER2_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER2_ADDR_REF]] -// CHECK: call void [[B_INT_LAMBDA:@.+]]([[CAP_TYPE3]]* [[CAP_ARG]]) +// CHECK: call{{( x86_thiscallcc)?}} void [[B_INT_LAMBDA:@.+]]([[CAP_TYPE3]]* [[CAP_ARG]]) // CHECK: call void @llvm.stackrestore( // CHECK: ret void -// CHECK: define linkonce_odr void [[F_INT_LAMBDA]]([[CAP_TYPE2]]* +// CHECK: define linkonce_odr{{( x86_thiscallcc)?}} void [[F_INT_LAMBDA]]([[CAP_TYPE2]]* // CHECK: [[THIS:%.+]] = load [[CAP_TYPE2]]*, [[CAP_TYPE2]]** // CHECK: [[SIZE_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]], [[CAP_TYPE2]]* [[THIS]], i{{.+}} 0, i{{.+}} 0 // CHECK: [[SIZE:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[SIZE_REF]] @@ -120,7 +120,7 @@ int main() { // CHECK: call void @llvm.stackrestore( // CHECK: ret void -// CHECK: define {{.*}} void [[B_INT_LAMBDA]]([[CAP_TYPE3]]* +// CHECK: define linkonce_odr{{( x86_thiscallcc)?}} void [[B_INT_LAMBDA]]([[CAP_TYPE3]]* // CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 // CHECK: [[SIZE2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE2_REF]] // CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 @@ -152,10 +152,10 @@ int main() { // CHECK: [[BUFFER1_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 // CHECK: [[BUFFER1_ADDR_ORIG:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER1_ADDR_REF_ORIG]] // CHECK: store [[INTPTR_T]]* [[BUFFER1_ADDR_ORIG]], [[INTPTR_T]]** [[BUFFER1_ADDR_REF]] -// CHECK: call void [[B_INT_LAMBDA_LAMBDA:@.+]]([[CAP_TYPE4]]* [[CAP]]) +// CHECK: call{{( x86_thiscallcc)?}} void [[B_INT_LAMBDA_LAMBDA:@.+]]([[CAP_TYPE4]]* [[CAP]]) // CHECK: ret void -// CHECK: define {{.*}} void [[B_INT_LAMBDA_LAMBDA]]([[CAP_TYPE4]]* +// CHECK: define linkonce_odr{{( x86_thiscallcc)?}} void [[B_INT_LAMBDA_LAMBDA]]([[CAP_TYPE4]]* // CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[THIS:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 // CHECK: [[SIZE1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE1_REF]] // CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m index 76106bb2fb..45599e22b3 100644 --- a/test/CodeGenObjC/arc-blocks.m +++ b/test/CodeGenObjC/arc-blocks.m @@ -87,7 +87,7 @@ void test3(void (^sink)(id*)) { // CHECK-NEXT: call void [[F1]](i8* [[BLOCK]], i8** [[TEMP]]) // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[TEMP]] // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) - // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V]]) [[NUW]] + // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[V]]) [[NUW]] // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[STRONG]] // CHECK-NEXT: store i8* [[T1]], i8** [[STRONG]] // CHECK-NEXT: call void @objc_release(i8* [[T2]]) diff --git a/test/CodeGenObjC/arc-literals.m b/test/CodeGenObjC/arc-literals.m index cce4a79de9..bb7b9759a2 100644 --- a/test/CodeGenObjC/arc-literals.m +++ b/test/CodeGenObjC/arc-literals.m @@ -56,7 +56,7 @@ void test_array(id a, id b) { // 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]]) + // CHECK: call void (...) @clang.arc.use(i8* [[V0]], i8* [[V1]]) id arr = @[a, b]; // CHECK: call void @objc_release @@ -100,7 +100,7 @@ void test_dictionary(id k1, id o1, id k2, id o2) { // 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]]) + // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]]) id dict = @{ k1 : o1, k2 : o2 }; @@ -145,7 +145,7 @@ void test_property(B *b) { // 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: call void (...) @clang.arc.use(i8* [[V1]]) // CHECK-NEXT: bitcast // CHECK-NEXT: bitcast // CHECK-NEXT: store diff --git a/test/CodeGenObjC/arc-ternary-op.m b/test/CodeGenObjC/arc-ternary-op.m index 3e96e40757..b9848d794b 100644 --- a/test/CodeGenObjC/arc-ternary-op.m +++ b/test/CodeGenObjC/arc-ternary-op.m @@ -67,7 +67,7 @@ void test1(int cond) { // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = load i8*, i8** [[TEMP1]] // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) - // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W]]) [[NUW]] + // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[W]]) [[NUW]] // CHECK-NEXT: [[T2:%.*]] = load i8*, 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 148d8e1bd0..4c968584a0 100644 --- a/test/CodeGenObjC/arc.m +++ b/test/CodeGenObjC/arc.m @@ -875,7 +875,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: call void (...) @clang.arc.use([[A_T]]* [[W0]]) [[NUW]] // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]*, [[A_T]]** [[A]] // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* @@ -891,7 +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: call void (...) @clang.arc.use([[A_T]]* [[W0]]) [[NUW]] // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]*, [[A_T]]** [[A]] // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* @@ -974,7 +974,7 @@ void test37(void) { // 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: call void (...) @clang.arc.use(i8* [[W1]]) [[NUW]] // CHECK-NEXT: [[T5:%.*]] = load [[TEST37]]*, [[TEST37]]** [[VAR]] // CHECK-NEXT: store [[TEST37]]* [[T4]], [[TEST37]]** [[VAR]] // CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST37]]* [[T5]] to i8* diff --git a/test/CodeGenObjC/blocks.m b/test/CodeGenObjC/blocks.m index fa86e363f3..091331e8b2 100644 --- a/test/CodeGenObjC/blocks.m +++ b/test/CodeGenObjC/blocks.m @@ -116,7 +116,7 @@ void test3(void (^block)(int, ...)) { // CHECK-NEXT: [[T3:%.*]] = bitcast [[BLOCK_T]]* [[T1]] to i8* // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T2]] // CHECK-NEXT: [[T5:%.*]] = bitcast i8* [[T4]] to void (i8*, i32, ...)* -// CHECK-NEXT: call void (i8*, i32, ...)* [[T5]](i8* [[T3]], i32 0, i32 1, i32 2, i32 3) +// CHECK-NEXT: call void (i8*, i32, ...) [[T5]](i8* [[T3]], i32 0, i32 1, i32 2, i32 3) // CHECK-NEXT: ret void void test4(void (^block)()) { diff --git a/test/CodeGenObjC/compound-literal-property-access.m b/test/CodeGenObjC/compound-literal-property-access.m new file mode 100644 index 0000000000..bc1bd78e0c --- /dev/null +++ b/test/CodeGenObjC/compound-literal-property-access.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-darwin -o - | FileCheck %s +// rdar://20407999 + +typedef __attribute__((__ext_vector_type__(2))) float vector_float2; + +@interface GPAgent2D +@property (nonatomic, assign) vector_float2 position; +@end + +@interface GPGoal @end + +@implementation GPGoal +-(void)getForce { + GPAgent2D* targetAgent; + (vector_float2){targetAgent.position.x, targetAgent.position.y}; +} +@end + +// CHECK: [[CL:%.*]] = alloca <2 x float>, align 8 +// CHECK: store <2 x float> [[VECINIT:%.*]], <2 x float>* [[CL]] +// CHECK: [[FOURTEEN:%.*]] = load <2 x float>, <2 x float>* [[CL]] diff --git a/test/CodeGenObjC/objc2-protocol-metadata.m b/test/CodeGenObjC/objc2-protocol-metadata.m new file mode 100644 index 0000000000..191016be85 --- /dev/null +++ b/test/CodeGenObjC/objc2-protocol-metadata.m @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10 -emit-llvm -o - %s | FileCheck %s +// rdar://20286356 + +@protocol P1 +- InstP; ++ ClsP; +@end + +@interface INTF <P1> +@end + +@implementation INTF +- InstP { return 0; } ++ ClsP { return 0; } +@end + +// CHECK: %struct._protocol_t = type { i8*, i8*, %struct._objc_protocol_list*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct._prop_list_t*, i32, i32, i8**, i8* } diff --git a/test/CodeGenObjC/objfw.m b/test/CodeGenObjC/objfw.m index 8e72867fcd..918b9bf413 100644 --- a/test/CodeGenObjC/objfw.m +++ b/test/CodeGenObjC/objfw.m @@ -9,7 +9,7 @@ void test0(void) { [Test0 test]; } // CHECK-LABEL: define void @test0() -// CHECK: [[T0:%.*]] = call i8* (i8*, i8*, ...)* (i8*, i8*)* @objc_msg_lookup(i8* bitcast (i64* @_OBJC_CLASS_Test0 to i8*), +// CHECK: [[T0:%.*]] = call i8* (i8*, i8*, ...)* @objc_msg_lookup(i8* bitcast (i64* @_OBJC_CLASS_Test0 to i8*), // CHECK-NEXT: [[T1:%.*]] = bitcast i8* (i8*, i8*, ...)* [[T0]] to void (i8*, i8*)* // CHECK-NEXT: call void [[T1]](i8* bitcast (i64* @_OBJC_CLASS_Test0 to i8*), // CHECK-NEXT: ret void diff --git a/test/CodeGenObjC/property.m b/test/CodeGenObjC/property.m index ee113780b6..4d884111ad 100644 --- a/test/CodeGenObjC/property.m +++ b/test/CodeGenObjC/property.m @@ -99,7 +99,7 @@ void test4(Test4 *t) { extern int test4_printf(const char *, ...); // CHECK: [[TMP:%.*]] = call float {{.*}} @objc_msgSend // CHECK-NEXT: [[EXT:%.*]] = fpext float [[TMP]] to double - // CHECK-NEXT: call i32 (i8*, ...)* @test4_printf(i8* {{.*}}, double [[EXT]]) + // CHECK-NEXT: call i32 (i8*, ...) @test4_printf(i8* {{.*}}, double [[EXT]]) // CHECK-NEXT: ret void test4_printf("%.2f", t.f); } diff --git a/test/CodeGenObjC/stret_lookup.m b/test/CodeGenObjC/stret_lookup.m index 6682fac7ae..9f14798020 100644 --- a/test/CodeGenObjC/stret_lookup.m +++ b/test/CodeGenObjC/stret_lookup.m @@ -19,11 +19,11 @@ void test0(void) { } // HASSTRET-LABEL: define void @test0() -// HASSTRET: [[T0:%.*]] = call i8* (i8*, i8*, ...)* (i8*, i8*)* @objc_msg_lookup_stret(i8* bitcast (i64* @_OBJC_CLASS_Test0 to i8*), +// HASSTRET: [[T0:%.*]] = call i8* (i8*, i8*, ...)* @objc_msg_lookup_stret(i8* bitcast (i64* @_OBJC_CLASS_Test0 to i8*), // HASSTRET-NEXT: [[T1:%.*]] = bitcast i8* (i8*, i8*, ...)* [[T0]] to void (%struct.test*, i8*, i8*)* // HASSTRET-NEXT: call void [[T1]](%struct.test* sret {{.*}}, i8* bitcast (i64* @_OBJC_CLASS_Test0 to i8*), // NOSTRET-LABEL: define void @test0() -// NOSTRET: [[T0:%.*]] = call i8* (i8*, i8*, ...)* (i8*, i8*)* @objc_msg_lookup(i8* +// NOSTRET: [[T0:%.*]] = call i8* (i8*, i8*, ...)* @objc_msg_lookup(i8* // NOSTRET-NEXT: [[T1:%.*]] = bitcast i8* (i8*, i8*, ...)* [[T0]] to void (%struct.test*, i8*, i8*)* // NOSTRET-NEXT: call void [[T1]](%struct.test* sret {{.*}}, i8* {{.*}}, i8* bitcast ([2 x { i8*, i8* }]* diff --git a/test/CodeGenObjC/tentative-cfconstantstring.m b/test/CodeGenObjC/tentative-cfconstantstring.m index 2f31916f5a..5b3c3bd924 100644 --- a/test/CodeGenObjC/tentative-cfconstantstring.m +++ b/test/CodeGenObjC/tentative-cfconstantstring.m @@ -38,6 +38,6 @@ static inline void _inlineFunction() { // CHECK: [[ZERO:%.*]] = load %struct._class_t*, %struct._class_t** @"OBJC_CLASSLIST_REFERENCES_ // CHECK-NEXT: [[ONE:%.*]] = load i8*, i8** @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: 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/CodeGenObjC/variadic-sends.m b/test/CodeGenObjC/variadic-sends.m index 726b497b21..3815bb3430 100644 --- a/test/CodeGenObjC/variadic-sends.m +++ b/test/CodeGenObjC/variadic-sends.m @@ -20,8 +20,8 @@ void f1(A *a) { } void f2(A *a) { - // CHECK-X86-32: call void (i8*, i8*, i32, ...)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, ...)*) - // CHECK-X86-64: call void (i8*, i8*, i32, ...)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, ...)*) + // CHECK-X86-32: call void (i8*, i8*, i32, ...) bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, ...)*) + // CHECK-X86-64: call void (i8*, i8*, i32, ...) bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, ...)*) [a im2: 1, 2]; } @@ -33,8 +33,8 @@ void f2(A *a) { [super im1: 1]; } -(void) bar { - // CHECK-X86-32: call void (%struct._objc_super*, i8*, i32, ...)* bitcast (i8* (%struct._objc_super*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, i8*, i32, ...)*) - // CHECK-X86-64: call void (%struct._objc_super*, i8*, i32, ...)* bitcast (i8* (%struct._objc_super*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, i8*, i32, ...)*) + // CHECK-X86-32: call void (%struct._objc_super*, i8*, i32, ...) bitcast (i8* (%struct._objc_super*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, i8*, i32, ...)*) + // CHECK-X86-64: call void (%struct._objc_super*, i8*, i32, ...) bitcast (i8* (%struct._objc_super*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, i8*, i32, ...)*) [super im2: 1, 2]; } diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm index c66417ba24..e70af31690 100644 --- a/test/CodeGenObjCXX/arc.mm +++ b/test/CodeGenObjCXX/arc.mm @@ -82,7 +82,7 @@ void test34(int cond) { // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = load i8*, i8** [[TEMP1]] // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) - // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W0]]) + // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[W0]]) // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[ARG]] // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]] // CHECK-NEXT: call void @objc_release(i8* [[T2]]) diff --git a/test/CodeGenObjCXX/lambda-expressions.mm b/test/CodeGenObjCXX/lambda-expressions.mm index 4d9b8d0bd3..0c309c0a4e 100644 --- a/test/CodeGenObjCXX/lambda-expressions.mm +++ b/test/CodeGenObjCXX/lambda-expressions.mm @@ -10,8 +10,8 @@ fp f() { auto x = []{ return 3; }; return x; } // MRC-LABEL: define internal i32 ()* @"_ZZ1fvENK3$_0cvU13block_pointerFivEEv" // MRC: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*) // MRC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke" to i8*) -// MRC: call i32 ()* (i8*, i8*)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 ()* (i8*, i8*)*) -// MRC: call i32 ()* (i8*, i8*)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 ()* (i8*, i8*)*) +// MRC: call i32 ()* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 ()* (i8*, i8*)*) +// MRC: call i32 ()* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 ()* (i8*, i8*)*) // MRC: ret i32 ()* // ARC-LABEL: define i32 ()* @_Z1fv( diff --git a/test/CodeGenOpenCL/memcpy.cl b/test/CodeGenOpenCL/memcpy.cl new file mode 100644 index 0000000000..cb27803adf --- /dev/null +++ b/test/CodeGenOpenCL/memcpy.cl @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -ffake-address-space-map -emit-llvm -o - | FileCheck %s + +// CHECK-LABEL: @test +// CHECK-NOT: addrspacecast +// CHECK: call void @llvm.memcpy.p1i8.p3i8 +kernel void test(global float *g, constant float *c) { + __builtin_memcpy(g, c, 32); +} diff --git a/test/CodeGenOpenCL/relaxed-fpmath.cl b/test/CodeGenOpenCL/relaxed-fpmath.cl index 4222ea9c74..6f302b1335 100644 --- a/test/CodeGenOpenCL/relaxed-fpmath.cl +++ b/test/CodeGenOpenCL/relaxed-fpmath.cl @@ -2,7 +2,6 @@ // RUN: %clang_cc1 %s -emit-llvm -cl-fast-relaxed-math -o - | FileCheck %s -check-prefix=FAST // RUN: %clang_cc1 %s -emit-llvm -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE // RUN: %clang_cc1 %s -emit-llvm -cl-unsafe-math-optimizations -o - | FileCheck %s -check-prefix=UNSAFE -// RUN: %clang_cc1 %s -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSZ typedef __attribute__(( ext_vector_type(4) )) float float4; @@ -13,7 +12,6 @@ float spscalardiv(float a, float b) { // FAST: fdiv fast float // FINITE: fdiv nnan ninf float // UNSAFE: fdiv nnan float - // NOSZ: fdiv nsz float return a / b; } // CHECK: attributes diff --git a/test/Driver/aarch64-cpus.c b/test/Driver/aarch64-cpus.c index 4380381a6f..43e3ccd459 100644 --- a/test/Driver/aarch64-cpus.c +++ b/test/Driver/aarch64-cpus.c @@ -88,3 +88,26 @@ // RUN: %clang -target aarch64 -mcpu=cortex-a72 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s // RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s // MCPU-MTUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a53" + +// RUN: %clang -target aarch64 -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s +// RUN: %clang -target aarch64 -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s +// RUN: %clang -target aarch64 -mlittle-endian -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s +// RUN: %clang -target aarch64 -mlittle-endian -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s +// RUN: %clang -target aarch64_be -mlittle-endian -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s +// RUN: %clang -target aarch64_be -mlittle-endian -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s +// GENERICV81A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.1a" + +// RUN: %clang -target arm64 -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV81A %s +// RUN: %clang -target arm64 -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV81A %s +// RUN: %clang -target arm64 -mlittle-endian -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV81A %s +// RUN: %clang -target arm64 -mlittle-endian -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV81A %s +// ARM64-GENERICV81A: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.1a" + +// RUN: %clang -target aarch64_be -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s +// RUN: %clang -target aarch64_be -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s +// RUN: %clang -target aarch64 -mbig-endian -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s +// RUN: %clang -target aarch64 -mbig-endian -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s +// RUN: %clang -target aarch64_be -mbig-endian -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s +// RUN: %clang -target aarch64_be -mbig-endian -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s +// GENERICV81A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.1a" + diff --git a/test/Driver/arm-cortex-cpus.c b/test/Driver/arm-cortex-cpus.c index 2d6c7e6898..7810bdd971 100644 --- a/test/Driver/arm-cortex-cpus.c +++ b/test/Driver/arm-cortex-cpus.c @@ -281,33 +281,41 @@ // CHECK-BE-CPUV7EM: "-cc1"{{.*}} "-triple" "thumbebv7em-{{.*}} // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s +// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4f -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r7 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s +// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4f -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r7 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s // CHECK-CPUV7R: "-cc1"{{.*}} "-triple" "armv7r-{{.*}} // RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s +// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r4f -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s // RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s // RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r7 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s +// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4f -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r7 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s // CHECK-BE-CPUV7R: "-cc1"{{.*}} "-triple" "armebv7r-{{.*}} // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s +// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4f -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r7 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s +// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4f -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r7 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s // CHECK-CPUV7R-THUMB: "-cc1"{{.*}} "-triple" "thumbv7r-{{.*}} // RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s +// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r4f -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s // RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r5 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s // RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r7 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s +// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4f -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r7 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s // CHECK-BE-CPUV7R-THUMB: "-cc1"{{.*}} "-triple" "thumbebv7r-{{.*}} diff --git a/test/Driver/cl-options.c b/test/Driver/cl-options.c index 3a22154d60..e36462dab6 100644 --- a/test/Driver/cl-options.c +++ b/test/Driver/cl-options.c @@ -30,6 +30,24 @@ // EP: "-P" // EP: "-o" "-" +// RUN: %clang_cl /fp:fast /fp:except -### -- %s 2>&1 | FileCheck -check-prefix=fpexcept %s +// fpexcept-NOT: -menable-unsafe-fp-math + +// RUN: %clang_cl /fp:fast /fp:except /fp:except- -### -- %s 2>&1 | FileCheck -check-prefix=fpexcept_ %s +// fpexcept_: -menable-unsafe-fp-math + +// RUN: %clang_cl /fp:precise /fp:fast -### -- %s 2>&1 | FileCheck -check-prefix=fpfast %s +// fpfast: -menable-unsafe-fp-math +// fpfast: -ffast-math + +// RUN: %clang_cl /fp:fast /fp:precise -### -- %s 2>&1 | FileCheck -check-prefix=fpprecise %s +// fpprecise-NOT: -menable-unsafe-fp-math +// fpprecise-NOT: -ffast-math + +// RUN: %clang_cl /fp:fast /fp:strict -### -- %s 2>&1 | FileCheck -check-prefix=fpstrict %s +// fpstrict-NOT: -menable-unsafe-fp-math +// fpstrict-NOT: -ffast-math + // RTTI is on by default; just check that we don't error. // RUN: %clang_cl /Zs /GR -- %s 2>&1 @@ -243,7 +261,6 @@ // RUN: /Fifoo \ // RUN: /Fmfoo \ // RUN: /FpDebug\main.pch \ -// RUN: /fp:precise \ // RUN: /Frfoo \ // RUN: /FRfoo \ // RUN: /FU foo \ @@ -326,16 +343,22 @@ // ThreadSafeStatics-NOT: "-fno-threadsafe-statics" // Accept "core" clang options. -// (/Zs is for syntax-only) +// (/Zs is for syntax-only, -Werror makes it fail hard on unknown options) // RUN: %clang_cl \ // RUN: --driver-mode=cl \ +// RUN: -fcolor-diagnostics \ +// RUN: -fno-color-diagnostics \ +// RUN: -fdiagnostics-color \ +// RUN: -fno-diagnostics-color \ // RUN: -ferror-limit=10 \ // RUN: -fmsc-version=1800 \ // RUN: -fno-strict-aliasing \ // RUN: -fstrict-aliasing \ +// RUN: -fsyntax-only \ // RUN: -mllvm -disable-llvm-optzns \ -// RUN: -Wunused-variables \ -// RUN: /Zs -- %s 2>&1 +// RUN: -Wunused-variable \ +// RUN: -fmacro-backtrace-limit=0 \ +// RUN: -Werror /Zs -- %s 2>&1 void f() { } diff --git a/test/Driver/darwin-version.c b/test/Driver/darwin-version.c index 8e909278a5..3e7496b6bc 100644 --- a/test/Driver/darwin-version.c +++ b/test/Driver/darwin-version.c @@ -30,6 +30,9 @@ // RUN: %clang -target x86_64-apple-macosx -mmacosx-version-min=10.10 -c %s -### 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK-VERSION-OSX10 %s // CHECK-VERSION-OSX10: "x86_64-apple-macosx10.10.0" +// RUN: %clang -target x86_64-apple-macosx -mmacosx-version-min= -c %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-VERSION-MISSING %s +// CHECK-VERSION-MISSING: invalid version number // Check environment variable gets interpreted correctly // RUN: env MACOSX_DEPLOYMENT_TARGET=10.5 \ diff --git a/test/Driver/fast-math.c b/test/Driver/fast-math.c index bacd7fe4cb..24c30386da 100644 --- a/test/Driver/fast-math.c +++ b/test/Driver/fast-math.c @@ -40,6 +40,21 @@ // CHECK-NO-SIGNED-ZEROS-NO-FAST-MATH: "-cc1" // CHECK-NO-SIGNED-ZEROS-NO-FAST-MATH-NOT: "-fno-signed-zeros" // +// RUN: %clang -### -freciprocal-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RECIPROCAL-MATH %s +// CHECK-RECIPROCAL-MATH: "-cc1" +// CHECK-RECIPROCAL-MATH: "-freciprocal-math" +// +// RUN: %clang -### -fno-fast-math -freciprocal-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NO-FAST-MATH-RECIPROCAL-MATH %s +// CHECK-NO-FAST-MATH-RECIPROCAL-MATH: "-cc1" +// CHECK-NO-FAST-MATH-RECIPROCAL-MATH: "-freciprocal-math" +// +// RUN: %clang -### -freciprocal-math -fno-fast-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RECIPROCAL-MATH-NO-FAST-MATH %s +// CHECK-RECIPROCAL-MATH-NO-FAST-MATH: "-cc1" +// CHECK-RECIPROCAL-MATH-NO-FAST-MATH-NOT: "-freciprocal-math" +// // RUN: %clang -### -fno-honor-nans -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NO-NANS %s // CHECK-NO-NANS: "-cc1" diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c index da8ace3055..994b2b236c 100644 --- a/test/Driver/fsanitize.c +++ b/test/Driver/fsanitize.c @@ -206,11 +206,13 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI // RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-derived-cast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-DCAST // RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-unrelated-cast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-UCAST -// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-vptr -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-VPTR -// CHECK-CFI: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast,cfi-unrelated-cast,cfi-vptr +// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-nvcall -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NVCALL +// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-vcall -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-VCALL +// CHECK-CFI: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall // CHECK-CFI-DCAST: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast // CHECK-CFI-UCAST: -emit-llvm-bc{{.*}}-fsanitize=cfi-unrelated-cast -// CHECK-CFI-VPTR: -emit-llvm-bc{{.*}}-fsanitize=cfi-vptr +// CHECK-CFI-NVCALL: -emit-llvm-bc{{.*}}-fsanitize=cfi-nvcall +// CHECK-CFI-VCALL: -emit-llvm-bc{{.*}}-fsanitize=cfi-vcall // RUN: %clang_cl -fsanitize=address -c -MDd -### -- %s 2>&1 | FileCheck %s -check-prefix=CHECK-ASAN-DEBUGRTL // RUN: %clang_cl -fsanitize=address -c -MTd -### -- %s 2>&1 | FileCheck %s -check-prefix=CHECK-ASAN-DEBUGRTL @@ -229,3 +231,11 @@ // RUN: %clang_cl -fsanitize=address -c -MDd -MD -### -- %s 2>&1 | FileCheck %s -check-prefix=CHECK-ASAN-RELEASERTL // RUN: %clang_cl -fsanitize=address -c -LDd -LD -### -- %s 2>&1 | FileCheck %s -check-prefix=CHECK-ASAN-RELEASERTL // CHECK-ASAN-RELEASERTL-NOT: error: invalid argument + +// RUN: %clang_cl -fsanitize=address -fsanitize-coverage=1 -c -### -- %s 2>&1 | FileCheck %s -check-prefix=CLANG-CL-COVERAGE +// CLANG-CL-COVERAGE-NOT: error: +// CLANG-CL-COVERAGE-NOT: warning: +// CLANG-CL-COVERAGE-NOT: argument unused +// CLANG-CL-COVERAGE-NOT: unknown argument +// CLANG-CL-COVERAGE: -fsanitize=address +// CLANG-CL-COVERAGE: -fsanitize-coverage=1 diff --git a/test/Driver/function-sections.c b/test/Driver/function-sections.c index ba065b1367..6c243195f6 100644 --- a/test/Driver/function-sections.c +++ b/test/Driver/function-sections.c @@ -72,3 +72,13 @@ // RUN: -target i386-unknown-linux \ // RUN: -fno-unique-section-names \ // RUN: | FileCheck --check-prefix=CHECK-NOUS %s + +// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ +// RUN: -target i386-unknown-linux \ +// RUN: -fno-integrated-as \ +// RUN: | FileCheck --check-prefix=CHECK-US %s + +// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ +// RUN: -target i386-unknown-linux \ +// RUN: -fintegrated-as \ +// RUN: | FileCheck --check-prefix=CHECK-NOUS %s diff --git a/test/Driver/mglobal-merge.c b/test/Driver/mglobal-merge.c new file mode 100644 index 0000000000..ad76736a69 --- /dev/null +++ b/test/Driver/mglobal-merge.c @@ -0,0 +1,40 @@ +// RUN: %clang -target armv7-unknown-unknown -### -fsyntax-only %s 2> %t \ +// RUN: -mno-global-merge +// RUN: FileCheck --check-prefix=CHECK-NGM-ARM < %t %s + +// RUN: %clang -target aarch64-unknown-unknown -### -fsyntax-only %s 2> %t \ +// RUN: -mno-global-merge +// RUN: FileCheck --check-prefix=CHECK-NGM-AARCH64 < %t %s + +// RUN: %clang -target x86_64-unknown-unknown -### -fsyntax-only %s 2> %t \ +// RUN: -mno-global-merge +// RUN: FileCheck --check-prefix=CHECK-NONE < %t %s + +// CHECK-NGM-ARM: "-backend-option" "-arm-global-merge=false" +// CHECK-NGM-AARCH64: "-backend-option" "-aarch64-global-merge=false" + +// RUN: %clang -target armv7-unknown-unknown -### -fsyntax-only %s 2> %t \ +// RUN: -mglobal-merge +// RUN: FileCheck --check-prefix=CHECK-GM-ARM < %t %s + +// RUN: %clang -target aarch64-unknown-unknown -### -fsyntax-only %s 2> %t \ +// RUN: -mglobal-merge +// RUN: FileCheck --check-prefix=CHECK-GM-AARCH64 < %t %s + +// RUN: %clang -target x86_64-unknown-unknown -### -fsyntax-only %s 2> %t \ +// RUN: -mglobal-merge +// RUN: FileCheck --check-prefix=CHECK-NONE < %t %s + +// CHECK-GM-ARM: "-backend-option" "-arm-global-merge=true" +// CHECK-GM-AARCH64: "-backend-option" "-aarch64-global-merge=true" + +// RUN: %clang -target armv7-unknown-unknown -### -fsyntax-only %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-NONE < %t %s + +// RUN: %clang -target aarch64-unknown-unknown -### -fsyntax-only %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-NONE < %t %s + +// RUN: %clang -target x86_64-unknown-unknown -### -fsyntax-only %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-NONE < %t %s + +// CHECK-NONE-NOT: -global-merge= diff --git a/test/Driver/mips-features.c b/test/Driver/mips-features.c index f7022306fc..5094f2b09b 100644 --- a/test/Driver/mips-features.c +++ b/test/Driver/mips-features.c @@ -105,13 +105,13 @@ // CHECK-NOMFP64: "-target-feature" "-fp64" // // -mnan=2008 -// RUN: %clang -target mips-linux-gnu -### -c %s \ +// RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \ // RUN: -mnan=legacy -mnan=2008 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NAN2008 %s // CHECK-NAN2008: "-target-feature" "+nan2008" // // -mnan=legacy -// RUN: %clang -target mips-linux-gnu -### -c %s \ +// RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \ // RUN: -mnan=2008 -mnan=legacy 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NANLEGACY %s // CHECK-NANLEGACY: "-target-feature" "-nan2008" diff --git a/test/Driver/mips-integrated-as.s b/test/Driver/mips-integrated-as.s index 08adb204cb..2c298e7552 100644 --- a/test/Driver/mips-integrated-as.s +++ b/test/Driver/mips-integrated-as.s @@ -62,7 +62,7 @@ // NAN-LEGACY: -cc1as // NAN-LEGACY: "-target-feature" "-nan2008" -// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mnan=2008 2>&1 | \ +// RUN: %clang -target mips-linux-gnu -march=mips32r6 -### -fintegrated-as -c %s -mnan=2008 2>&1 | \ // RUN: FileCheck -check-prefix=NAN-2008 %s // NAN-2008: -cc1as // NAN-2008: "-target-feature" "+nan2008" diff --git a/test/Driver/mno-global-merge.c b/test/Driver/mno-global-merge.c deleted file mode 100644 index a17848f04d..0000000000 --- a/test/Driver/mno-global-merge.c +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang -target armv7-apple-darwin10 \ -// RUN: -mno-global-merge -### -fsyntax-only %s 2> %t -// RUN: FileCheck --check-prefix=CHECK-NGM < %t %s - -// RUN: %clang -target arm64-apple-ios7 \ -// RUN: -mno-global-merge -### -fsyntax-only %s 2> %t -// RUN: FileCheck --check-prefix=CHECK-NGM < %t %s - -// CHECK-NGM: "-mno-global-merge" - -// RUN: %clang -target armv7-apple-darwin10 \ -// RUN: -mglobal-merge -### -fsyntax-only %s 2> %t -// RUN: FileCheck --check-prefix=CHECK-GM < %t %s - -// RUN: %clang -target arm64-apple-ios7 \ -// RUN: -mglobal-merge -### -fsyntax-only %s 2> %t -// RUN: FileCheck --check-prefix=CHECK-GM < %t %s - -// CHECK-GM-NOT: "-mglobal-merge" - diff --git a/test/Driver/nacl-direct.c b/test/Driver/nacl-direct.c new file mode 100644 index 0000000000..9768eab24d --- /dev/null +++ b/test/Driver/nacl-direct.c @@ -0,0 +1,111 @@ +// Test clang changes for NaCl Support including: +// include paths, library paths, emulation, default static +// +// RUN: %clang -no-canonical-prefixes -### -o %t.o %s \ +// RUN: -target i686-unknown-nacl -resource-dir foo 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-I686 %s +// CHECK-I686: {{.*}}clang{{.*}}" "-cc1" +// CHECK-I686: "-fuse-init-array" +// CHECK-I686: "-target-cpu" "pentium4" +// CHECK-I686: "-resource-dir" "foo" +// CHECK-I686: "-internal-isystem" "foo{{/|\\\\}}include" +// CHECK-I686: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}usr{{/|\\\\}}include" +// CHECK-I686: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}include" +// CHECK-I686: as{{(.exe)?}}" "--32" +// CHECK-I686: ld{{(.exe)?}}" +// CHECK-I686: "--build-id" +// CHECK-I686: "-m" "elf_i386_nacl" +// CHECK-I686: "-static" +// CHECK-I686: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}lib32" +// CHECK-I686: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}usr{{/|\\\\}}lib32" +// CHECK-I686: "-Lfoo{{/|\\\\}}lib{{/|\\\\}}i686-nacl" +// CHECK-I686-NOT: -lpthread +// +// RUN: %clang -no-canonical-prefixes -### -o %t.o %s \ +// RUN: -target x86_64-unknown-nacl -resource-dir foo 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-x86_64 %s +// CHECK-x86_64: {{.*}}clang{{.*}}" "-cc1" +// CHECK-x86_64: "-fuse-init-array" +// CHECK-x86_64: "-target-cpu" "x86-64" +// CHECK-x86_64: "-resource-dir" "foo" +// CHECK-x86_64: "-internal-isystem" "foo{{/|\\\\}}include" +// CHECK-x86_64: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}usr{{/|\\\\}}include" +// CHECK-x86_64: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}include" +// CHECK-x86_64: as{{(.exe)?}}" "--64" +// CHECK-x86_64: ld{{(.exe)?}}" +// CHECK-x86_64: "--build-id" +// CHECK-x86_64: "-m" "elf_x86_64_nacl" +// CHECK-x86_64: "-static" +// CHECK-x86_64: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}lib" +// CHECK-x86_64: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}usr{{/|\\\\}}lib" +// CHECK-x86_64: "-Lfoo{{/|\\\\}}lib{{/|\\\\}}x86_64-nacl" +// CHECK-X86_64-NOT: -lpthread +// +// RUN: %clang -no-canonical-prefixes -### -o %t.o %s \ +// RUN: -target armv7a-unknown-nacl-gnueabihf -resource-dir foo 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-ARM %s +// CHECK-ARM: {{.*}}clang{{.*}}" "-cc1" +// CHECK-ARM: "-fuse-init-array" +// CHECK-ARM: "-target-cpu" "cortex-a8" +// CHECK-ARM: "-target-abi" "aapcs-linux" +// CHECK-ARM: "-mfloat-abi" "hard" +// CHECK-ARM: "-resource-dir" "foo" +// CHECK-ARM: "-internal-isystem" "foo{{/|\\\\}}include" +// CHECK-ARM: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}arm-nacl{{/|\\\\}}usr{{/|\\\\}}include" +// CHECK-ARM: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}arm-nacl{{/|\\\\}}include" +// CHECK-ARM: as{{(.exe)?}}" +// CHECK-ARM: "-mfloat-abi=hard" +// CHECK-ARM: ld{{(.exe)?}}" +// CHECK-ARM: "--build-id" +// CHECK-ARM: "-m" "armelf_nacl" +// CHECK-ARM: "-static" +// CHECK-ARM: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}arm-nacl{{/|\\\\}}lib" +// CHECK-ARM: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}arm-nacl{{/|\\\\}}usr{{/|\\\\}}lib" +// CHECK-ARM: "-Lfoo{{/|\\\\}}lib{{/|\\\\}}arm-nacl" +// CHECK-ARM-NOT: -lpthread + +// Check that even when the target arch is just "arm" (as will be the case when +// it is inferred from the binary name) that we get the right ABI flags +// RUN: %clang -no-canonical-prefixes -### -o %t.o %s 2>&1 \ +// RUN: -target arm-nacl \ +// RUN: | FileCheck --check-prefix=CHECK-ARM-NOV7 %s +// CHECK-ARM-NOV7: "-triple" "armv7--nacl-gnueabihf" +// CHECK-ARM-NOV7: "-target-abi" "aapcs-linux" +// CHECK-ARM-NOV7: "-mfloat-abi" "hard" +// CHECK-ARM-NOV7: as{{(.exe)?}}" +// CHECK-ARM-NOV7: "-mfloat-abi=hard" + +// Test clang c++ include dirs and link line when using clang++ + +// RUN: %clangxx -no-canonical-prefixes -### -o %t.o %s \ +// RUN: -target armv7a-unknown-nacl-gnueabihf -resource-dir foo 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-ARM-CXX %s +// CHECK-ARM-CXX: {{.*}}clang{{.*}}" "-cc1" +// CHECK-ARM-CXX: "-resource-dir" "foo" +// CHECK-ARM-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}arm-nacl{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}v1" +// CHECK-ARM-CXX: "-internal-isystem" "foo{{/|\\\\}}include" +// CHECK-ARM-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}arm-nacl{{/|\\\\}}usr{{/|\\\\}}include" +// CHECK-ARM-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}arm-nacl{{/|\\\\}}include" +// CHECK-ARM-CXX: "-lpthread" + +// RUN: %clangxx -no-canonical-prefixes -### -o %t.o %s \ +// RUN: -target i686-unknown-nacl -resource-dir foo 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-I686-CXX %s +// CHECK-I686-CXX: {{.*}}clang{{.*}}" "-cc1" +// CHECK-I686-CXX: "-resource-dir" "foo" +// CHECK-I686-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}v1" +// CHECK-I686-CXX: "-internal-isystem" "foo{{/|\\\\}}include" +// CHECK-I686-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}usr{{/|\\\\}}include" +// CHECK-I686-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}include" +// CHECK-I686-CXX: "-lpthread" + +// RUN: %clangxx -no-canonical-prefixes -### -o %t.o %s \ +// RUN: -target x86_64-unknown-nacl -resource-dir foo 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-x86_64-CXX %s +// CHECK-x86_64-CXX: {{.*}}clang{{.*}}" "-cc1" +// CHECK-x86_64-CXX: "-resource-dir" "foo" +// CHECK-x86_64-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}v1" +// CHECK-x86_64-CXX: "-internal-isystem" "foo{{/|\\\\}}include" +// CHECK-x86_64-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}usr{{/|\\\\}}include" +// CHECK-x86_64-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}include" +// CHECK-x86_64-CXX: "-lpthread" diff --git a/test/Driver/ppc-features.cpp b/test/Driver/ppc-features.cpp index 39d6357dcc..8ef8318469 100644 --- a/test/Driver/ppc-features.cpp +++ b/test/Driver/ppc-features.cpp @@ -77,6 +77,12 @@ // 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-isel -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOISEL %s +// CHECK-NOISEL: "-target-feature" "-isel" + +// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-isel -misel -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-ISEL %s +// CHECK-ISEL: "-target-feature" "+isel" + // 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" diff --git a/test/Driver/preserve-uselistorder.c b/test/Driver/preserve-uselistorder.c new file mode 100644 index 0000000000..aee75a6827 --- /dev/null +++ b/test/Driver/preserve-uselistorder.c @@ -0,0 +1,9 @@ +// RUN: %clang -target x86_64-apple-darwin -emit-llvm -arch x86_64 %s -### 2>&1 \ +// RUN: | FileCheck %s +// CHECK: "-emit-llvm-bc" +// CHECK: "-emit-llvm-uselists" + +// RUN: %clang -target x86_64-apple-darwin -flto -arch x86_64 %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=LTO %s +// LTO: "-emit-llvm-bc" +// LTO-NOT: "-emit-llvm-uselists" diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c index 97205f4ba9..a95a83397e 100644 --- a/test/Driver/sanitizer-ld.c +++ b/test/Driver/sanitizer-ld.c @@ -227,8 +227,7 @@ // RUN: | FileCheck --check-prefix=CHECK-ASAN-UBSAN-LINUX %s // CHECK-ASAN-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-ASAN-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive" -// 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-NOT: libclang_rt.ubsan // CHECK-ASAN-UBSAN-LINUX-NOT: "-lstdc++" // CHECK-ASAN-UBSAN-LINUX: "-lpthread" @@ -238,8 +237,8 @@ // RUN: | FileCheck --check-prefix=CHECK-ASAN-UBSAN-LINUX-CXX %s // CHECK-ASAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}" // CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive" -// 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: "-whole-archive" "{{.*}}libclang_rt.asan_cxx-i386.a" "-no-whole-archive" +// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan // CHECK-ASAN-UBSAN-LINUX-CXX: "-lstdc++" // CHECK-ASAN-UBSAN-LINUX-CXX: "-lpthread" @@ -273,3 +272,12 @@ // CHECK-LSAN-ASAN-LINUX-NOT: libclang_rt.lsan // CHECK-LSAN-ASAN-LINUX: libclang_rt.asan-x86_64 // CHECK-LSAN-ASAN-LINUX-NOT: libclang_rt.lsan + +// RUN: %clangxx -fsanitize=address %s -### -o %t.o 2>&1 \ +// RUN: -mmacosx-version-min=10.6 \ +// RUN: -target x86_64-apple-darwin13.4.0 \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-ASAN-DARWIN106-CXX %s +// CHECK-ASAN-DARWIN106-CXX: "{{.*}}ld{{(.exe)?}}" +// CHECK-ASAN-DARWIN106-CXX: libclang_rt.asan_osx_dynamic.dylib +// CHECK-ASAN-DARWIN106-CXX-NOT: -lc++abi diff --git a/test/Driver/save-temps.c b/test/Driver/save-temps.c index 438d748932..277a901eeb 100644 --- a/test/Driver/save-temps.c +++ b/test/Driver/save-temps.c @@ -1,6 +1,7 @@ // RUN: %clang -target x86_64-apple-darwin -save-temps -arch x86_64 %s -### 2>&1 \ // RUN: | FileCheck %s // CHECK: "-o" "save-temps.i" +// CHECK: "-emit-llvm-uselists" // CHECK: "-disable-llvm-optzns" // CHECK: "-o" "save-temps.bc" // CHECK: "-o" "save-temps.s" @@ -12,6 +13,7 @@ // RUN: %clang -target x86_64-apple-darwin -save-temps=cwd -arch x86_64 %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefix=CWD // CWD: "-o" "save-temps.i" +// CWD: "-emit-llvm-uselists" // CWD: "-disable-llvm-optzns" // CWD: "-o" "save-temps.bc" // CWD: "-o" "save-temps.s" diff --git a/test/Driver/systemz-features.cpp b/test/Driver/systemz-features.cpp new file mode 100644 index 0000000000..25937d1cdc --- /dev/null +++ b/test/Driver/systemz-features.cpp @@ -0,0 +1,15 @@ + +// RUN: %clang -target s390x-unknown-linux-gnu %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-DEFAULT %s +// CHECK-DEFAULT-NOT: "-target-feature" "+transactional-execution" +// CHECK-DEFAULT-NOT: "-target-feature" "-transactional-execution" + +// RUN: %clang -target s390x-unknown-linux-gnu %s -mhtm -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-HTM %s +// RUN: %clang -target s390x-unknown-linux-gnu %s -mno-htm -mhtm -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-HTM %s +// CHECK-HTM: "-target-feature" "+transactional-execution" +// CHECK-HTM-NOT: "-target-feature" "-transactional-execution" + +// RUN: %clang -target s390x-unknown-linux-gnu %s -mno-htm -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOHTM %s +// RUN: %clang -target s390x-unknown-linux-gnu %s -mhtm -mno-htm -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOHTM %s +// CHECK-NOHTM: "-target-feature" "-transactional-execution" +// CHECK-NOHTM-NOT: "-target-feature" "+transactional-execution" + diff --git a/test/FixIt/fixit-eof-space.c b/test/FixIt/fixit-eof-space.c new file mode 100644 index 0000000000..dc9a45d0c5 --- /dev/null +++ b/test/FixIt/fixit-eof-space.c @@ -0,0 +1,9 @@ +// RUN: not %clang_cc1 %s -fsyntax-only -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s +// vim: set binary noeol: + +// This file intentionally ends without a \n on the last line. Make sure your +// editor doesn't add one. The trailing space is also intentional. + +// CHECK: :9:8: warning: duplicate 'extern' declaration specifier +// CHECK: fix-it:"{{.*}}":{9:8-9:15}:"" +extern extern
\ No newline at end of file diff --git a/test/FixIt/fixit-recursive-block.c b/test/FixIt/fixit-recursive-block.c index b276b417ac..3793f825f6 100644 --- a/test/FixIt/fixit-recursive-block.c +++ b/test/FixIt/fixit-recursive-block.c @@ -5,7 +5,7 @@ int main() { void (^arc_fail)() = ^() { // expected-warning {{block pointer variable 'arc_fail' is uninitialized when captured by block}} \ - // expected-note {{maybe you meant to use __block 'arc_fail'}} + // expected-note {{did you mean to use __block 'arc_fail'}} arc_fail(); // BOOM }; } diff --git a/test/FixIt/fixit.cpp b/test/FixIt/fixit.cpp index 585c216f90..6c2fb7faf1 100644 --- a/test/FixIt/fixit.cpp +++ b/test/FixIt/fixit.cpp @@ -344,7 +344,7 @@ namespace PR15045 { int f() { Cl0 c; - return c->a; // expected-error {{member reference type 'PR15045::Cl0' is not a pointer; maybe you meant to use '.'?}} + return c->a; // expected-error {{member reference type 'PR15045::Cl0' is not a pointer; did you mean to use '.'?}} } } diff --git a/test/Headers/altivec-header.c b/test/Headers/altivec-header.c index 7b6c5168b0..0ea9e2b52d 100644 --- a/test/Headers/altivec-header.c +++ b/test/Headers/altivec-header.c @@ -1,16 +1,12 @@ -// REQUIRES: powerpc-registered-target -// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -faltivec -ffreestanding -S -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -faltivec -ffreestanding -fno-lax-vector-conversions -S -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -faltivec -ffreestanding -x c++ -S -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -faltivec -ffreestanding -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -faltivec -ffreestanding -emit-llvm -fno-lax-vector-conversions -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -faltivec -ffreestanding -emit-llvm -x c++ -o - %s | FileCheck %s #include <altivec.h> // Verify that simply including <altivec.h> does not generate any code // (i.e. all inline routines in the header are marked "static") -// CHECK: .text -// CHECK-NEXT: .file +// CHECK: target triple = "powerpc64- // CHECK-NEXT: {{^$}} -// CHECK-NEXT: .ident{{.*$}} -// CHECK-NEXT: .section ".note.GNU-stack","",@progbits -// CHECK-NOT: . +// CHECK-NEXT: llvm.ident diff --git a/test/Index/print-type-size.cpp b/test/Index/print-type-size.cpp index 58f2e14c33..45de93f308 100644 --- a/test/Index/print-type-size.cpp +++ b/test/Index/print-type-size.cpp @@ -65,12 +65,12 @@ struct Test2 { int foo; }; struct { -//CHECK64: FieldDecl=bar:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=32] +//CHECK64: FieldDecl=bar:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=32/0] int bar; }; struct { struct { -//CHECK64: FieldDecl=foobar:[[@LINE+1]]:15 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64] +//CHECK64: FieldDecl=foobar:[[@LINE+1]]:15 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64/0] int foobar; }; }; @@ -160,6 +160,7 @@ struct s4a { struct { struct { struct { +//CHECK64: FieldDecl=s4_e1:[[@LINE+1]]:17 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-1/0] int s4_e1; }; }; diff --git a/test/Index/print-type.cpp b/test/Index/print-type.cpp index af5c556c4d..f73f1b442f 100644 --- a/test/Index/print-type.cpp +++ b/test/Index/print-type.cpp @@ -44,6 +44,7 @@ void foo(int i, int incomplete_array[]) { int variable_array[i]; } struct Blob { int i; + int j; }; int Blob::*member_pointer; @@ -58,7 +59,7 @@ int Blob::*member_pointer; // CHECK: NonTypeTemplateParameter=U:8:32 (Definition) [type=unsigned int] [typekind=UInt] [isPOD=1] // CHECK: TemplateTemplateParameter=W:8:60 (Definition) [type=] [typekind=Invalid] [isPOD=0] // CHECK: Namespace=inner:14:11 (Definition) [type=] [typekind=Invalid] [isPOD=0] -// CHECK: StructDecl=Bar:16:8 (Definition) [type=outer::inner::Bar] [typekind=Record] [isPOD=0] +// CHECK: StructDecl=Bar:16:8 (Definition) [type=outer::inner::Bar] [typekind=Record] [isPOD=0] [nbFields=3] // CHECK: CXXConstructor=Bar:17:3 (Definition) [type=void (outer::Foo<bool> *){{.*}}] [typekind=FunctionProto] [canonicaltype=void (outer::Foo<bool> *){{.*}}] [canonicaltypekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [outer::Foo<bool> *] [Pointer]] [isPOD=0] // CHECK: ParmDecl=foo:17:25 (Definition) [type=outer::Foo<bool> *] [typekind=Pointer] [canonicaltype=outer::Foo<bool> *] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=outer::Foo<bool>] [pointeekind=Unexposed] // CHECK: NamespaceRef=outer:1:11 [type=] [typekind=Invalid] [isPOD=0] @@ -115,6 +116,6 @@ int Blob::*member_pointer; // CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0] // CHECK: VarDecl=variable_array:43:47 (Definition) [type=int [i]] [typekind=VariableArray] [isPOD=1] // CHECK: DeclRefExpr=i:43:14 [type=int] [typekind=Int] [isPOD=1] -// CHECK: StructDecl=Blob:45:8 (Definition) [type=Blob] [typekind=Record] [isPOD=1] +// CHECK: StructDecl=Blob:45:8 (Definition) [type=Blob] [typekind=Record] [isPOD=1] [nbFields=2] // CHECK: FieldDecl=i:46:7 (Definition) [type=int] [typekind=Int] [isPOD=1] -// CHECK: VarDecl=member_pointer:48:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [isPOD=1] +// CHECK: VarDecl=member_pointer:49:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [isPOD=1] diff --git a/test/Lexer/eof-number.c b/test/Lexer/eof-number.c new file mode 100644 index 0000000000..d97a6fec4b --- /dev/null +++ b/test/Lexer/eof-number.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -Wnewline-eof +// vim: set binary noeol: + +// This file intentionally ends without a \n on the last line. Make sure your +// editor doesn't add one. + +// expected-error@+2{{unterminated conditional directive}} +// expected-warning@+1{{no newline at end of file}} +#if 0
\ No newline at end of file diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c index 657b44dc18..86274ad0bd 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 (94): +CHECK: Warnings without flags (93): CHECK-NEXT: ext_excess_initializers CHECK-NEXT: ext_excess_initializers_in_char_array_initializer CHECK-NEXT: ext_expected_semi_decl_list @@ -68,7 +68,6 @@ CHECK-NEXT: warn_drv_pch_not_first_include CHECK-NEXT: warn_dup_category_def CHECK-NEXT: warn_duplicate_protocol_def CHECK-NEXT: warn_enum_value_overflow -CHECK-NEXT: warn_exception_caught_by_earlier_handler CHECK-NEXT: warn_expected_qualified_after_typename CHECK-NEXT: warn_extraneous_char_constant CHECK-NEXT: warn_fe_cc_log_diagnostics_failure diff --git a/test/Modules/Inputs/redecl-add-after-load-decls.h b/test/Modules/Inputs/redecl-add-after-load-decls.h index fbe6b9387a..a4227971a8 100644 --- a/test/Modules/Inputs/redecl-add-after-load-decls.h +++ b/test/Modules/Inputs/redecl-add-after-load-decls.h @@ -16,9 +16,9 @@ typedef C::A CB; constexpr int C_test(bool b) { return b ? C::variable : C::function(); } struct D { - struct A; // expected-note {{forward}} + struct A; static const int variable; - static constexpr int function(); // expected-note {{here}} + static constexpr int function(); }; typedef D::A DB; -constexpr int D_test(bool b) { return b ? D::variable : D::function(); } // expected-note {{subexpression}} expected-note {{undefined}} +constexpr int D_test(bool b) { return b ? D::variable : D::function(); } diff --git a/test/Modules/Inputs/submodules-merge-defs/defs.h b/test/Modules/Inputs/submodules-merge-defs/defs.h index 16f71840d0..89e4b2319c 100644 --- a/test/Modules/Inputs/submodules-merge-defs/defs.h +++ b/test/Modules/Inputs/submodules-merge-defs/defs.h @@ -1,13 +1,15 @@ struct A { int a_member; }; -namespace { inline int use_a(A a) { return a.a_member; } } +inline int use_a(A a) { return a.a_member; } class B { struct Inner1 {}; public: struct Inner2; + template<typename T> void f(); }; // Check that lookup and access checks are performed in the right context. struct B::Inner2 : Inner1 {}; +template<typename T> void B::f() {} // Check that base-specifiers are correctly disambiguated. template<int N> struct C_Base { struct D { constexpr operator int() const { return 0; } }; }; @@ -17,4 +19,13 @@ struct C2 : C_Base<C_Const<0>::D{} extern c2; typedef struct { int a; void f(); struct X; } D; struct D::X { int dx; } extern dx; -namespace { inline int use_dx(D::X dx) { return dx.dx; } } +inline int use_dx(D::X dx) { return dx.dx; } + +template<typename T> int E(T t) { return t; } + +template<typename T> struct F { + int f(); + template<typename U> int g(); +}; +template<typename T> int F<T>::f() { return 0; } +template<typename T> template<typename U> int F<T>::g() { return 0; } diff --git a/test/Modules/Inputs/submodules-merge-defs/merged-defs.h b/test/Modules/Inputs/submodules-merge-defs/merged-defs.h new file mode 100644 index 0000000000..31c69c6a44 --- /dev/null +++ b/test/Modules/Inputs/submodules-merge-defs/merged-defs.h @@ -0,0 +1 @@ +#include "defs.h" diff --git a/test/Modules/Inputs/submodules-merge-defs/module.modulemap b/test/Modules/Inputs/submodules-merge-defs/module.modulemap index 5c7ee8a89a..82abdb088f 100644 --- a/test/Modules/Inputs/submodules-merge-defs/module.modulemap +++ b/test/Modules/Inputs/submodules-merge-defs/module.modulemap @@ -9,3 +9,8 @@ module "redef" { // Do not re-export stuff.use use "stuff" } + +module "merged-defs" { + header "merged-defs.h" + use "stuff" +} diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp index 41b0f2cd92..00fc38b522 100644 --- a/test/Modules/cxx-templates.cpp +++ b/test/Modules/cxx-templates.cpp @@ -125,10 +125,7 @@ void g() { static_assert(Outer<int>::Inner<int>::f() == 1, ""); static_assert(Outer<int>::Inner<int>::g() == 2, ""); -// FIXME: We're too lazy in merging class definitions to find the definition -// of this function. -static_assert(MergeTemplateDefinitions<int>::f() == 1, ""); // expected-error {{constant expression}} expected-note {{undefined}} -// expected-note@cxx-templates-c.h:10 {{here}} +static_assert(MergeTemplateDefinitions<int>::f() == 1, ""); static_assert(MergeTemplateDefinitions<int>::g() == 2, ""); RedeclaredAsFriend<int> raf1; diff --git a/test/Modules/redecl-add-after-load.cpp b/test/Modules/redecl-add-after-load.cpp index 53e54c84cc..8ca70ad958 100644 --- a/test/Modules/redecl-add-after-load.cpp +++ b/test/Modules/redecl-add-after-load.cpp @@ -2,8 +2,9 @@ // RUN: %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 // RUN: %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 -DIMPORT_DECLS -#ifdef IMPORT_DECLS // expected-no-diagnostics + +#ifdef IMPORT_DECLS @import redecl_add_after_load_decls; #else typedef struct A B; @@ -24,12 +25,12 @@ typedef C::A CB; constexpr int C_test(bool b) { return b ? C::variable : C::function(); } struct D { - struct A; // expected-note {{forward}} + struct A; static const int variable; - static constexpr int function(); // expected-note {{here}} + static constexpr int function(); }; typedef D::A DB; -constexpr int D_test(bool b) { return b ? D::variable : D::function(); } // expected-note {{undefined}} +constexpr int D_test(bool b) { return b ? D::variable : D::function(); } #endif @import redecl_add_after_load; @@ -46,14 +47,6 @@ CB struct_struct_test; constexpr int struct_variable_test = C_test(true); constexpr int struct_function_test = C_test(false); -// FIXME: We should accept this, but we're currently too lazy when merging class -// definitions to determine that the definitions in redecl_add_after_load are -// definitions of these entities. DB merged_struct_struct_test; constexpr int merged_struct_variable_test = D_test(true); constexpr int merged_struct_function_test = D_test(false); -#ifndef IMPORT_DECLS -// expected-error@-4 {{incomplete}} -// @-4: definition of D::variable must be emitted, so it gets imported eagerly -// expected-error@-4 {{constant}} expected-note@-4 {{in call to}} -#endif diff --git a/test/Modules/submodules-merge-defs.cpp b/test/Modules/submodules-merge-defs.cpp index cdda48ea65..79213cae8f 100644 --- a/test/Modules/submodules-merge-defs.cpp +++ b/test/Modules/submodules-merge-defs.cpp @@ -1,33 +1,54 @@ // RUN: rm -rf %t +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules-cache-path=%t -fmodules -I %S/Inputs/submodules-merge-defs %s -verify -fno-modules-error-recovery -DTEXTUAL // RUN: %clang_cc1 -x c++ -std=c++11 -fmodules-cache-path=%t -fmodules -I %S/Inputs/submodules-merge-defs %s -verify -fno-modules-error-recovery // Trigger import of definitions, but don't make them visible. #include "empty.h" A pre_a; // expected-error {{must be imported}} expected-error {{must use 'struct'}} -// expected-note@defs.h:1 {{here}} +// expected-note@defs.h:1 +{{here}} +// FIXME: We should warn that use_a is being used without being imported. +int pre_use_a = use_a(pre_a); // expected-error {{'A' must be imported}} B::Inner2 pre_bi; // expected-error +{{must be imported}} // expected-note@defs.h:4 +{{here}} -// expected-note@defs.h:10 +{{here}} +// expected-note@defs.h:11 +{{here}} C_Base<1> pre_cb1; // expected-error +{{must be imported}} -// expected-note@defs.h:13 +{{here}} -C1 pre_c1; // expected-error +{{must be imported}} expected-error {{must use 'struct'}} // expected-note@defs.h:15 +{{here}} +C1 pre_c1; // expected-error +{{must be imported}} expected-error {{must use 'struct'}} +// expected-note@defs.h:17 +{{here}} C2 pre_c2; // expected-error +{{must be imported}} expected-error {{must use 'struct'}} -// expected-note@defs.h:16 +{{here}} +// expected-note@defs.h:18 +{{here}} D::X pre_dx; // expected-error +{{must be imported}} -// expected-note@defs.h:18 +{{here}} -// expected-note@defs.h:19 +{{here}} +// expected-note@defs.h:20 +{{here}} +// expected-note@defs.h:21 +{{here}} +// FIXME: We should warn that use_dx is being used without being imported. +int pre_use_dx = use_dx(pre_dx); + +int pre_e = E(0); // expected-error {{must be imported}} +// expected-note@defs.h:24 +{{here}} + +int pre_ff = F<int>().f(); // expected-error +{{must be imported}} +int pre_fg = F<int>().g<int>(); // expected-error +{{must be imported}} +// expected-note@defs.h:26 +{{here}} // Make definitions from second module visible. +#ifdef TEXTUAL #include "import-and-redefine.h" +#else +#include "merged-defs.h" +#endif A post_a; +int post_use_a = use_a(post_a); B::Inner2 post_bi; C_Base<1> post_cb1; C1 c1; C2 c2; D::X post_dx; +int post_use_dx = use_dx(post_dx); +int post_e = E(0); +int post_ff = F<char>().f(); +int post_fg = F<char>().g<int>(); diff --git a/test/OpenMP/atomic_codegen.cpp b/test/OpenMP/atomic_codegen.cpp index e78720db66..9d1d516cef 100644 --- a/test/OpenMP/atomic_codegen.cpp +++ b/test/OpenMP/atomic_codegen.cpp @@ -29,6 +29,22 @@ void parallel_atomic_ewc() { // CHECK: invoke void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]]) #pragma omp atomic write St().get() = b; + // CHECK: invoke void @_ZN2StC1Ev(%struct.St* [[TEMP_ST_ADDR:%.+]]) + // CHECK: [[SCALAR_ADDR:%.+]] = invoke dereferenceable(4) i32* @_ZN2St3getEv(%struct.St* [[TEMP_ST_ADDR]]) + // CHECK: [[B_VAL:%.+]] = load i32, i32* @b + // CHECK: [[OLD_VAL:%.+]] = load atomic i32, i32* [[SCALAR_ADDR]] monotonic, + // CHECK: br label %[[OMP_UPDATE:.+]] + // CHECK: [[OMP_UPDATE]] + // CHECK: [[OLD_PHI_VAL:%.+]] = phi i32 [ [[OLD_VAL]], %{{.+}} ], [ [[NEW_OLD_VAL:%.+]], %[[OMP_UPDATE]] ] + // CHECK: [[NEW_VAL:%.+]] = srem i32 [[OLD_PHI_VAL]], [[B_VAL]] + // CHECK: [[RES:%.+]] = cmpxchg i32* [[SCALAR_ADDR]], i32 [[OLD_PHI_VAL]], i32 [[NEW_VAL]] monotonic monotonic + // CHECK: [[NEW_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0 + // CHECK: [[COND:%.+]] = extractvalue { i32, i1 } [[RES]], 1 + // CHECK: br i1 [[COND]], label %[[OMP_DONE:.+]], label %[[OMP_UPDATE]] + // CHECK: [[OMP_DONE]] + // CHECK: invoke void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]]) +#pragma omp atomic + St().get() %= b; } } @@ -50,11 +66,19 @@ void parallel_atomic() { // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: store atomic i32 {{%.+}}, i32* @{{.+}} monotonic, {{.*}}!dbg [[WRITE_LOC:![0-9]+]] - // TERM_DEBUG: [[TERM_LPAD]] - // TERM_DEBUG: call void @__clang_call_terminate - // TERM_DEBUG: unreachable a = foo(); +#pragma omp atomic update + // TERM_DEBUG-NOT: __kmpc_global_thread_num + // TERM_DEBUG: invoke {{.*}}foo{{.*}}() + // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], + // TERM_DEBUG-NOT: __kmpc_global_thread_num + // TERM_DEBUG: atomicrmw add i32* @{{.+}}, i32 %{{.+}} monotonic, {{.*}}!dbg [[UPDATE_LOC:![0-9]+]] + a += foo(); } + // TERM_DEBUG: [[TERM_LPAD]] + // TERM_DEBUG: call void @__clang_call_terminate + // TERM_DEBUG: unreachable } -// TERM_DEBUG-DAG: [[READ_LOC]] = !MDLocation(line: 41, -// TERM_DEBUG-DAG: [[WRITE_LOC]] = !MDLocation(line: 47, +// TERM_DEBUG-DAG: [[READ_LOC]] = !MDLocation(line: [[@LINE-25]], +// TERM_DEBUG-DAG: [[WRITE_LOC]] = !MDLocation(line: [[@LINE-20]], +// TERM_DEBUG-DAG: [[UPDATE_LOC]] = !MDLocation(line: [[@LINE-14]], diff --git a/test/OpenMP/atomic_messages.c b/test/OpenMP/atomic_messages.c index 8d4ade6fe0..294ce7e6b2 100644 --- a/test/OpenMP/atomic_messages.c +++ b/test/OpenMP/atomic_messages.c @@ -193,3 +193,175 @@ int updateint() { return 0; } +int captureint() { + int a = 0, b = 0, c = 0; +// Test for atomic capture +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected compound statement}} + ; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + foo(); +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected built-in binary or unary operator}} + a = b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = b || a; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}} + b = a = a && b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = (float)a + b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = 2 * b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = b + *&a; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected exactly two expression statements}} + { a = b; } +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected exactly two expression statements}} + {} +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected in right hand side of the first expression}} + {a = b;a = b;} +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected in right hand side of the first expression}} + {a = b; a = b || a;} +#pragma omp atomic capture + {b = a; a = a && b;} +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected in right hand side of expression}} + b = a = (float)a + b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected in right hand side of expression}} + b = a = 2 * b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected in right hand side of expression}} + b = a = b + *&a; +#pragma omp atomic capture + c = *&a = *&a + 2; +#pragma omp atomic capture + c = a++; +#pragma omp atomic capture + c = ++a; +#pragma omp atomic capture + c = a--; +#pragma omp atomic capture + c = --a; +#pragma omp atomic capture + c = a += b; +#pragma omp atomic capture + c = a %= b; +#pragma omp atomic capture + c = a *= b; +#pragma omp atomic capture + c = a -= b; +#pragma omp atomic capture + c = a /= b; +#pragma omp atomic capture + c = a &= b; +#pragma omp atomic capture + c = a ^= b; +#pragma omp atomic capture + c = a |= b; +#pragma omp atomic capture + c = a <<= b; +#pragma omp atomic capture + c = a >>= b; +#pragma omp atomic capture + c = a = b + a; +#pragma omp atomic capture + c = a = a * b; +#pragma omp atomic capture + c = a = b - a; +#pragma omp atomic capture + c = a = a / b; +#pragma omp atomic capture + c = a = b & a; +#pragma omp atomic capture + c = a = a ^ b; +#pragma omp atomic capture + c = a = b | a; +#pragma omp atomic capture + c = a = a << b; +#pragma omp atomic capture + c = a = b >> a; +#pragma omp atomic capture + { c = *&a; *&a = *&a + 2;} +#pragma omp atomic capture + { *&a = *&a + 2; c = *&a;} +#pragma omp atomic capture + {c = a; a++;} +#pragma omp atomic capture + {++a;c = a;} +#pragma omp atomic capture + {c = a;a--;} +#pragma omp atomic capture + {--a;c = a;} +#pragma omp atomic capture + {c = a; a += b;} +#pragma omp atomic capture + {a %= b; c = a;} +#pragma omp atomic capture + {c = a; a *= b;} +#pragma omp atomic capture + {a -= b;c = a;} +#pragma omp atomic capture + {c = a; a /= b;} +#pragma omp atomic capture + {a &= b; c = a;} +#pragma omp atomic capture + {c = a; a ^= b;} +#pragma omp atomic capture + {a |= b; c = a;} +#pragma omp atomic capture + {c = a; a <<= b;} +#pragma omp atomic capture + {a >>= b; c = a;} +#pragma omp atomic capture + {c = a; a = b + a;} +#pragma omp atomic capture + {a = a * b; c = a;} +#pragma omp atomic capture + {c = a; a = b - a;} +#pragma omp atomic capture + {a = a / b; c = a;} +#pragma omp atomic capture + {c = a; a = b & a;} +#pragma omp atomic capture + {a = a ^ b; c = a;} +#pragma omp atomic capture + {c = a; a = b | a;} +#pragma omp atomic capture + {a = a << b; c = a;} +#pragma omp atomic capture + {c = a; a = b >> a;} +#pragma omp atomic capture + {c = a; a = foo();} + // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} +#pragma omp atomic capture capture + b = a /= b; + + return 0; +} + diff --git a/test/OpenMP/atomic_messages.cpp b/test/OpenMP/atomic_messages.cpp index b47fbbc5c4..7466509b27 100644 --- a/test/OpenMP/atomic_messages.cpp +++ b/test/OpenMP/atomic_messages.cpp @@ -152,7 +152,7 @@ int write() { template <class T> T update() { - T a, b = 0; + T a = 0, b = 0, c = 0; // Test for atomic update #pragma omp atomic update // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} @@ -332,34 +332,347 @@ int update() { template <class T> T capture() { - T a, b = 0; + T a = 0, b = 0, c = 0; // Test for atomic capture #pragma omp atomic capture - // expected-error@+1 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} - ++a; -#pragma omp atomic capture - // expected-error@+1 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected compound statement}} ; -// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + foo(); +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected built-in binary or unary operator}} + a = b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = b || a; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}} + b = a = a && b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = (float)a + b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = 2 * b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = b + *&a; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected exactly two expression statements}} + { a = b; } +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected exactly two expression statements}} + {} +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected in right hand side of the first expression}} + {a = b;a = b;} +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected in right hand side of the first expression}} + {a = b; a = b || a;} +#pragma omp atomic capture + {b = a; a = a && b;} +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected in right hand side of expression}} + b = a = (float)a + b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected in right hand side of expression}} + b = a = 2 * b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected in right hand side of expression}} + b = a = b + *&a; +#pragma omp atomic capture + c = *&a = *&a + 2; +#pragma omp atomic capture + c = a++; +#pragma omp atomic capture + c = ++a; +#pragma omp atomic capture + c = a--; +#pragma omp atomic capture + c = --a; +#pragma omp atomic capture + c = a += b; +#pragma omp atomic capture + c = a %= b; +#pragma omp atomic capture + c = a *= b; +#pragma omp atomic capture + c = a -= b; +#pragma omp atomic capture + c = a /= b; +#pragma omp atomic capture + c = a &= b; +#pragma omp atomic capture + c = a ^= b; +#pragma omp atomic capture + c = a |= b; +#pragma omp atomic capture + c = a <<= b; +#pragma omp atomic capture + c = a >>= b; +#pragma omp atomic capture + c = a = b + a; +#pragma omp atomic capture + c = a = a * b; +#pragma omp atomic capture + c = a = b - a; +#pragma omp atomic capture + c = a = a / b; +#pragma omp atomic capture + c = a = b & a; +#pragma omp atomic capture + c = a = a ^ b; +#pragma omp atomic capture + c = a = b | a; +#pragma omp atomic capture + c = a = a << b; +#pragma omp atomic capture + c = a = b >> a; +#pragma omp atomic capture + { c = *&a; *&a = *&a + 2;} +#pragma omp atomic capture + { *&a = *&a + 2; c = *&a;} +#pragma omp atomic capture + {c = a; a++;} +#pragma omp atomic capture + {++a;c = a;} +#pragma omp atomic capture + {c = a;a--;} +#pragma omp atomic capture + {--a;c = a;} +#pragma omp atomic capture + {c = a; a += b;} +#pragma omp atomic capture + {a %= b; c = a;} +#pragma omp atomic capture + {c = a; a *= b;} +#pragma omp atomic capture + {a -= b;c = a;} +#pragma omp atomic capture + {c = a; a /= b;} +#pragma omp atomic capture + {a &= b; c = a;} +#pragma omp atomic capture + {c = a; a ^= b;} +#pragma omp atomic capture + {a |= b; c = a;} +#pragma omp atomic capture + {c = a; a <<= b;} +#pragma omp atomic capture + {a >>= b; c = a;} +#pragma omp atomic capture + {c = a; a = b + a;} +#pragma omp atomic capture + {a = a * b; c = a;} +#pragma omp atomic capture + {c = a; a = b - a;} +#pragma omp atomic capture + {a = a / b; c = a;} +#pragma omp atomic capture + {c = a; a = b & a;} +#pragma omp atomic capture + {a = a ^ b; c = a;} +#pragma omp atomic capture + {c = a; a = b | a;} +#pragma omp atomic capture + {a = a << b; c = a;} +#pragma omp atomic capture + {c = a; a = b >> a;} +#pragma omp atomic capture + {c = a; a = foo();} + // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} #pragma omp atomic capture capture - a = ++b; + b = a /= b; return T(); } int capture() { - int a, b = 0; + int a = 0, b = 0, c = 0; // Test for atomic capture #pragma omp atomic capture - // expected-error@+1 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} - ++a; -#pragma omp atomic capture - // expected-error@+1 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected compound statement}} ; -// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + foo(); +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected built-in binary or unary operator}} + a = b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = b || a; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}} + b = a = a && b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = (float)a + b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = 2 * b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected assignment expression}} + a = b + *&a; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected exactly two expression statements}} + { a = b; } +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected exactly two expression statements}} + {} +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected in right hand side of the first expression}} + {a = b;a = b;} +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected in right hand side of the first expression}} + {a = b; a = b || a;} +#pragma omp atomic capture + {b = a; a = a && b;} +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected in right hand side of expression}} + b = a = (float)a + b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected in right hand side of expression}} + b = a = 2 * b; +#pragma omp atomic capture + // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + // expected-note@+1 {{expected in right hand side of expression}} + b = a = b + *&a; +#pragma omp atomic capture + c = *&a = *&a + 2; +#pragma omp atomic capture + c = a++; +#pragma omp atomic capture + c = ++a; +#pragma omp atomic capture + c = a--; +#pragma omp atomic capture + c = --a; +#pragma omp atomic capture + c = a += b; +#pragma omp atomic capture + c = a %= b; +#pragma omp atomic capture + c = a *= b; +#pragma omp atomic capture + c = a -= b; +#pragma omp atomic capture + c = a /= b; +#pragma omp atomic capture + c = a &= b; +#pragma omp atomic capture + c = a ^= b; +#pragma omp atomic capture + c = a |= b; +#pragma omp atomic capture + c = a <<= b; +#pragma omp atomic capture + c = a >>= b; +#pragma omp atomic capture + c = a = b + a; +#pragma omp atomic capture + c = a = a * b; +#pragma omp atomic capture + c = a = b - a; +#pragma omp atomic capture + c = a = a / b; +#pragma omp atomic capture + c = a = b & a; +#pragma omp atomic capture + c = a = a ^ b; +#pragma omp atomic capture + c = a = b | a; +#pragma omp atomic capture + c = a = a << b; +#pragma omp atomic capture + c = a = b >> a; +#pragma omp atomic capture + { c = *&a; *&a = *&a + 2;} +#pragma omp atomic capture + { *&a = *&a + 2; c = *&a;} +#pragma omp atomic capture + {c = a; a++;} +#pragma omp atomic capture + {++a;c = a;} +#pragma omp atomic capture + {c = a;a--;} +#pragma omp atomic capture + {--a;c = a;} +#pragma omp atomic capture + {c = a; a += b;} +#pragma omp atomic capture + {a %= b; c = a;} +#pragma omp atomic capture + {c = a; a *= b;} +#pragma omp atomic capture + {a -= b;c = a;} +#pragma omp atomic capture + {c = a; a /= b;} +#pragma omp atomic capture + {a &= b; c = a;} +#pragma omp atomic capture + {c = a; a ^= b;} +#pragma omp atomic capture + {a |= b; c = a;} +#pragma omp atomic capture + {c = a; a <<= b;} +#pragma omp atomic capture + {a >>= b; c = a;} +#pragma omp atomic capture + {c = a; a = b + a;} +#pragma omp atomic capture + {a = a * b; c = a;} +#pragma omp atomic capture + {c = a; a = b - a;} +#pragma omp atomic capture + {a = a / b; c = a;} +#pragma omp atomic capture + {c = a; a = b & a;} +#pragma omp atomic capture + {a = a ^ b; c = a;} +#pragma omp atomic capture + {c = a; a = b | a;} +#pragma omp atomic capture + {a = a << b; c = a;} +#pragma omp atomic capture + {c = a; a = b >> a;} +#pragma omp atomic capture + {c = a; a = foo();} + // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} #pragma omp atomic capture capture - a = ++b; + b = a /= b; + // expected-note@+1 {{in instantiation of function template specialization 'capture<int>' requested here}} return capture<int>(); } diff --git a/test/OpenMP/atomic_update_codegen.cpp b/test/OpenMP/atomic_update_codegen.cpp new file mode 100644 index 0000000000..ada2e41114 --- /dev/null +++ b/test/OpenMP/atomic_update_codegen.cpp @@ -0,0 +1,1070 @@ +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp=libiomp5 -x c -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +_Bool bv, bx; +char cv, cx; +unsigned char ucv, ucx; +short sv, sx; +unsigned short usv, usx; +int iv, ix; +unsigned int uiv, uix; +long lv, lx; +unsigned long ulv, ulx; +long long llv, llx; +unsigned long long ullv, ullx; +float fv, fx; +double dv, dx; +long double ldv, ldx; +_Complex int civ, cix; +_Complex float cfv, cfx; +_Complex double cdv, cdx; + +typedef int int4 __attribute__((__vector_size__(16))); +int4 int4x; + +struct BitFields { + int : 32; + int a : 31; +} bfx; + +struct BitFields_packed { + int : 32; + int a : 31; +} __attribute__ ((__packed__)) bfx_packed; + +struct BitFields2 { + int : 31; + int a : 1; +} bfx2; + +struct BitFields2_packed { + int : 31; + int a : 1; +} __attribute__ ((__packed__)) bfx2_packed; + +struct BitFields3 { + int : 11; + int a : 14; +} bfx3; + +struct BitFields3_packed { + int : 11; + int a : 14; +} __attribute__ ((__packed__)) bfx3_packed; + +struct BitFields4 { + short : 16; + int a: 1; + long b : 7; +} bfx4; + +struct BitFields4_packed { + short : 16; + int a: 1; + long b : 7; +} __attribute__ ((__packed__)) bfx4_packed; + +typedef float float2 __attribute__((ext_vector_type(2))); +float2 float2x; + +register int rix __asm__("0"); + +int main() { +// CHECK: atomicrmw add i8* @{{.+}}, i8 1 monotonic +#pragma omp atomic + bx++; +// CHECK: atomicrmw add i8* @{{.+}}, i8 1 monotonic +#pragma omp atomic update + ++cx; +// CHECK: atomicrmw sub i8* @{{.+}}, i8 1 monotonic +#pragma omp atomic + ucx--; +// CHECK: atomicrmw sub i16* @{{.+}}, i16 1 monotonic +#pragma omp atomic update + --sx; +// CHECK: [[USV:%.+]] = load i16, i16* @{{.+}}, +// CHECK: [[EXPR:%.+]] = zext i16 [[USV]] to i32 +// CHECK: [[X:%.+]] = load atomic i16, i16* [[X_ADDR:@.+]] monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[EXPECTED:%.+]] = phi i16 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[CONV:%.+]] = zext i16 [[EXPECTED]] to i32 +// CHECK: [[ADD:%.+]] = add nsw i32 [[CONV]], [[EXPR]] +// CHECK: [[DESIRED:%.+]] = trunc i32 [[ADD]] to i16 +// CHECK: [[RES:%.+]] = cmpxchg i16* [[X_ADDR]], i16 [[EXPECTED]], i16 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_X]] = extractvalue { i16, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i16, i1 } [[RES]], 1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + usx += usv; +// CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}}, +// CHECK: [[X:%.+]] = load atomic i32, i32* [[X_ADDR:@.+]] monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[EXPECTED:%.+]] = phi i32 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[DESIRED:%.+]] = mul nsw i32 [[EXPECTED]], [[EXPR]] +// CHECK: [[RES:%.+]] = cmpxchg i32* [[X_ADDR]], i32 [[EXPECTED]], i32 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_X]] = extractvalue { i32, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + ix *= iv; +// CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}}, +// CHECK: atomicrmw sub i32* @{{.+}}, i32 [[EXPR]] monotonic +#pragma omp atomic + uix -= uiv; +// CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}}, +// CHECK: [[X:%.+]] = load atomic i32, i32* [[X_ADDR:@.+]] monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[EXPECTED:%.+]] = phi i32 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[DESIRED:%.+]] = shl i32 [[EXPECTED]], [[EXPR]] +// CHECK: [[RES:%.+]] = cmpxchg i32* [[X_ADDR]], i32 [[EXPECTED]], i32 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_X]] = extractvalue { i32, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + ix <<= iv; +// CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}}, +// CHECK: [[X:%.+]] = load atomic i32, i32* [[X_ADDR:@.+]] monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[EXPECTED:%.+]] = phi i32 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[DESIRED:%.+]] = lshr i32 [[EXPECTED]], [[EXPR]] +// CHECK: [[RES:%.+]] = cmpxchg i32* [[X_ADDR]], i32 [[EXPECTED]], i32 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_X]] = extractvalue { i32, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + uix >>= uiv; +// CHECK: [[EXPR:%.+]] = load i64, i64* @{{.+}}, +// CHECK: [[X:%.+]] = load atomic i64, i64* [[X_ADDR:@.+]] monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[DESIRED:%.+]] = sdiv i64 [[EXPECTED]], [[EXPR]] +// CHECK: [[RES:%.+]] = cmpxchg i64* [[X_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_X]] = extractvalue { i64, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + lx /= lv; +// CHECK: [[EXPR:%.+]] = load i64, i64* @{{.+}}, +// CHECK: atomicrmw and i64* @{{.+}}, i64 [[EXPR]] monotonic +#pragma omp atomic + ulx &= ulv; +// CHECK: [[EXPR:%.+]] = load i64, i64* @{{.+}}, +// CHECK: atomicrmw xor i64* @{{.+}}, i64 [[EXPR]] monotonic +#pragma omp atomic update + llx ^= llv; +// CHECK: [[EXPR:%.+]] = load i64, i64* @{{.+}}, +// CHECK: atomicrmw or i64* @{{.+}}, i64 [[EXPR]] monotonic +#pragma omp atomic + ullx |= ullv; +// CHECK: [[EXPR:%.+]] = load float, float* @{{.+}}, +// CHECK: [[OLD:%.+]] = load atomic i32, i32* bitcast (float* [[X_ADDR:@.+]] to i32*) monotonic +// CHECK: [[X:%.+]] = bitcast i32 [[OLD]] to float +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi float [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[ADD:%.+]] = fadd float [[OLD]], [[EXPR]] +// CHECK: [[EXPECTED:%.+]] = bitcast float [[OLD]] to i32 +// CHECK: [[DESIRED:%.+]] = bitcast float [[ADD]] to i32 +// CHECK: [[RES:%.+]] = cmpxchg i32* bitcast (float* [[X_ADDR]] to i32*), i32 [[EXPECTED]], i32 [[DESIRED]] monotonic monotonic +// CHECK: [[PREV:%.+]] = extractvalue { i32, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1 +// CHECK: [[OLD_X]] = bitcast i32 [[PREV]] to float +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + fx = fx + fv; +// CHECK: [[EXPR:%.+]] = load double, double* @{{.+}}, +// CHECK: [[OLD:%.+]] = load atomic i64, i64* bitcast (double* [[X_ADDR:@.+]] to i64*) monotonic +// CHECK: [[X:%.+]] = bitcast i64 [[OLD]] to double +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi double [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[SUB:%.+]] = fsub double [[EXPR]], [[OLD]] +// CHECK: [[EXPECTED:%.+]] = bitcast double [[OLD]] to i64 +// CHECK: [[DESIRED:%.+]] = bitcast double [[SUB]] to i64 +// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (double* [[X_ADDR]] to i64*), i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic +// CHECK: [[PREV:%.+]] = extractvalue { i64, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1 +// CHECK: [[OLD_X]] = bitcast i64 [[PREV]] to double +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + dx = dv - dx; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}, +// CHECK: [[OLD:%.+]] = load atomic i128, i128* bitcast (x86_fp80* [[X_ADDR:@.+]] to i128*) monotonic +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP:%.+]] to i128* +// CHECK: store i128 [[OLD]], i128* [[BITCAST]] +// CHECK: [[X:%.+]] = load x86_fp80, x86_fp80* [[TEMP]] +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi x86_fp80 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[MUL:%.+]] = fmul x86_fp80 [[OLD]], [[EXPR]] +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP:%.+]] to i8* +// CHECK: call void @llvm.memset.p0i8.i64(i8* [[BITCAST]], i8 0, i64 16, i32 16, i1 false) +// CHECK: store x86_fp80 [[OLD]], x86_fp80* [[TEMP]] +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP]] to i128* +// CHECK: [[EXPECTED:%.+]] = load i128, i128* [[BITCAST]] +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP:%.+]] to i8* +// CHECK: call void @llvm.memset.p0i8.i64(i8* [[BITCAST]], i8 0, i64 16, i32 16, i1 false) +// CHECK: store x86_fp80 [[MUL]], x86_fp80* [[TEMP]] +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP]] to i128* +// CHECK: [[DESIRED:%.+]] = load i128, i128* [[BITCAST]] +// CHECK: [[RES:%.+]] = cmpxchg i128* bitcast (x86_fp80* [[X_ADDR]] to i128*), i128 [[EXPECTED]], i128 [[DESIRED]] monotonic monotonic +// CHECK: [[PREV:%.+]] = extractvalue { i128, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i128, i1 } [[RES]], 1 +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP:%.+]] to i128* +// CHECK: store i128 [[PREV]], i128* [[BITCAST]] +// CHECK: [[OLD_X]] = load x86_fp80, x86_fp80* [[TEMP]], +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + ldx = ldx * ldv; +// CHECK: [[EXPR_RE:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 0) +// CHECK: [[EXPR_IM:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 1) +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP:%.+]] to i8* +// CHECK: call void @__atomic_load(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR:@.+]] to i8*), i8* [[BITCAST]], i32 0) +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 0 +// CHECK: [[LD_RE:%.+]] = load i32, i32* [[LD_RE_ADDR]] +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: [[LD_IM:%.+]] = load i32, i32* [[LD_IM_ADDR]] +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: store i32 [[LD_RE]], i32* [[LD_RE_ADDR]] +// CHECK: store i32 [[LD_IM]], i32* [[LD_IM_ADDR]] +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP]] to i64* +// CHECK: [[X:%.+]] = load i64, i64* [[BITCAST]] +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP:%.+]] to i64* +// CHECK: store i64 [[OLD]], i64* [[BITCAST]] +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 0 +// CHECK: [[X_RE:%.+]] = load i32, i32* [[X_RE_ADDR]] +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: [[X_IM:%.+]] = load i32, i32* [[X_IM_ADDR]] +// <Skip checks for complex calculations> +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR:%.+]], i32 0, i32 0 +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR]], i32 0, i32 1 +// CHECK: store i32 [[X_RE]], i32* [[X_RE_ADDR]] +// CHECK: store i32 [[X_IM]], i32* [[X_IM_ADDR]] +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR:%.+]], i32 0, i32 0 +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR]], i32 0, i32 1 +// CHECK: store i32 %{{.+}}, i32* [[X_RE_ADDR]] +// CHECK: store i32 %{{.+}}, i32* [[X_IM_ADDR]] +// CHECK: [[EXPECTED:%.+]] = bitcast { i32, i32 }* [[EXPECTED_ADDR]] to i8* +// CHECK: [[DESIRED:%.+]] = bitcast { i32, i32 }* [[DESIRED_ADDR]] to i8* +// CHECK: [[SUCCESS_FAIL:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR]] to i8*), i8* [[EXPECTED]], i8* [[DESIRED]], i32 0, i32 0) +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[X_RE:%.+]] = load i32, i32* [[X_RE_ADDR]] +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: [[X_IM:%.+]] = load i32, i32* [[X_IM_ADDR]] +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: store i32 [[X_RE]], i32* [[LD_RE_ADDR]] +// CHECK: store i32 [[X_IM]], i32* [[LD_IM_ADDR]] +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP]] to i64* +// CHECK: [[OLD_X]] = load i64, i64* [[BITCAST]] +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + cix = civ / cix; +// CHECK: [[EXPR_RE:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 0) +// CHECK: [[EXPR_IM:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 1) +// CHECK: [[BITCAST:%.+]] = bitcast { float, float }* [[TEMP:%.+]] to i8* +// CHECK: call void @__atomic_load(i64 8, i8* bitcast ({ float, float }* [[X_ADDR:@.+]] to i8*), i8* [[BITCAST]], i32 0) +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 0 +// CHECK: [[LD_RE:%.+]] = load float, float* [[LD_RE_ADDR]] +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1 +// CHECK: [[LD_IM:%.+]] = load float, float* [[LD_IM_ADDR]] +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1 +// CHECK: store float [[LD_RE]], float* [[LD_RE_ADDR]] +// CHECK: store float [[LD_IM]], float* [[LD_IM_ADDR]] +// CHECK: [[BITCAST:%.+]] = bitcast { float, float }* [[TEMP]] to i64* +// CHECK: [[X:%.+]] = load i64, i64* [[BITCAST]] +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[BITCAST:%.+]] = bitcast { float, float }* [[TEMP:%.+]] to i64* +// CHECK: store i64 [[OLD]], i64* [[BITCAST]] +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 0 +// CHECK: [[X_RE:%.+]] = load float, float* [[X_RE_ADDR]] +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1 +// CHECK: [[X_IM:%.+]] = load float, float* [[X_IM_ADDR]] +// <Skip checks for complex calculations> +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[EXPECTED_ADDR:%.+]], i32 0, i32 0 +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[EXPECTED_ADDR]], i32 0, i32 1 +// CHECK: store float [[X_RE]], float* [[X_RE_ADDR]] +// CHECK: store float [[X_IM]], float* [[X_IM_ADDR]] +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[DESIRED_ADDR:%.+]], i32 0, i32 0 +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[DESIRED_ADDR]], i32 0, i32 1 +// CHECK: store float %{{.+}}, float* [[X_RE_ADDR]] +// CHECK: store float %{{.+}}, float* [[X_IM_ADDR]] +// CHECK: [[EXPECTED:%.+]] = bitcast { float, float }* [[EXPECTED_ADDR]] to i8* +// CHECK: [[DESIRED:%.+]] = bitcast { float, float }* [[DESIRED_ADDR]] to i8* +// CHECK: [[SUCCESS_FAIL:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 8, i8* bitcast ({ float, float }* [[X_ADDR]] to i8*), i8* [[EXPECTED]], i8* [[DESIRED]], i32 0, i32 0) +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[X_RE:%.+]] = load float, float* [[X_RE_ADDR]] +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1 +// CHECK: [[X_IM:%.+]] = load float, float* [[X_IM_ADDR]] +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1 +// CHECK: store float [[X_RE]], float* [[LD_RE_ADDR]] +// CHECK: store float [[X_IM]], float* [[LD_IM_ADDR]] +// CHECK: [[BITCAST:%.+]] = bitcast { float, float }* [[TEMP]] to i64* +// CHECK: [[OLD_X]] = load i64, i64* [[BITCAST]] +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + cfx = cfv + cfx; +// CHECK: [[EXPR_RE:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 0) +// CHECK: [[EXPR_IM:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 1) +// CHECK: [[BITCAST:%.+]] = bitcast { double, double }* [[TEMP:%.+]] to i8* +// CHECK: call void @__atomic_load(i64 16, i8* bitcast ({ double, double }* [[X_ADDR:@.+]] to i8*), i8* [[BITCAST]], i32 5) +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP]], i32 0, i32 0 +// CHECK: [[LD_RE:%.+]] = load double, double* [[LD_RE_ADDR]] +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP]], i32 0, i32 1 +// CHECK: [[LD_IM:%.+]] = load double, double* [[LD_IM_ADDR]] +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP]], i32 0, i32 1 +// CHECK: store double [[LD_RE]], double* [[LD_RE_ADDR]] +// CHECK: store double [[LD_IM]], double* [[LD_IM_ADDR]] +// CHECK: [[BITCAST:%.+]] = bitcast { double, double }* [[TEMP]] to i128* +// CHECK: [[X:%.+]] = load i128, i128* [[BITCAST]] +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi i128 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[BITCAST:%.+]] = bitcast { double, double }* [[TEMP:%.+]] to i128* +// CHECK: store i128 [[OLD]], i128* [[BITCAST]] +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP]], i32 0, i32 0 +// CHECK: [[X_RE:%.+]] = load double, double* [[X_RE_ADDR]] +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP]], i32 0, i32 1 +// CHECK: [[X_IM:%.+]] = load double, double* [[X_IM_ADDR]] +// <Skip checks for complex calculations> +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[EXPECTED_ADDR:%.+]], i32 0, i32 0 +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[EXPECTED_ADDR]], i32 0, i32 1 +// CHECK: store double [[X_RE]], double* [[X_RE_ADDR]] +// CHECK: store double [[X_IM]], double* [[X_IM_ADDR]] +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[DESIRED_ADDR:%.+]], i32 0, i32 0 +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[DESIRED_ADDR]], i32 0, i32 1 +// CHECK: store double %{{.+}}, double* [[X_RE_ADDR]] +// CHECK: store double %{{.+}}, double* [[X_IM_ADDR]] +// CHECK: [[EXPECTED:%.+]] = bitcast { double, double }* [[EXPECTED_ADDR]] to i8* +// CHECK: [[DESIRED:%.+]] = bitcast { double, double }* [[DESIRED_ADDR]] to i8* +// CHECK: [[SUCCESS_FAIL:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 16, i8* bitcast ({ double, double }* [[X_ADDR]] to i8*), i8* [[EXPECTED]], i8* [[DESIRED]], i32 5, i32 5) +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[X_RE:%.+]] = load double, double* [[X_RE_ADDR]] +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP]], i32 0, i32 1 +// CHECK: [[X_IM:%.+]] = load double, double* [[X_IM_ADDR]] +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP]], i32 0, i32 1 +// CHECK: store double [[X_RE]], double* [[LD_RE_ADDR]] +// CHECK: store double [[X_IM]], double* [[LD_IM_ADDR]] +// CHECK: [[BITCAST:%.+]] = bitcast { double, double }* [[TEMP]] to i128* +// CHECK: [[OLD_X]] = load i128, i128* [[BITCAST]] +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +// CHECK: call{{.*}} @__kmpc_flush( +#pragma omp atomic seq_cst + cdx = cdx - cdv; +// CHECK: [[BV:%.+]] = load i8, i8* @{{.+}} +// CHECK: [[BOOL:%.+]] = trunc i8 [[BV]] to i1 +// CHECK: [[EXPR:%.+]] = zext i1 [[BOOL]] to i64 +// CHECK: atomicrmw and i64* @{{.+}}, i64 [[EXPR]] monotonic +#pragma omp atomic update + ulx = ulx & bv; +// CHECK: [[CV:%.+]] = load i8, i8* @{{.+}}, align 1 +// CHECK: [[EXPR:%.+]] = sext i8 [[CV]] to i32 +// CHECK: [[BX:%.+]] = load atomic i8, i8* [[BX_ADDR:@.+]] monotonic +// CHECK: [[X:%.+]] = trunc i8 [[BX]] to i1 +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi i1 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[X_RVAL:%.+]] = zext i1 [[OLD]] to i32 +// CHECK: [[AND:%.+]] = and i32 [[EXPR]], [[X_RVAL]] +// CHECK: [[CAST:%.+]] = icmp ne i32 [[AND]], 0 +// CHECK: [[EXPECTED:%.+]] = zext i1 [[OLD]] to i8 +// CHECK: [[DESIRED:%.+]] = zext i1 [[CAST]] to i8 +// CHECK: [[RES:%.+]] = cmpxchg i8* [[BX_ADDR]], i8 [[EXPECTED]], i8 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD:%.+]] = extractvalue { i8, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i8, i1 } [[RES]], 1 +// CHECK: [[OLD_X]] = trunc i8 [[OLD]] to i1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + bx = cv & bx; +// CHECK: [[UCV:%.+]] = load i8, i8* @{{.+}}, +// CHECK: [[EXPR:%.+]] = zext i8 [[UCV]] to i32 +// CHECK: [[X:%.+]] = load atomic i8, i8* [[CX_ADDR:@.+]] seq_cst +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[EXPECTED:%.+]] = phi i8 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[X_RVAL:%.+]] = sext i8 [[EXPECTED]] to i32 +// CHECK: [[ASHR:%.+]] = ashr i32 [[X_RVAL]], [[EXPR]] +// CHECK: [[DESIRED:%.+]] = trunc i32 [[ASHR]] to i8 +// CHECK: [[RES:%.+]] = cmpxchg i8* [[CX_ADDR]], i8 [[EXPECTED]], i8 [[DESIRED]] seq_cst seq_cst +// CHECK: [[OLD_X:%.+]] = extractvalue { i8, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i8, i1 } [[RES]], 1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +// CHECK: call{{.*}} @__kmpc_flush( +#pragma omp atomic update, seq_cst + cx = cx >> ucv; +// CHECK: [[SV:%.+]] = load i16, i16* @{{.+}}, +// CHECK: [[EXPR:%.+]] = sext i16 [[SV]] to i32 +// CHECK: [[X:%.+]] = load atomic i64, i64* [[ULX_ADDR:@.+]] monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[X_RVAL:%.+]] = trunc i64 [[EXPECTED]] to i32 +// CHECK: [[SHL:%.+]] = shl i32 [[EXPR]], [[X_RVAL]] +// CHECK: [[DESIRED:%.+]] = sext i32 [[SHL]] to i64 +// CHECK: [[RES:%.+]] = cmpxchg i64* [[ULX_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_X:%.+]] = extractvalue { i64, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + ulx = sv << ulx; +// CHECK: [[USV:%.+]] = load i16, i16* @{{.+}}, +// CHECK: [[EXPR:%.+]] = zext i16 [[USV]] to i64 +// CHECK: [[X:%.+]] = load atomic i64, i64* [[LX_ADDR:@.+]] monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[DESIRED:%.+]] = srem i64 [[EXPECTED]], [[EXPR]] +// CHECK: [[RES:%.+]] = cmpxchg i64* [[LX_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_X:%.+]] = extractvalue { i64, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + lx = lx % usv; +// CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}} +// CHECK: atomicrmw or i32* @{{.+}}, i32 [[EXPR]] seq_cst +// CHECK: call{{.*}} @__kmpc_flush( +#pragma omp atomic seq_cst, update + uix = iv | uix; +// CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}} +// CHECK: atomicrmw and i32* @{{.+}}, i32 [[EXPR]] monotonic +#pragma omp atomic + ix = ix & uiv; +// CHECK: [[EXPR:%.+]] = load i64, i64* @{{.+}}, +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP:%.+]] to i8* +// CHECK: call void @__atomic_load(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR:@.+]] to i8*), i8* [[BITCAST]], i32 0) +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 0 +// CHECK: [[LD_RE:%.+]] = load i32, i32* [[LD_RE_ADDR]] +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: [[LD_IM:%.+]] = load i32, i32* [[LD_IM_ADDR]] +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: store i32 [[LD_RE]], i32* [[LD_RE_ADDR]] +// CHECK: store i32 [[LD_IM]], i32* [[LD_IM_ADDR]] +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP]] to i64* +// CHECK: [[X:%.+]] = load i64, i64* [[BITCAST]] +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP:%.+]] to i64* +// CHECK: store i64 [[OLD]], i64* [[BITCAST]] +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 0 +// CHECK: [[X_RE:%.+]] = load i32, i32* [[X_RE_ADDR]] +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: [[X_IM:%.+]] = load i32, i32* [[X_IM_ADDR]] +// <Skip checks for complex calculations> +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR:%.+]], i32 0, i32 0 +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR]], i32 0, i32 1 +// CHECK: store i32 [[X_RE]], i32* [[X_RE_ADDR]] +// CHECK: store i32 [[X_IM]], i32* [[X_IM_ADDR]] +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR:%.+]], i32 0, i32 0 +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR]], i32 0, i32 1 +// CHECK: store i32 %{{.+}}, i32* [[X_RE_ADDR]] +// CHECK: store i32 %{{.+}}, i32* [[X_IM_ADDR]] +// CHECK: [[EXPECTED:%.+]] = bitcast { i32, i32 }* [[EXPECTED_ADDR]] to i8* +// CHECK: [[DESIRED:%.+]] = bitcast { i32, i32 }* [[DESIRED_ADDR]] to i8* +// CHECK: [[SUCCESS_FAIL:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR]] to i8*), i8* [[EXPECTED]], i8* [[DESIRED]], i32 0, i32 0) +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[X_RE:%.+]] = load i32, i32* [[X_RE_ADDR]] +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: [[X_IM:%.+]] = load i32, i32* [[X_IM_ADDR]] +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: store i32 [[X_RE]], i32* [[LD_RE_ADDR]] +// CHECK: store i32 [[X_IM]], i32* [[LD_IM_ADDR]] +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP]] to i64* +// CHECK: [[OLD_X]] = load i64, i64* [[BITCAST]] +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + cix = lv + cix; +// CHECK: [[ULV:%.+]] = load i64, i64* @{{.+}}, +// CHECK: [[EXPR:%.+]] = uitofp i64 [[ULV]] to float +// CHECK: [[OLD:%.+]] = load atomic i32, i32* bitcast (float* [[X_ADDR:@.+]] to i32*) monotonic +// CHECK: [[X:%.+]] = bitcast i32 [[OLD]] to float +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi float [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[MUL:%.+]] = fmul float [[OLD]], [[EXPR]] +// CHECK: [[EXPECTED:%.+]] = bitcast float [[OLD]] to i32 +// CHECK: [[DESIRED:%.+]] = bitcast float [[MUL]] to i32 +// CHECK: [[RES:%.+]] = cmpxchg i32* bitcast (float* [[X_ADDR]] to i32*), i32 [[EXPECTED]], i32 [[DESIRED]] monotonic monotonic +// CHECK: [[PREV:%.+]] = extractvalue { i32, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1 +// CHECK: [[OLD_X]] = bitcast i32 [[PREV]] to float +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + fx = fx * ulv; +// CHECK: [[LLV:%.+]] = load i64, i64* @{{.+}}, +// CHECK: [[EXPR:%.+]] = sitofp i64 [[LLV]] to double +// CHECK: [[OLD:%.+]] = load atomic i64, i64* bitcast (double* [[X_ADDR:@.+]] to i64*) monotonic +// CHECK: [[X:%.+]] = bitcast i64 [[OLD]] to double +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi double [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[DIV:%.+]] = fdiv double [[OLD]], [[EXPR]] +// CHECK: [[EXPECTED:%.+]] = bitcast double [[OLD]] to i64 +// CHECK: [[DESIRED:%.+]] = bitcast double [[DIV]] to i64 +// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (double* [[X_ADDR]] to i64*), i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic +// CHECK: [[PREV:%.+]] = extractvalue { i64, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1 +// CHECK: [[OLD_X]] = bitcast i64 [[PREV]] to double +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + dx /= llv; +// CHECK: [[ULLV:%.+]] = load i64, i64* @{{.+}}, +// CHECK: [[EXPR:%.+]] = uitofp i64 [[ULLV]] to x86_fp80 +// CHECK: [[OLD:%.+]] = load atomic i128, i128* bitcast (x86_fp80* [[X_ADDR:@.+]] to i128*) monotonic +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP:%.+]] to i128* +// CHECK: store i128 [[OLD]], i128* [[BITCAST]] +// CHECK: [[X:%.+]] = load x86_fp80, x86_fp80* [[TEMP]] +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi x86_fp80 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[SUB:%.+]] = fsub x86_fp80 [[OLD]], [[EXPR]] +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP:%.+]] to i8* +// CHECK: call void @llvm.memset.p0i8.i64(i8* [[BITCAST]], i8 0, i64 16, i32 16, i1 false) +// CHECK: store x86_fp80 [[OLD]], x86_fp80* [[TEMP]] +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP]] to i128* +// CHECK: [[EXPECTED:%.+]] = load i128, i128* [[BITCAST]] +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP:%.+]] to i8* +// CHECK: call void @llvm.memset.p0i8.i64(i8* [[BITCAST]], i8 0, i64 16, i32 16, i1 false) +// CHECK: store x86_fp80 [[SUB]], x86_fp80* [[TEMP]] +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP]] to i128* +// CHECK: [[DESIRED:%.+]] = load i128, i128* [[BITCAST]] +// CHECK: [[RES:%.+]] = cmpxchg i128* bitcast (x86_fp80* [[X_ADDR]] to i128*), i128 [[EXPECTED]], i128 [[DESIRED]] monotonic monotonic +// CHECK: [[PREV:%.+]] = extractvalue { i128, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i128, i1 } [[RES]], 1 +// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP:%.+]] to i128* +// CHECK: store i128 [[PREV]], i128* [[BITCAST]] +// CHECK: [[OLD_X]] = load x86_fp80, x86_fp80* [[TEMP]], +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + ldx -= ullv; +// CHECK: [[EXPR:%.+]] = load float, float* @{{.+}}, +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP:%.+]] to i8* +// CHECK: call void @__atomic_load(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR:@.+]] to i8*), i8* [[BITCAST]], i32 0) +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 0 +// CHECK: [[LD_RE:%.+]] = load i32, i32* [[LD_RE_ADDR]] +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: [[LD_IM:%.+]] = load i32, i32* [[LD_IM_ADDR]] +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: store i32 [[LD_RE]], i32* [[LD_RE_ADDR]] +// CHECK: store i32 [[LD_IM]], i32* [[LD_IM_ADDR]] +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP]] to i64* +// CHECK: [[X:%.+]] = load i64, i64* [[BITCAST]] +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP:%.+]] to i64* +// CHECK: store i64 [[OLD]], i64* [[BITCAST]] +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 0 +// CHECK: [[X_RE:%.+]] = load i32, i32* [[X_RE_ADDR]] +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: [[X_IM:%.+]] = load i32, i32* [[X_IM_ADDR]] +// <Skip checks for complex calculations> +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR:%.+]], i32 0, i32 0 +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR]], i32 0, i32 1 +// CHECK: store i32 [[X_RE]], i32* [[X_RE_ADDR]] +// CHECK: store i32 [[X_IM]], i32* [[X_IM_ADDR]] +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR:%.+]], i32 0, i32 0 +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR]], i32 0, i32 1 +// CHECK: store i32 %{{.+}}, i32* [[X_RE_ADDR]] +// CHECK: store i32 %{{.+}}, i32* [[X_IM_ADDR]] +// CHECK: [[EXPECTED:%.+]] = bitcast { i32, i32 }* [[EXPECTED_ADDR]] to i8* +// CHECK: [[DESIRED:%.+]] = bitcast { i32, i32 }* [[DESIRED_ADDR]] to i8* +// CHECK: [[SUCCESS_FAIL:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR]] to i8*), i8* [[EXPECTED]], i8* [[DESIRED]], i32 0, i32 0) +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[X_RE:%.+]] = load i32, i32* [[X_RE_ADDR]] +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: [[X_IM:%.+]] = load i32, i32* [[X_IM_ADDR]] +// CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1 +// CHECK: store i32 [[X_RE]], i32* [[LD_RE_ADDR]] +// CHECK: store i32 [[X_IM]], i32* [[LD_IM_ADDR]] +// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP]] to i64* +// CHECK: [[OLD_X]] = load i64, i64* [[BITCAST]] +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + cix = fv / cix; +// CHECK: [[EXPR:%.+]] = load double, double* @{{.+}}, +// CHECK: [[X:%.+]] = load atomic i16, i16* [[X_ADDR:@.+]] monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[EXPECTED:%.+]] = phi i16 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[CONV:%.+]] = sext i16 [[EXPECTED]] to i32 +// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CONV]] to double +// CHECK: [[ADD:%.+]] = fadd double [[X_RVAL]], [[EXPR]] +// CHECK: [[DESIRED:%.+]] = fptosi double [[ADD]] to i16 +// CHECK: [[RES:%.+]] = cmpxchg i16* [[X_ADDR]], i16 [[EXPECTED]], i16 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_X]] = extractvalue { i16, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i16, i1 } [[RES]], 1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + sx = sx + dv; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}, +// CHECK: [[XI8:%.+]] = load atomic i8, i8* [[X_ADDR:@.+]] monotonic +// CHECK: [[X:%.+]] = trunc i8 [[XI8]] to i1 +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[BOOL_EXPECTED:%.+]] = phi i1 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[CONV:%.+]] = zext i1 [[BOOL_EXPECTED]] to i32 +// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CONV]] to x86_fp80 +// CHECK: [[MUL:%.+]] = fmul x86_fp80 [[EXPR]], [[X_RVAL]] +// CHECK: [[BOOL_DESIRED:%.+]] = fcmp une x86_fp80 [[MUL]], 0xK00000000000000000000 +// CHECK: [[EXPECTED:%.+]] = zext i1 [[BOOL_EXPECTED]] to i8 +// CHECK: [[DESIRED:%.+]] = zext i1 [[BOOL_DESIRED]] to i8 +// CHECK: [[RES:%.+]] = cmpxchg i8* [[X_ADDR]], i8 [[EXPECTED]], i8 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_XI8:%.+]] = extractvalue { i8, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i8, i1 } [[RES]], 1 +// CHECK: [[OLD_X]] = trunc i8 [[OLD_XI8]] to i1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + bx = ldv * bx; +// CHECK: [[EXPR_RE:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* [[CIV_ADDR:@.+]], i32 0, i32 0), +// CHECK: [[EXPR_IM:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* [[CIV_ADDR]], i32 0, i32 1), +// CHECK: [[XI8:%.+]] = load atomic i8, i8* [[X_ADDR:@.+]] monotonic +// CHECK: [[X:%.+]] = trunc i8 [[XI8]] to i1 +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[BOOL_EXPECTED:%.+]] = phi i1 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[X_RVAL:%.+]] = zext i1 [[BOOL_EXPECTED]] to i32 +// CHECK: [[SUB_RE:%.+]] = sub i32 [[EXPR_RE:%.+]], [[X_RVAL]] +// CHECK: [[SUB_IM:%.+]] = sub i32 [[EXPR_IM:%.+]], 0 +// CHECK: icmp ne i32 [[SUB_RE]], 0 +// CHECK: icmp ne i32 [[SUB_IM]], 0 +// CHECK: [[BOOL_DESIRED:%.+]] = or i1 +// CHECK: [[EXPECTED:%.+]] = zext i1 [[BOOL_EXPECTED]] to i8 +// CHECK: [[DESIRED:%.+]] = zext i1 [[BOOL_DESIRED]] to i8 +// CHECK: [[RES:%.+]] = cmpxchg i8* [[X_ADDR]], i8 [[EXPECTED]], i8 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_XI8:%.+]] = extractvalue { i8, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i8, i1 } [[RES]], 1 +// CHECK: [[OLD_X]] = trunc i8 [[OLD_XI8]] to i1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + bx = civ - bx; +// CHECK: [[EXPR_RE:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 0) +// CHECK: [[EXPR_IM:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 1) +// CHECK: [[X:%.+]] = load atomic i16, i16* [[X_ADDR:@.+]] monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[EXPECTED:%.+]] = phi i16 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[CONV:%.+]] = zext i16 [[EXPECTED]] to i32 +// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CONV]] to float +// <Skip checks for complex calculations> +// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP:%.+]], i32 0, i32 0 +// CHECK: [[X_RE:%.+]] = load float, float* [[X_RE_ADDR]] +// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1 +// CHECK: [[X_IM:%.+]] = load float, float* [[X_IM_ADDR]] +// CHECK: [[DESIRED:%.+]] = fptoui float [[X_RE]] to i16 +// CHECK: [[RES:%.+]] = cmpxchg i16* [[X_ADDR]], i16 [[EXPECTED]], i16 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_X]] = extractvalue { i16, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i16, i1 } [[RES]], 1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + usx /= cfv; +// CHECK: [[EXPR_RE:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 0) +// CHECK: [[EXPR_IM:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 1) +// CHECK: [[X:%.+]] = load atomic i64, i64* [[X_ADDR:@.+]] monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ] +// CHECK: [[X_RVAL:%.+]] = sitofp i64 [[EXPECTED]] to double +// CHECK: [[ADD_RE:%.+]] = fadd double [[X_RVAL]], [[EXPR_RE]] +// CHECK: [[ADD_IM:%.+]] = fadd double 0.000000e+00, [[EXPR_IM]] +// CHECK: [[DESIRED:%.+]] = fptosi double [[ADD_RE]] to i64 +// CHECK: [[RES:%.+]] = cmpxchg i64* [[X_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic +// CHECK: [[OLD_X]] = extractvalue { i64, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1 +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + llx += cdv; +// CHECK: [[IDX:%.+]] = load i16, i16* @{{.+}} +// CHECK: load i8, i8* +// CHECK: [[VEC_ITEM_VAL:%.+]] = zext i1 %{{.+}} to i32 +// CHECK: [[I128VAL:%.+]] = load atomic i128, i128* bitcast (<4 x i32>* [[DEST:@.+]] to i128*) monotonic +// CHECK: [[LD:%.+]] = bitcast i128 [[I128VAL]] to <4 x i32> +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_VEC_VAL:%.+]] = phi <4 x i32> [ [[LD]], %{{.+}} ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: store <4 x i32> [[OLD_VEC_VAL]], <4 x i32>* [[LDTEMP:%.+]], +// CHECK: [[VEC_VAL:%.+]] = load <4 x i32>, <4 x i32>* [[LDTEMP]] +// CHECK: [[ITEM:%.+]] = extractelement <4 x i32> [[VEC_VAL]], i16 [[IDX]] +// CHECK: [[OR:%.+]] = or i32 [[ITEM]], [[VEC_ITEM_VAL]] +// CHECK: [[VEC_VAL:%.+]] = load <4 x i32>, <4 x i32>* [[LDTEMP]] +// CHECK: [[NEW_VEC_VAL:%.+]] = insertelement <4 x i32> [[VEC_VAL]], i32 [[OR]], i16 [[IDX]] +// CHECK: store <4 x i32> [[NEW_VEC_VAL]], <4 x i32>* [[LDTEMP]] +// CHECK: [[NEW_VEC_VAL:%.+]] = load <4 x i32>, <4 x i32>* [[LDTEMP]] +// CHECK: [[OLD_I128:%.+]] = bitcast <4 x i32> [[OLD_VEC_VAL]] to i128 +// CHECK: [[NEW_I128:%.+]] = bitcast <4 x i32> [[NEW_VEC_VAL]] to i128 +// CHECK: [[RES:%.+]] = cmpxchg i128* bitcast (<4 x i32>* [[DEST]] to i128*), i128 [[OLD_I128]], i128 [[NEW_I128]] monotonic monotonic +// CHECK: [[FAILED_I128_OLD_VAL:%.+]] = extractvalue { i128, i1 } [[RES]], 0 +// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i128, i1 } [[RES]], 1 +// CHECK: [[FAILED_OLD_VAL]] = bitcast i128 [[FAILED_I128_OLD_VAL]] to <4 x i32> +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + int4x[sv] |= bv; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} +// CHECK: [[PREV_VALUE:%.+]] = load atomic i32, i32* bitcast (i8* getelementptr (i8, i8* bitcast (%struct.BitFields* @{{.+}} to i8*), i64 4) to i32*) monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_BF_VALUE:%.+]] = phi i32 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: store i32 [[OLD_BF_VALUE]], i32* [[TEMP:%.+]], +// CHECK: [[A_LD:%.+]] = load i32, i32* [[TEMP]], +// CHECK: [[A_SHL:%.+]] = shl i32 [[A_LD]], 1 +// CHECK: [[A_ASHR:%.+]] = ashr i32 [[A_SHL]], 1 +// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[A_ASHR]] to x86_fp80 +// CHECK: [[SUB:%.+]] = fsub x86_fp80 [[X_RVAL]], [[EXPR]] +// CHECK: [[CONV:%.+]] = fptosi x86_fp80 [[SUB]] to i32 +// CHECK: [[NEW_VAL:%.+]] = load i32, i32* [[TEMP]], +// CHECK: [[BF_VALUE:%.+]] = and i32 [[CONV]], 2147483647 +// CHECK: [[BF_CLEAR:%.+]] = and i32 [[NEW_VAL]], -2147483648 +// CHECK: or i32 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK: store i32 %{{.+}}, i32* [[LDTEMP:%.+]] +// CHECK: [[NEW_BF_VALUE:%.+]] = load i32, i32* [[LDTEMP]] +// CHECK: [[RES:%.+]] = cmpxchg i32* bitcast (i8* getelementptr (i8, i8* bitcast (%struct.BitFields* @{{.+}} to i8*), i64 4) to i32*), i32 [[OLD_BF_VALUE]], i32 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0 +// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i32, i1 } [[RES]], 1 +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + bfx.a = bfx.a - ldv; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} +// CHECK: [[BITCAST:%.+]] = bitcast i32* [[LDTEMP:%.+]] to i8* +// CHECK: call void @__atomic_load(i64 4, i8* getelementptr (i8, i8* bitcast (%struct.BitFields_packed* @{{.+}} to i8*), i64 4), i8* [[BITCAST]], i32 0) +// CHECK: [[PREV_VALUE:%.+]] = load i32, i32* [[LDTEMP]] +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_BF_VALUE:%.+]] = phi i32 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: store i32 [[OLD_BF_VALUE]], i32* [[TEMP:%.+]], +// CHECK: [[A_LD:%.+]] = load i32, i32* [[TEMP]], +// CHECK: [[A_SHL:%.+]] = shl i32 [[A_LD]], 1 +// CHECK: [[A_ASHR:%.+]] = ashr i32 [[A_SHL]], 1 +// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[A_ASHR]] to x86_fp80 +// CHECK: [[MUL:%.+]] = fmul x86_fp80 [[X_RVAL]], [[EXPR]] +// CHECK: [[CONV:%.+]] = fptosi x86_fp80 [[MUL]] to i32 +// CHECK: [[NEW_VAL:%.+]] = load i32, i32* [[TEMP]], +// CHECK: [[BF_VALUE:%.+]] = and i32 [[CONV]], 2147483647 +// CHECK: [[BF_CLEAR:%.+]] = and i32 [[NEW_VAL]], -2147483648 +// CHECK: or i32 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK: store i32 %{{.+}}, i32* [[LDTEMP:%.+]] +// CHECK: [[NEW_BF_VALUE:%.+]] = load i32, i32* [[LDTEMP]] +// CHECK: store i32 [[OLD_BF_VALUE]], i32* [[TEMP_OLD_BF_ADDR:%.+]], +// CHECK: store i32 [[NEW_BF_VALUE]], i32* [[TEMP_NEW_BF_ADDR:%.+]], +// CHECK: [[BITCAST_TEMP_OLD_BF_ADDR:%.+]] = bitcast i32* [[TEMP_OLD_BF_ADDR]] to i8* +// CHECK: [[BITCAST_TEMP_NEW_BF_ADDR:%.+]] = bitcast i32* [[TEMP_NEW_BF_ADDR]] to i8* +// CHECK: [[FAIL_SUCCESS:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 4, i8* getelementptr (i8, i8* bitcast (%struct.BitFields_packed* @{{.+}} to i8*), i64 4), i8* [[BITCAST_TEMP_OLD_BF_ADDR]], i8* [[BITCAST_TEMP_NEW_BF_ADDR]], i32 0, i32 0) +// CHECK: [[FAILED_OLD_VAL]] = load i32, i32* [[TEMP_OLD_BF_ADDR]] +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + bfx_packed.a *= ldv; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} +// CHECK: [[PREV_VALUE:%.+]] = load atomic i32, i32* getelementptr inbounds (%struct.BitFields2, %struct.BitFields2* @{{.+}}, i32 0, i32 0) monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_BF_VALUE:%.+]] = phi i32 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: store i32 [[OLD_BF_VALUE]], i32* [[TEMP:%.+]], +// CHECK: [[A_LD:%.+]] = load i32, i32* [[TEMP]], +// CHECK: [[A_ASHR:%.+]] = ashr i32 [[A_LD]], 31 +// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[A_ASHR]] to x86_fp80 +// CHECK: [[SUB:%.+]] = fsub x86_fp80 [[X_RVAL]], [[EXPR]] +// CHECK: [[CONV:%.+]] = fptosi x86_fp80 [[SUB]] to i32 +// CHECK: [[NEW_VAL:%.+]] = load i32, i32* [[TEMP]], +// CHECK: [[BF_AND:%.+]] = and i32 [[CONV]], 1 +// CHECK: [[BF_VALUE:%.+]] = shl i32 [[BF_AND]], 31 +// CHECK: [[BF_CLEAR:%.+]] = and i32 [[NEW_VAL]], 2147483647 +// CHECK: or i32 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK: store i32 %{{.+}}, i32* [[LDTEMP:%.+]] +// CHECK: [[NEW_BF_VALUE:%.+]] = load i32, i32* [[LDTEMP]] +// CHECK: [[RES:%.+]] = cmpxchg i32* getelementptr inbounds (%struct.BitFields2, %struct.BitFields2* @{{.+}}, i32 0, i32 0), i32 [[OLD_BF_VALUE]], i32 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0 +// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i32, i1 } [[RES]], 1 +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + bfx2.a -= ldv; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} +// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr (i8, i8* bitcast (%struct.BitFields2_packed* @{{.+}} to i8*), i64 3) monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: [[BITCAST:%.+]] = bitcast i32* %{{.+}} to i8* +// CHECK: store i8 [[OLD_BF_VALUE]], i8* [[BITCAST]], +// CHECK: [[A_LD:%.+]] = load i8, i8* [[BITCAST]], +// CHECK: [[A_ASHR:%.+]] = ashr i8 [[A_LD]], 7 +// CHECK: [[CAST:%.+]] = sext i8 [[A_ASHR]] to i32 +// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CAST]] to x86_fp80 +// CHECK: [[DIV:%.+]] = fdiv x86_fp80 [[EXPR]], [[X_RVAL]] +// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 [[DIV]] to i32 +// CHECK: [[TRUNC:%.+]] = trunc i32 [[NEW_VAL]] to i8 +// CHECK: [[BF_LD:%.+]] = load i8, i8* [[BITCAST]], +// CHECK: [[BF_AND:%.+]] = and i8 [[TRUNC]], 1 +// CHECK: [[BF_VALUE:%.+]] = shl i8 [[BF_AND]], 7 +// CHECK: [[BF_CLEAR:%.+]] = and i8 %{{.+}}, 127 +// CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK: store i8 %{{.+}}, i8* [[LDTEMP:%.+]] +// CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[LDTEMP]] +// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr (i8, i8* bitcast (%struct.BitFields2_packed* @{{.+}} to i8*), i64 3), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0 +// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1 +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + bfx2_packed.a = ldv / bfx2_packed.a; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} +// CHECK: [[PREV_VALUE:%.+]] = load atomic i32, i32* getelementptr inbounds (%struct.BitFields3, %struct.BitFields3* @{{.+}}, i32 0, i32 0) monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_BF_VALUE:%.+]] = phi i32 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: store i32 [[OLD_BF_VALUE]], i32* [[TEMP:%.+]], +// CHECK: [[A_LD:%.+]] = load i32, i32* [[TEMP]], +// CHECK: [[A_SHL:%.+]] = shl i32 [[A_LD]], 7 +// CHECK: [[A_ASHR:%.+]] = ashr i32 [[A_SHL]], 18 +// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[A_ASHR]] to x86_fp80 +// CHECK: [[DIV:%.+]] = fdiv x86_fp80 [[X_RVAL]], [[EXPR]] +// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 [[DIV]] to i32 +// CHECK: [[BF_LD:%.+]] = load i32, i32* [[TEMP]], +// CHECK: [[BF_AND:%.+]] = and i32 [[NEW_VAL]], 16383 +// CHECK: [[BF_VALUE:%.+]] = shl i32 [[BF_AND]], 11 +// CHECK: [[BF_CLEAR:%.+]] = and i32 %{{.+}}, -33552385 +// CHECK: or i32 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK: store i32 %{{.+}}, i32* [[LDTEMP:%.+]] +// CHECK: [[NEW_BF_VALUE:%.+]] = load i32, i32* [[LDTEMP]] +// CHECK: [[RES:%.+]] = cmpxchg i32* getelementptr inbounds (%struct.BitFields3, %struct.BitFields3* @{{.+}}, i32 0, i32 0), i32 [[OLD_BF_VALUE]], i32 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0 +// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i32, i1 } [[RES]], 1 +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + bfx3.a /= ldv; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} +// CHECK: [[LDTEMP:%.+]] = bitcast i32* %{{.+}} to i24* +// CHECK: [[BITCAST:%.+]] = bitcast i24* %{{.+}} to i8* +// CHECK: call void @__atomic_load(i64 3, i8* getelementptr (i8, i8* bitcast (%struct.BitFields3_packed* @{{.+}} to i8*), i64 1), i8* [[BITCAST]], i32 0) +// CHECK: [[PREV_VALUE:%.+]] = load i24, i24* [[LDTEMP]] +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_BF_VALUE:%.+]] = phi i24 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: [[BITCAST:%.+]] = bitcast i32* %{{.+}} to i24* +// CHECK: store i24 [[OLD_BF_VALUE]], i24* [[BITCAST]], +// CHECK: [[A_LD:%.+]] = load i24, i24* [[BITCAST]], +// CHECK: [[A_SHL:%.+]] = shl i24 [[A_LD]], 7 +// CHECK: [[A_ASHR:%.+]] = ashr i24 [[A_SHL]], 10 +// CHECK: [[CAST:%.+]] = sext i24 [[A_ASHR]] to i32 +// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CAST]] to x86_fp80 +// CHECK: [[ADD:%.+]] = fadd x86_fp80 [[X_RVAL]], [[EXPR]] +// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 [[ADD]] to i32 +// CHECK: [[TRUNC:%.+]] = trunc i32 [[NEW_VAL]] to i24 +// CHECK: [[BF_LD:%.+]] = load i24, i24* [[BITCAST]], +// CHECK: [[BF_AND:%.+]] = and i24 [[TRUNC]], 16383 +// CHECK: [[BF_VALUE:%.+]] = shl i24 [[BF_AND]], 3 +// CHECK: [[BF_CLEAR:%.+]] = and i24 [[BF_LD]], -131065 +// CHECK: or i24 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK: store i24 %{{.+}}, i24* [[LDTEMP:%.+]] +// CHECK: [[NEW_BF_VALUE:%.+]] = load i24, i24* [[LDTEMP]] +// CHECK: [[TEMP_OLD_BF_ADDR:%.+]] = bitcast i32* %{{.+}} to i24* +// CHECK: store i24 [[OLD_BF_VALUE]], i24* [[TEMP_OLD_BF_ADDR]] +// CHECK: [[TEMP_NEW_BF_ADDR:%.+]] = bitcast i32* %{{.+}} to i24* +// CHECK: store i24 [[NEW_BF_VALUE]], i24* [[TEMP_NEW_BF_ADDR]] +// CHECK: [[BITCAST_TEMP_OLD_BF_ADDR:%.+]] = bitcast i24* [[TEMP_OLD_BF_ADDR]] to i8* +// CHECK: [[BITCAST_TEMP_NEW_BF_ADDR:%.+]] = bitcast i24* [[TEMP_NEW_BF_ADDR]] to i8* +// CHECK: [[FAIL_SUCCESS:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 3, i8* getelementptr (i8, i8* bitcast (%struct.BitFields3_packed* @{{.+}} to i8*), i64 1), i8* [[BITCAST_TEMP_OLD_BF_ADDR]], i8* [[BITCAST_TEMP_NEW_BF_ADDR]], i32 0, i32 0) +// CHECK: [[FAILED_OLD_VAL]] = load i24, i24* [[TEMP_OLD_BF_ADDR]] +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + bfx3_packed.a += ldv; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} +// CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_BF_VALUE:%.+]] = phi i64 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: store i64 [[OLD_BF_VALUE]], i64* [[TEMP:%.+]], +// CHECK: [[A_LD:%.+]] = load i64, i64* [[TEMP]], +// CHECK: [[A_SHL:%.+]] = shl i64 [[A_LD]], 47 +// CHECK: [[A_ASHR:%.+]] = ashr i64 [[A_SHL:%.+]], 63 +// CHECK: [[A_CAST:%.+]] = trunc i64 [[A_ASHR:%.+]] to i32 +// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CAST:%.+]] to x86_fp80 +// CHECK: [[MUL:%.+]] = fmul x86_fp80 [[X_RVAL]], [[EXPR]] +// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 [[MUL]] to i32 +// CHECK: [[ZEXT:%.+]] = zext i32 [[NEW_VAL]] to i64 +// CHECK: [[BF_LD:%.+]] = load i64, i64* [[TEMP]], +// CHECK: [[BF_AND:%.+]] = and i64 [[ZEXT]], 1 +// CHECK: [[BF_VALUE:%.+]] = shl i64 [[BF_AND]], 16 +// CHECK: [[BF_CLEAR:%.+]] = and i64 [[BF_LD]], -65537 +// CHECK: or i64 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK: store i64 %{{.+}}, i64* [[LDTEMP:%.+]] +// CHECK: [[NEW_BF_VALUE:%.+]] = load i64, i64* [[LDTEMP]] +// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i64, i1 } [[RES]], 0 +// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1 +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + bfx4.a = bfx4.a * ldv; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} +// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %{{.+}} ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: [[BITCAST:%.+]] = bitcast i32* %{{.+}} to i8* +// CHECK: store i8 [[OLD_BF_VALUE]], i8* [[BITCAST]], +// CHECK: [[A_LD:%.+]] = load i8, i8* [[BITCAST]], +// CHECK: [[A_SHL:%.+]] = shl i8 [[A_LD]], 7 +// CHECK: [[A_ASHR:%.+]] = ashr i8 [[A_SHL:%.+]], 7 +// CHECK: [[CAST:%.+]] = sext i8 [[A_ASHR:%.+]] to i32 +// CHECK: [[CONV:%.+]] = sitofp i32 [[CAST]] to x86_fp80 +// CHECK: [[SUB: %.+]] = fsub x86_fp80 [[CONV]], [[EXPR]] +// CHECK: [[CONV:%.+]] = fptosi x86_fp80 [[SUB:%.+]] to i32 +// CHECK: [[NEW_VAL:%.+]] = trunc i32 [[CONV]] to i8 +// CHECK: [[BF_LD:%.+]] = load i8, i8* [[BITCAST]], +// CHECK: [[BF_VALUE:%.+]] = and i8 [[NEW_VAL]], 1 +// CHECK: [[BF_CLEAR:%.+]] = and i8 [[BF_LD]], -2 +// CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK: store i8 %{{.+}}, i8* [[LDTEMP:%.+]] +// CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[LDTEMP]] +// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0 +// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1 +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + bfx4_packed.a -= ldv; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} +// CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_BF_VALUE:%.+]] = phi i64 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: store i64 [[OLD_BF_VALUE]], i64* [[TEMP:%.+]], +// CHECK: [[A_LD:%.+]] = load i64, i64* [[TEMP]], +// CHECK: [[A_SHL:%.+]] = shl i64 [[A_LD]], 40 +// CHECK: [[A_ASHR:%.+]] = ashr i64 [[A_SHL:%.+]], 57 +// CHECK: [[CONV:%.+]] = sitofp i64 [[A_ASHR]] to x86_fp80 +// CHECK: [[DIV:%.+]] = fdiv x86_fp80 [[CONV]], [[EXPR]] +// CHECK: [[CONV:%.+]] = fptosi x86_fp80 [[DIV]] to i64 +// CHECK: [[BF_LD:%.+]] = load i64, i64* [[TEMP]], +// CHECK: [[BF_AND:%.+]] = and i64 [[CONV]], 127 +// CHECK: [[BF_VALUE:%.+]] = shl i64 [[BF_AND:%.+]], 17 +// CHECK: [[BF_CLEAR:%.+]] = and i64 [[BF_LD]], -16646145 +// CHECK: [[VAL:%.+]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK: store i64 [[VAL]], i64* [[LDTEMP:%.+]] +// CHECK: [[NEW_BF_VALUE:%.+]] = load i64, i64* [[LDTEMP]] +// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i64, i1 } [[RES]], 0 +// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1 +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + bfx4.b /= ldv; +// CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} +// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) monotonic +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: [[BITCAST:%.+]] = bitcast i64* %{{.+}} to i8* +// CHECK: store i8 [[OLD_BF_VALUE]], i8* [[BITCAST]], +// CHECK: [[A_LD:%.+]] = load i8, i8* [[BITCAST]], +// CHECK: [[A_ASHR:%.+]] = ashr i8 [[A_LD]], 1 +// CHECK: [[CAST:%.+]] = sext i8 [[A_ASHR]] to i64 +// CHECK: [[CONV:%.+]] = sitofp i64 [[CAST]] to x86_fp80 +// CHECK: [[ADD:%.+]] = fadd x86_fp80 [[CONV]], [[EXPR]] +// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 [[ADD]] to i64 +// CHECK: [[TRUNC:%.+]] = trunc i64 [[NEW_VAL]] to i8 +// CHECK: [[BF_LD:%.+]] = load i8, i8* [[BITCAST]], +// CHECK: [[BF_AND:%.+]] = and i8 [[TRUNC]], 127 +// CHECK: [[BF_VALUE:%.+]] = shl i8 [[BF_AND]], 1 +// CHECK: [[BF_CLEAR:%.+]] = and i8 [[BF_LD]], 1 +// CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK: store i8 %{{.+}}, i8* [[LDTEMP:%.+]] +// CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[LDTEMP]] +// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0 +// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1 +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic update + bfx4_packed.b += ldv; +// CHECK: load i64, i64* +// CHECK: [[EXPR:%.+]] = uitofp i64 %{{.+}} to float +// CHECK: [[I64VAL:%.+]] = load atomic i64, i64* bitcast (<2 x float>* [[DEST:@.+]] to i64*) monotonic +// CHECK: [[LD:%.+]] = bitcast i64 [[I64VAL]] to <2 x float> +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[OLD_VEC_VAL:%.+]] = phi <2 x float> [ [[LD]], %{{.+}} ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] +// CHECK: store <2 x float> [[OLD_VEC_VAL]], <2 x float>* [[LDTEMP:%.+]], +// CHECK: [[VEC_VAL:%.+]] = load <2 x float>, <2 x float>* [[LDTEMP]] +// CHECK: [[X:%.+]] = extractelement <2 x float> [[VEC_VAL]], i64 0 +// CHECK: [[VEC_ITEM_VAL:%.+]] = fsub float [[EXPR]], [[X]] +// CHECK: [[VEC_VAL:%.+]] = load <2 x float>, <2 x float>* [[LDTEMP]], +// CHECK: [[NEW_VEC_VAL:%.+]] = insertelement <2 x float> [[VEC_VAL]], float [[VEC_ITEM_VAL]], i64 0 +// CHECK: store <2 x float> [[NEW_VEC_VAL]], <2 x float>* [[LDTEMP]] +// CHECK: [[NEW_VEC_VAL:%.+]] = load <2 x float>, <2 x float>* [[LDTEMP]] +// CHECK: [[OLD_I64:%.+]] = bitcast <2 x float> [[OLD_VEC_VAL]] to i64 +// CHECK: [[NEW_I64:%.+]] = bitcast <2 x float> [[NEW_VEC_VAL]] to i64 +// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (<2 x float>* [[DEST]] to i64*), i64 [[OLD_I64]], i64 [[NEW_I64]] monotonic monotonic +// CHECK: [[FAILED_I64_OLD_VAL:%.+]] = extractvalue { i64, i1 } [[RES]], 0 +// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1 +// CHECK: [[FAILED_OLD_VAL]] = bitcast i64 [[FAILED_I64_OLD_VAL]] to <2 x float> +// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] +// CHECK: [[EXIT]] +#pragma omp atomic + float2x.x = ulv - float2x.x; +// CHECK: [[EXPR:%.+]] = load double, double* @{{.+}}, +// CHECK: [[OLD_VAL:%.+]] = call i32 @llvm.read_register.i32([[REG:metadata ![0-9]+]]) +// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[OLD_VAL]] to double +// CHECK: [[DIV:%.+]] = fdiv double [[EXPR]], [[X_RVAL]] +// CHECK: [[NEW_VAL:%.+]] = fptosi double [[DIV]] to i32 +// CHECK: call void @llvm.write_register.i32([[REG]], i32 [[NEW_VAL]]) +// CHECK: call{{.*}} @__kmpc_flush( +#pragma omp atomic seq_cst + rix = dv / rix; + return 0; +} + +#endif diff --git a/test/OpenMP/critical_codegen.cpp b/test/OpenMP/critical_codegen.cpp index fdba923e1e..cf99a75202 100644 --- a/test/OpenMP/critical_codegen.cpp +++ b/test/OpenMP/critical_codegen.cpp @@ -53,6 +53,6 @@ void parallel_critical() { // TERM_DEBUG: unreachable foo(); } -// TERM_DEBUG-DAG: [[DBG_LOC_START]] = !MDLocation(line: 44, -// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !MDLocation(line: 44, +// TERM_DEBUG-DAG: [[DBG_LOC_START]] = !MDLocation(line: [[@LINE-12]], +// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !MDLocation(line: [[@LINE-3]], #endif diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp index f24f97ce23..a53af80ac6 100644 --- a/test/OpenMP/for_codegen.cpp +++ b/test/OpenMP/for_codegen.cpp @@ -8,10 +8,11 @@ #define HEADER // CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* } +// CHECK: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* // CHECK-LABEL: define {{.*void}} @{{.*}}without_schedule_clause{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) void without_schedule_clause(float *a, float *b, float *c, float *d) { // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]]) - #pragma omp for + #pragma omp for nowait // CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1) // UB = min(UB, GlobalUB) // CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]] @@ -44,7 +45,7 @@ void without_schedule_clause(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) -// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK-NOT: __kmpc_cancel_barrier // CHECK: ret void } @@ -84,7 +85,7 @@ void static_not_chunked(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) -// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // CHECK: ret void } @@ -143,7 +144,7 @@ void static_chunked(float *a, float *b, float *c, float *d) { // CHECK: [[O_LOOP1_END]] // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) -// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // CHECK: ret void } @@ -184,7 +185,7 @@ void dynamic1(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: [[O_LOOP1_END]] -// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // CHECK: ret void } @@ -225,7 +226,7 @@ void guided7(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: [[O_LOOP1_END]] -// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // CHECK: ret void } @@ -269,7 +270,7 @@ void test_auto(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: [[O_LOOP1_END]] -// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // CHECK: ret void } @@ -310,7 +311,7 @@ void runtime(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: [[O_LOOP1_END]] -// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // CHECK: ret void } diff --git a/test/OpenMP/for_firstprivate_codegen.cpp b/test/OpenMP/for_firstprivate_codegen.cpp new file mode 100644 index 0000000000..b2fe730b6c --- /dev/null +++ b/test/OpenMP/for_firstprivate_codegen.cpp @@ -0,0 +1,280 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +struct St { + int a, b; + St() : a(0), b(0) {} + St(const St &st) : a(st.a + st.b), b(0) {} + ~St() {} +}; + +volatile int g = 1212; + +template <class T> +struct S { + T f; + S(T a) : f(a + g) {} + S() : f(g) {} + S(const S &s, St t = St()) : f(s.f + t.a) {} + operator T() { return T(); } + ~S() {} +}; + +// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } +// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} } +// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } + +template <typename T> +T tmain() { + S<T> test; + T t_var = T(); + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> var(3); +#pragma omp parallel +#pragma omp for firstprivate(t_var, vec, s_arr, var) + for (int i = 0; i < 0; ++i) { + vec[i] = t_var; + s_arr[i] = var; + } + return T(); +} + +// CHECK: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer, +S<float> test; +// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333, +int t_var = 333; +// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2], +int vec[] = {1, 2}; +// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer, +S<float> s_arr[] = {1, 2}; +// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer, +S<float> var(3); +// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* + +// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) +// CHECK: ([[S_FLOAT_TY]]*)* [[S_FLOAT_TY_DESTR:@[^ ]+]] {{[^,]+}}, {{.+}}([[S_FLOAT_TY]]* [[TEST]] +int main() { +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, + // LAMBDA-LABEL: @main + // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + [&]() { +// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( +// LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) +#pragma omp parallel +#pragma omp for firstprivate(g) + for (int i = 0; i < 2; ++i) { + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // Skip temp vars for loop + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] + // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // LAMBDA: call i32 @__kmpc_cancel_barrier( + g = 1; + // LAMBDA: call void @__kmpc_for_static_init_4( + // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) + // LAMBDA: call void @__kmpc_for_static_fini( + // LAMBDA: call i32 @__kmpc_cancel_barrier( + [&]() { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + g = 2; + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] + // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ +// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* +// BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) +#pragma omp parallel +#pragma omp for firstprivate(g) + for (int i = 0; i < 2; ++i) { + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // Skip temp vars for loop + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] + // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS: call i32 @__kmpc_cancel_barrier( + g = 1; + // BLOCKS: call void @__kmpc_for_static_init_4( + // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + // BLOCKS: call void @__kmpc_for_static_fini( + // BLOCKS: call i32 @__kmpc_cancel_barrier( + ^{ + // BLOCKS: define {{.+}} void {{@.+}}(i8* + g = 2; + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: ret + }(); + } + }(); + return 0; +#else +#pragma omp for firstprivate(t_var, vec, s_arr, var) + for (int i = 0; i < 0; ++i) { + vec[i] = t_var; + s_arr[i] = var; + } + return tmain<int>(); +#endif +} + +// CHECK: define {{.*}}i{{[0-9]+}} @main() +// CHECK: alloca i{{[0-9]+}}, +// Skip temp vars for loop +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num( + +// firstprivate t_var(t_var) +// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR]], +// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], + +// firstprivate vec(vec) +// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* +// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* bitcast ([2 x i{{[0-9]+}}]* [[VEC]] to i8*), + +// firstprivate s_arr(s_arr) +// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] +// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] +// CHECK: [[S_ARR_BODY]] +// CHECK: getelementptr inbounds ([2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0) +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR:@.+]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] + +// firstprivate var(var) +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR]], [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) + +// Synchronization for initialization. +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) + +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK: call void @__kmpc_for_static_fini( + +// ~(firstprivate var), ~(firstprivate s_arr) +// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) + +// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() + +// CHECK: ret void + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// Skip temp vars for loop +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// firstprivate t_var(t_var) +// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], +// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], +// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], + +// firstprivate vec(vec) +// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], +// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* +// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* +// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]], + +// firstprivate s_arr(s_arr) +// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_REF]], +// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] +// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] +// CHECK: [[S_ARR_BODY]] +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] + +// firstprivate var(var) +// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_REF_PTR]], +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) + +// Synchronization for initialization. +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) + +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK: call void @__kmpc_for_static_fini( + +// ~(firstprivate var), ~(firstprivate s_arr) +// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: ret void +#endif + diff --git a/test/OpenMP/for_firstprivate_messages.cpp b/test/OpenMP/for_firstprivate_messages.cpp index 6aa977b65d..a7333718c5 100644 --- a/test/OpenMP/for_firstprivate_messages.cpp +++ b/test/OpenMP/for_firstprivate_messages.cpp @@ -26,8 +26,8 @@ class S3 { S3 &operator=(const S3 &s3); public: - S3() : a(0) {} // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}} - S3(S3 &s3) : a(s3.a) {} // expected-note {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}} + S3() : a(0) {} // expected-note 2 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}} + S3(S3 &s3) : a(s3.a) {} // expected-note 2 {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}} }; const S3 c; const S3 ca[5]; @@ -152,6 +152,14 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; @@ -194,7 +202,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{no matching constructor for initialization of 'const S3'}} +#pragma omp for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{no matching constructor for initialization of 'S3'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel @@ -210,7 +218,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for firstprivate(ca) // OK +#pragma omp for firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel @@ -288,6 +296,10 @@ int main(int argc, char **argv) { #pragma omp for firstprivate(i) // expected-error {{firstprivate variable must be shared}} for (i = 0; i < argc; ++i) foo(); +#pragma omp parallel +#pragma omp for firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} } diff --git a/test/OpenMP/for_lastprivate_codegen.cpp b/test/OpenMP/for_lastprivate_codegen.cpp new file mode 100644 index 0000000000..b9e23cee7a --- /dev/null +++ b/test/OpenMP/for_lastprivate_codegen.cpp @@ -0,0 +1,361 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +template <class T> +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + S<T> &operator=(const S<T> &); + operator T() { return T(); } + ~S() {} +}; + +volatile int g = 1212; + +// CHECK: [[S_FLOAT_TY:%.+]] = type { float } +// CHECK: [[CAP_MAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* } +// CHECK: [[S_INT_TY:%.+]] = type { i32 } +// CHECK: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } +// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* +// CHECK-DAG: [[X:@.+]] = global double 0.0 +template <typename T> +T tmain() { + S<T> test; + T t_var = T(); + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> var(3); +#pragma omp parallel +#pragma omp for lastprivate(t_var, vec, s_arr, var) + for (int i = 0; i < 2; ++i) { + vec[i] = t_var; + s_arr[i] = var; + } + return T(); +} + +namespace A { +double x; +} +namespace B { +using A::x; +} + +int main() { +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, + // LAMBDA-LABEL: @main + // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) +#pragma omp parallel +#pragma omp for lastprivate(g) + for (int i = 0; i < 2; ++i) { + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // LAMBDA: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 %{{.+}}, i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) + // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) + // LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) + g = 1; + // Check for final copying of private values back to original vars. + // LAMBDA: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], + // LAMBDA: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 + // LAMBDA: br i1 [[IS_LAST_ITER:%.+]], label %[[LAST_THEN:.+]], label %[[LAST_DONE:.+]] + // LAMBDA: [[LAST_THEN]] + // Actual copying. + + // original g=private_g; + // LAMBDA: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], + // LAMBDA: br label %[[LAST_DONE]] + // LAMBDA: [[LAST_DONE]] + // LAMBDA: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} + // LAMBDA: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] + // LAMBDA: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) + [&]() { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + g = 2; + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] + // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) +#pragma omp parallel +#pragma omp for lastprivate(g) + for (int i = 0; i < 2; ++i) { + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // BLOCKS: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 %{{.+}}, i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) + // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + // BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) + g = 1; + // Check for final copying of private values back to original vars. + // BLOCKS: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], + // BLOCKS: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 + // BLOCKS: br i1 [[IS_LAST_ITER:%.+]], label %[[LAST_THEN:.+]], label %[[LAST_DONE:.+]] + // BLOCKS: [[LAST_THEN]] + // Actual copying. + + // original g=private_g; + // BLOCKS: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], + // BLOCKS: br label %[[LAST_DONE]] + // BLOCKS: [[LAST_DONE]] + // BLOCKS: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} + // BLOCKS: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] + // BLOCKS: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) + g = 1; + ^{ + // BLOCKS: define {{.+}} void {{@.+}}(i8* + g = 2; + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: ret + }(); + } + }(); + return 0; +#else + S<float> test; + int t_var = 0; + int vec[] = {1, 2}; + S<float> s_arr[] = {1, 2}; + S<float> var(3); +#pragma omp parallel +#pragma omp for lastprivate(t_var, vec, s_arr, var) + for (int i = 0; i < 2; ++i) { + vec[i] = t_var; + s_arr[i] = var; + } +#pragma omp parallel +#pragma omp for lastprivate(A::x, B::x) + for (int i = 0; i < 2; ++i) { + A::x++; + } + return tmain<int>(); +#endif +} + +// CHECK: define i{{[0-9]+}} @main() +// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) +// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, %{{.+}}*)* [[MAIN_MICROTASK1:@.+]] to void +// CHECK: = call {{.+}} [[TMAIN_INT:@.+]]() +// CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* +// CHECK: ret + +// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] + +// Check for default initialization. +// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], +// CHECK-NOT: [[T_VAR_PRIV]] +// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], +// CHECK-NOT: [[VEC_PRIV]] +// CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_REF_PTR]], +// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]* +// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]]) +// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_REF_PTR]], +// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) +// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 %{{.+}}, i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) +// <Skip loop body> +// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) + +// Check for final copying of private values back to original vars. +// CHECK: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], +// CHECK: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 +// CHECK: br i1 [[IS_LAST_ITER:%.+]], label %[[LAST_THEN:.+]], label %[[LAST_DONE:.+]] +// CHECK: [[LAST_THEN]] +// Actual copying. + +// original t_var=private_t_var; +// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]], +// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_REF]], + +// original vec[]=private_vec[]; +// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* +// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* +// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]], + +// original s_arr[]=private_s_arr[]; +// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]* +// CHECK: [[S_ARR_END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_END]] +// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] +// CHECK: [[S_ARR_BODY]] +// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN:@.+]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}) +// CHECK: br i1 {{.+}}, label %[[S_ARR_BODY_DONE]], label %[[S_ARR_BODY]] +// CHECK: [[S_ARR_BODY_DONE]] + +// original var=private_var; +// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN:@.+]]([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* {{.*}} [[VAR_PRIV]]) +// CHECK: br label %[[LAST_DONE]] +// CHECK: [[LAST_DONE]] +// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: ret void + +// +// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: [[X_PRIV:%.+]] = alloca double, +// CHECK-NOT: alloca double + +// Check for default initialization. +// CHECK-NOT: [[X_PRIV]] + +// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 %{{.+}}, i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) +// <Skip loop body> +// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) + +// Check for final copying of private values back to original vars. +// CHECK: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], +// CHECK: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 +// CHECK: br i1 [[IS_LAST_ITER:%.+]], label %[[LAST_THEN:.+]], label %[[LAST_DONE:.+]] +// CHECK: [[LAST_THEN]] +// Actual copying. + +// original x=private_x; +// CHECK: [[X_VAL:%.+]] = load double, double* [[X_PRIV]], +// CHECK: store double [[X_VAL]], double* [[X]], +// CHECK-NEXT: br label %[[LAST_DONE]] +// CHECK: [[LAST_DONE]] + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: ret void + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] + +// Check for default initialization. +// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], +// CHECK-NOT: [[T_VAR_PRIV]] +// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], +// CHECK-NOT: [[VEC_PRIV]] +// CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_REF_PTR]], +// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]* +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]]) +// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_REF_PTR]], +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 %{{.+}}, i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) +// <Skip loop body> +// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) + +// Check for final copying of private values back to original vars. +// CHECK: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], +// CHECK: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 +// CHECK: br i1 [[IS_LAST_ITER:%.+]], label %[[LAST_THEN:.+]], label %[[LAST_DONE:.+]] +// CHECK: [[LAST_THEN]] +// Actual copying. + +// original t_var=private_t_var; +// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]], +// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_REF]], + +// original vec[]=private_vec[]; +// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* +// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* +// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]], + +// original s_arr[]=private_s_arr[]; +// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]] to [[S_INT_TY]]* +// CHECK: [[S_ARR_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_END]] +// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] +// CHECK: [[S_ARR_BODY]] +// CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN:@.+]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}) +// CHECK: br i1 {{.+}}, label %[[S_ARR_BODY_DONE]], label %[[S_ARR_BODY]] +// CHECK: [[S_ARR_BODY_DONE]] + +// original var=private_var; +// CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN:@.+]]([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* {{.*}} [[VAR_PRIV]]) +// CHECK: br label %[[LAST_DONE]] +// CHECK: [[LAST_DONE]] +// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: ret void +#endif + diff --git a/test/OpenMP/for_lastprivate_messages.cpp b/test/OpenMP/for_lastprivate_messages.cpp index a3a1c4b34e..632ed8446c 100644 --- a/test/OpenMP/for_lastprivate_messages.cpp +++ b/test/OpenMP/for_lastprivate_messages.cpp @@ -15,15 +15,17 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} + const S2 &operator =(const S2&) const; + S2 &operator =(const S2&); static float S2s; // expected-note {{static data member is predetermined as shared}} static const float S2sc; }; const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} const S2 b; const S2 ba[5]; -class S3 { // expected-note 2 {{'S3' declared here}} +class S3 { int a; - S3 &operator=(const S3 &s3); + S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}} public: S3() : a(0) {} @@ -32,17 +34,17 @@ public: const S3 c; // expected-note {{global variable is predetermined as shared}} const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} extern const int f; // expected-note {{global variable is predetermined as shared}} -class S4 { // expected-note 3 {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note 3 {{implicitly declared private here}} S4(const S4 &s4); public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(const S5 &s5) : a(s5.a) {} @@ -62,8 +64,8 @@ S3 h; template <class I, class C> int foomain(int argc, char **argv) { - I e(4); // expected-note {{'e' defined here}} - I g(5); // expected-note {{'g' defined here}} + I e(4); + I g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel @@ -107,7 +109,7 @@ int foomain(int argc, char **argv) { for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel -#pragma omp for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp for lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel @@ -140,12 +142,20 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} - S3 m; // expected-note 2 {{'m' defined here}} + S4 e(4); + S5 g(5); + S3 m; S6 n(2); int i; int &j = i; // expected-note {{'j' defined here}} @@ -223,11 +233,11 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp for lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp for lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel @@ -235,6 +245,10 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel +#pragma omp for lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel #pragma omp for private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}} for (i = 0; i < argc; ++i) foo(); @@ -255,7 +269,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp for firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel diff --git a/test/OpenMP/for_private_messages.cpp b/test/OpenMP/for_private_messages.cpp index 45c8683cfa..635a17d6e5 100644 --- a/test/OpenMP/for_private_messages.cpp +++ b/test/OpenMP/for_private_messages.cpp @@ -108,6 +108,14 @@ int foomain(I argc, C **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { S4 e(4); S5 g(5); @@ -149,6 +157,9 @@ int main(int argc, char **argv) { #pragma omp for private(h) // expected-error {{threadprivate or thread local variable cannot be private}} for (int k = 0; k < argc; ++k) ++k; +#pragma omp for private(B::x) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; #pragma omp for shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp for'}} for (int k = 0; k < argc; ++k) ++k; diff --git a/test/OpenMP/for_reduction_messages.cpp b/test/OpenMP/for_reduction_messages.cpp index 62fee52e49..5ebb7b7951 100644 --- a/test/OpenMP/for_reduction_messages.cpp +++ b/test/OpenMP/for_reduction_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 150 -o - %s void foo() { } @@ -11,7 +11,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+=(const S2 &arg) { return (*this); } + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} public: S2() : a(0) {} @@ -28,17 +28,17 @@ class S3 { public: S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} - S3 operator+=(const S3 &arg1) { return arg1; } + S3 operator+(const S3 &arg1) { return arg1; } }; -int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } S3 c; // expected-note 2 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} S4(const S4 &s4); - S4 &operator+=(const S4 &arg) { return (*this); } + S4 &operator+(const S4 &arg) { return (*this); } public: S4(int v) : a(v) {} @@ -46,26 +46,26 @@ public: S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} S5(const S5 &s5) : a(s5.a) {} - S5 &operator+=(const S5 &arg); + S5 &operator+(const S5 &arg); public: S5(int v) : a(v) {} }; -class S6 { +class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} int a; public: S6() : a(6) {} operator int() { return 6; } -} o; // expected-note 2 {{'o' defined here}} +} o; S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} template <class T> // expected-note {{declared here}} -T tmain(T argc) { // expected-note 2 {{'argc' defined here}} +T tmain(T argc) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -74,7 +74,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} - T fl; // expected-note {{'fl' defined here}} + T fl; #pragma omp parallel #pragma omp for reduction // expected-error {{expected '(' after 'reduction'}} for (int i = 0; i < 10; ++i) @@ -104,11 +104,11 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -128,7 +128,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -152,7 +152,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -168,7 +168,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp for reduction(+ : o) // expected-error {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -204,18 +204,26 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} return T(); } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note 2 {{'j' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; // expected-note {{'q' defined here}} - float fl; // expected-note {{'fl' defined here}} + float fl; #pragma omp parallel #pragma omp for reduction // expected-error {{expected '(' after 'reduction'}} for (int i = 0; i < 10; ++i) @@ -269,7 +277,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -293,7 +301,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -305,7 +313,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} +#pragma omp for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -313,7 +321,11 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp for reduction(+ : B::x, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for reduction(+ : o) // expected-error {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel diff --git a/test/OpenMP/for_simd_firstprivate_messages.cpp b/test/OpenMP/for_simd_firstprivate_messages.cpp index 1345bfc988..194656b13f 100644 --- a/test/OpenMP/for_simd_firstprivate_messages.cpp +++ b/test/OpenMP/for_simd_firstprivate_messages.cpp @@ -152,6 +152,14 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; @@ -247,6 +255,10 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel +#pragma omp for simd firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel #pragma omp for simd private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/for_simd_lastprivate_messages.cpp b/test/OpenMP/for_simd_lastprivate_messages.cpp index 38651e5c8e..8eff052c51 100644 --- a/test/OpenMP/for_simd_lastprivate_messages.cpp +++ b/test/OpenMP/for_simd_lastprivate_messages.cpp @@ -15,15 +15,17 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} + S2 &operator =(const S2&); + const S2 &operator =(const S2&) const; static float S2s; // expected-note {{static data member is predetermined as shared}} static const float S2sc; }; const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} const S2 b; const S2 ba[5]; -class S3 { // expected-note 2 {{'S3' declared here}} +class S3 { int a; - S3 &operator=(const S3 &s3); + S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}} public: S3() : a(0) {} @@ -32,17 +34,17 @@ public: const S3 c; // expected-note {{global variable is predetermined as shared}} const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} extern const int f; // expected-note {{global variable is predetermined as shared}} -class S4 { // expected-note 3 {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note 3 {{implicitly declared private here}} S4(const S4 &s4); public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(const S5 &s5) : a(s5.a) {} @@ -62,8 +64,8 @@ S3 h; template <class I, class C> int foomain(int argc, char **argv) { - I e(4); // expected-note {{'e' defined here}} - I g(5); // expected-note {{'g' defined here}} + I e(4); + I g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel @@ -107,7 +109,7 @@ int foomain(int argc, char **argv) { for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel -#pragma omp for simd lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp for simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel @@ -140,12 +142,20 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} - S3 m; // expected-note 2 {{'m' defined here}} + S4 e(4); + S5 g(5); + S3 m; S6 n(2); int i; int &j = i; // expected-note {{'j' defined here}} @@ -223,15 +233,15 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for simd lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp for simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for simd lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp for simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} +#pragma omp for simd lastprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be lastprivate}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel @@ -255,7 +265,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for simd firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp for simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel diff --git a/test/OpenMP/for_simd_linear_messages.cpp b/test/OpenMP/for_simd_linear_messages.cpp index 9a935c3fdf..705c9f538c 100644 --- a/test/OpenMP/for_simd_linear_messages.cpp +++ b/test/OpenMP/for_simd_linear_messages.cpp @@ -148,6 +148,14 @@ template<class I, class C> int foomain(I argc, C **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace C { +using A::x; +} + int main(int argc, char **argv) { double darr[100]; // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} @@ -185,7 +193,7 @@ int main(int argc, char **argv) { // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}} #pragma omp for simd linear(e, g) for (int k = 0; k < argc; ++k) ++k; - #pragma omp for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + #pragma omp for simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel { diff --git a/test/OpenMP/for_simd_private_messages.cpp b/test/OpenMP/for_simd_private_messages.cpp index 016a5ec6b5..3f7cb268e2 100644 --- a/test/OpenMP/for_simd_private_messages.cpp +++ b/test/OpenMP/for_simd_private_messages.cpp @@ -108,6 +108,14 @@ int foomain(I argc, C **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { S4 e(4); S5 g(5); @@ -146,7 +154,7 @@ int main(int argc, char **argv) { #pragma omp for simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (int k = 0; k < argc; ++k) ++k; -#pragma omp for simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} +#pragma omp for simd private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} for (int k = 0; k < argc; ++k) ++k; #pragma omp for simd shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp for simd'}} diff --git a/test/OpenMP/for_simd_reduction_messages.cpp b/test/OpenMP/for_simd_reduction_messages.cpp index 708973be51..b4099d538a 100644 --- a/test/OpenMP/for_simd_reduction_messages.cpp +++ b/test/OpenMP/for_simd_reduction_messages.cpp @@ -11,7 +11,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+=(const S2 &arg) { return (*this); } + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} public: S2() : a(0) {} @@ -28,17 +28,17 @@ class S3 { public: S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} - S3 operator+=(const S3 &arg1) { return arg1; } + S3 operator+(const S3 &arg1) { return arg1; } }; -int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } S3 c; // expected-note 2 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} S4(const S4 &s4); - S4 &operator+=(const S4 &arg) { return (*this); } + S4 &operator+(const S4 &arg) { return (*this); } public: S4(int v) : a(v) {} @@ -46,26 +46,26 @@ public: S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} S5(const S5 &s5) : a(s5.a) {} - S5 &operator+=(const S5 &arg); + S5 &operator+(const S5 &arg); public: S5(int v) : a(v) {} }; -class S6 { +class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} int a; public: S6() : a(6) {} operator int() { return 6; } -} o; // expected-note 2 {{'o' defined here}} +} o; S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} template <class T> // expected-note {{declared here}} -T tmain(T argc) { // expected-note 2 {{'argc' defined here}} +T tmain(T argc) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -74,7 +74,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} - T fl; // expected-note {{'fl' defined here}} + T fl; #pragma omp parallel #pragma omp for simd reduction // expected-error {{expected '(' after 'reduction'}} for (int i = 0; i < 10; ++i) @@ -104,11 +104,11 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp for simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -128,7 +128,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -152,7 +152,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -168,7 +168,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp for simd reduction(+ : o) // expected-error {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -204,18 +204,26 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} return T(); } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note 2 {{'j' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; // expected-note {{'q' defined here}} - float fl; // expected-note {{'fl' defined here}} + float fl; #pragma omp parallel #pragma omp for simd reduction // expected-error {{expected '(' after 'reduction'}} for (int i = 0; i < 10; ++i) @@ -269,7 +277,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -293,7 +301,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -305,15 +313,15 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} +#pragma omp for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} +#pragma omp for simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp for simd reduction(+ : o) // expected-error {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel diff --git a/test/OpenMP/master_codegen.cpp b/test/OpenMP/master_codegen.cpp index 25438f131b..8dfd53c562 100644 --- a/test/OpenMP/master_codegen.cpp +++ b/test/OpenMP/master_codegen.cpp @@ -61,7 +61,7 @@ void parallel_master() { // TERM_DEBUG: unreachable foo(); } -// TERM_DEBUG-DAG: [[DBG_LOC_START]] = !MDLocation(line: 52, -// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !MDLocation(line: 52, +// TERM_DEBUG-DAG: [[DBG_LOC_START]] = !MDLocation(line: [[@LINE-12]], +// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !MDLocation(line: [[@LINE-3]], #endif diff --git a/test/OpenMP/parallel_codegen.cpp b/test/OpenMP/parallel_codegen.cpp index 73c4d41e44..88c7f7b87a 100644 --- a/test/OpenMP/parallel_codegen.cpp +++ b/test/OpenMP/parallel_codegen.cpp @@ -39,7 +39,7 @@ int main (int argc, char **argv) { // CHECK: [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon, %struct.anon* [[AGG_CAPTURED]], i32 0, i32 0 // CHECK-NEXT: store i32* {{%[a-z0-9.]+}}, i32** [[ARGC_REF]] // CHECK-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon* [[AGG_CAPTURED]] to i8* -// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @.omp_outlined. to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i8* [[BITCAST]]) // CHECK-NEXT: [[ARGV:%.+]] = load i8**, i8*** {{%[a-z0-9.]+}} // CHECK-NEXT: [[RET:%.+]] = call {{[a-z]*[ ]?i32}} [[TMAIN:@.+tmain.+]](i8** [[ARGV]]) // CHECK-NEXT: ret i32 [[RET]] @@ -55,13 +55,13 @@ int main (int argc, char **argv) { // CHECK-DEBUG-NEXT: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t, %ident_t* [[LOC_2_ADDR]], i32 0, i32 4 // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.+}} x i8], [{{.+}} x i8]* [[LOC1]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]] // CHECK-DEBUG-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon* [[AGG_CAPTURED]] to i8* -// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @.omp_outlined. to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i8* [[BITCAST]]) // CHECK-DEBUG-NEXT: [[ARGV:%.+]] = load i8**, i8*** {{%[a-z0-9.]+}} // CHECK-DEBUG-NEXT: [[RET:%.+]] = call i32 [[TMAIN:@.+tmain.+]](i8** [[ARGV]]) // CHECK-DEBUG-NEXT: ret i32 [[RET]] // CHECK-DEBUG-NEXT: } -// CHECK-LABEL: define internal void @.omp_outlined.(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context) +// CHECK: define internal void [[OMP_OUTLINED]](i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context) // CHECK: #[[FN_ATTRS:[0-9]+]] // CHECK: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon* // CHECK: store %struct.anon* %__context, %struct.anon** [[CONTEXT_ADDR]] @@ -70,11 +70,12 @@ int main (int argc, char **argv) { // CHECK-NEXT: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_REF]] // CHECK-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]] // CHECK-NEXT: invoke void [[FOO:@.+foo.+]](i32{{[ ]?[a-z]*}} [[ARGC]]) +// CHECK: call {{.+}} @__kmpc_cancel_barrier( // CHECK: ret void // CHECK: call void @{{.+terminate.*|abort}}( // CHECK-NEXT: unreachable // CHECK-NEXT: } -// CHECK-DEBUG-LABEL: define internal void @.omp_outlined.(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context) +// CHECK-DEBUG: define internal void [[OMP_OUTLINED]](i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context) // CHECK-DEBUG: #[[FN_ATTRS:[0-9]+]] // CHECK-DEBUG: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon* // CHECK-DEBUG: store %struct.anon* %__context, %struct.anon** [[CONTEXT_ADDR]] @@ -83,6 +84,7 @@ int main (int argc, char **argv) { // CHECK-DEBUG-NEXT: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_REF]] // CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]] // CHECK-DEBUG-NEXT: invoke void [[FOO:@.+foo.+]](i32 [[ARGC]]) +// CHECK-DEBUG: call {{.+}} @__kmpc_cancel_barrier( // CHECK-DEBUG: ret void // CHECK-DEBUG: call void @{{.+terminate.*|abort}}( // CHECK-DEBUG-NEXT: unreachable @@ -98,7 +100,7 @@ int main (int argc, char **argv) { // CHECK: [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon.0, %struct.anon.0* [[AGG_CAPTURED]], i32 0, i32 0 // CHECK-NEXT: store i8*** {{%[a-z0-9.]+}}, i8**** [[ARGC_REF]] // CHECK-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon.0* [[AGG_CAPTURED]] to i8* -// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @.omp_outlined.1 to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i8* [[BITCAST]]) // CHECK-NEXT: ret i32 0 // CHECK-NEXT: } // CHECK-DEBUG: define linkonce_odr i32 [[TMAIN]](i8** %argc) @@ -112,11 +114,11 @@ int main (int argc, char **argv) { // CHECK-DEBUG-NEXT: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t, %ident_t* [[LOC_2_ADDR]], i32 0, i32 4 // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.+}} x i8], [{{.+}} x i8]* [[LOC2]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]] // CHECK-DEBUG-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon.0* [[AGG_CAPTURED]] to i8* -// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @.omp_outlined.1 to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i8* [[BITCAST]]) // CHECK-DEBUG-NEXT: ret i32 0 // CHECK-DEBUG-NEXT: } -// CHECK-LABEL: define internal void @.omp_outlined.1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context) +// CHECK: define internal void [[OMP_OUTLINED]](i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context) // CHECK: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon.0* // CHECK: store %struct.anon.0* %__context, %struct.anon.0** [[CONTEXT_ADDR]] // CHECK: [[CONTEXT_PTR:%.+]] = load %struct.anon.0*, %struct.anon.0** [[CONTEXT_ADDR]] @@ -124,11 +126,12 @@ int main (int argc, char **argv) { // CHECK-NEXT: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_REF]] // CHECK-NEXT: [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]] // CHECK-NEXT: invoke void [[FOO1:@.+foo.+]](i8** [[ARGC]]) +// CHECK: call {{.+}} @__kmpc_cancel_barrier( // CHECK: ret void // CHECK: call void @{{.+terminate.*|abort}}( // CHECK-NEXT: unreachable // CHECK-NEXT: } -// CHECK-DEBUG-LABEL: define internal void @.omp_outlined.1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context) +// CHECK-DEBUG: define internal void [[OMP_OUTLINED]](i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context) // CHECK-DEBUG: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon.0* // CHECK-DEBUG: store %struct.anon.0* %__context, %struct.anon.0** [[CONTEXT_ADDR]] // CHECK-DEBUG: [[CONTEXT_PTR:%.+]] = load %struct.anon.0*, %struct.anon.0** [[CONTEXT_ADDR]] @@ -136,6 +139,7 @@ int main (int argc, char **argv) { // CHECK-DEBUG-NEXT: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_REF]] // CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]] // CHECK-DEBUG-NEXT: invoke void [[FOO1:@.+foo.+]](i8** [[ARGC]]) +// CHECK-DEBUG: call {{.+}} @__kmpc_cancel_barrier( // CHECK-DEBUG: ret void // CHECK-DEBUG: call void @{{.+terminate.*|abort}}( // CHECK-DEBUG-NEXT: unreachable diff --git a/test/OpenMP/parallel_copyin_codegen.cpp b/test/OpenMP/parallel_copyin_codegen.cpp new file mode 100644 index 0000000000..0bb43693c9 --- /dev/null +++ b/test/OpenMP/parallel_copyin_codegen.cpp @@ -0,0 +1,272 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +volatile int g = 1212; +#pragma omp threadprivate(g) + +template <class T> +struct S { + T f; + S(T a) : f(a + g) {} + S() : f(g) {} + S &operator=(const S &) { return *this; }; + operator T() { return T(); } + ~S() {} +}; + +// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } +// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* + + +// CHECK-DAG: [[T_VAR:@.+]] = internal global i{{[0-9]+}} 1122, +// CHECK-DAG: [[VEC:@.+]] = internal global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2], +// CHECK-DAG: [[S_ARR:@.+]] = internal global [2 x [[S_FLOAT_TY]]] zeroinitializer, +// CHECK-DAG: [[VAR:@.+]] = internal global [[S_FLOAT_TY]] zeroinitializer, +// CHECK-DAG: [[TMAIN_T_VAR:@.+]] = linkonce_odr global i{{[0-9]+}} 333, +// CHECK-DAG: [[TMAIN_VEC:@.+]] = linkonce_odr global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 3, i{{[0-9]+}} 3], +// CHECK-DAG: [[TMAIN_S_ARR:@.+]] = linkonce_odr global [2 x [[S_INT_TY]]] zeroinitializer, +// CHECK-DAG: [[TMAIN_VAR:@.+]] = linkonce_odr global [[S_INT_TY]] zeroinitializer, +template <typename T> +T tmain() { + S<T> test; + test = S<T>(); + static T t_var = 333; + static T vec[] = {3, 3}; + static S<T> s_arr[] = {1, 2}; + static S<T> var(3); +#pragma omp threadprivate(t_var, vec, s_arr, var) +#pragma omp parallel copyin(t_var, vec, s_arr, var) + { + vec[0] = t_var; + s_arr[0] = var; + } +#pragma omp parallel copyin(t_var) + {} + return T(); +} + +int main() { +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, + // LAMBDA-LABEL: @main + // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* +#pragma omp parallel copyin(g) + { + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + + // threadprivate_g = g; + // LAMBDA: call i8* @__kmpc_threadprivate_cached({{.+}} [[G]] + // LAMBDA: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} + // LAMBDA: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[G]] to i{{[0-9]+}}), %{{.+}} + // LAMBDA: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] + // LAMBDA: [[NOT_MASTER]] + // LAMBDA: load i{{[0-9]+}}, i{{[0-9]+}}* [[G]], + // LAMBDA: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, + // LAMBDA: [[DONE]] + + // LAMBDA: call i32 @__kmpc_cancel_barrier( + g = 1; + // LAMBDA: call{{( x86_thiscallcc)?}} void [[INNER_LAMBDA:@.+]](%{{.+}}* + [&]() { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + g = 2; + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* +#pragma omp parallel copyin(g) + { + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + + // threadprivate_g = g; + // BLOCKS: call i8* @__kmpc_threadprivate_cached({{.+}} [[G]] + // BLOCKS: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} + // BLOCKS: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[G]] to i{{[0-9]+}}), %{{.+}} + // BLOCKS: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] + // BLOCKS: [[NOT_MASTER]] + // BLOCKS: load i{{[0-9]+}}, i{{[0-9]+}}* [[G]], + // BLOCKS: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, + // BLOCKS: [[DONE]] + + // BLOCKS: call i32 @__kmpc_cancel_barrier( + g = 1; + // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define {{.+}} void {{@.+}}(i8* + g = 2; + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: call i8* @__kmpc_threadprivate_cached({{.+}} [[G]] + // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: ret + }(); + } + }(); + return 0; +#else + S<float> test; + test = S<float>(); + static int t_var = 1122; + static int vec[] = {1, 2}; + static S<float> s_arr[] = {1, 2}; + static S<float> var(3); +#pragma omp threadprivate(t_var, vec, s_arr, var) +#pragma omp parallel copyin(t_var, vec, s_arr, var) + { + vec[0] = t_var; + s_arr[0] = var; + } +#pragma omp parallel copyin(t_var) + {} + return tmain<int>(); +#endif +} + +// CHECK-LABEL: @main +// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN:@.+]]([[S_FLOAT_TY]]* [[TEST]], [[S_FLOAT_TY]]* +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, {{%.+}}*)* [[MAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, {{%.+}}*)* [[MAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() +// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], + +// threadprivate_t_var = t_var; +// CHECK: call i8* @__kmpc_threadprivate_cached({{.+}} [[T_VAR]] +// CHECK: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} +// CHECK: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[T_VAR]] to i{{[0-9]+}}), %{{.+}} +// CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] +// CHECK: [[NOT_MASTER]] +// CHECK: load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR]], +// CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, + +// threadprivate_vec = vec; +// CHECK: call i8* @__kmpc_threadprivate_cached({{.+}} [[VEC]] +// CHECK: call void @llvm.memcpy{{.*}}(i8* %{{.+}}, i8* bitcast ([2 x i{{[0-9]+}}]* [[VEC]] to i8*), + +// threadprivate_s_arr = s_arr; +// CHECK: call i8* @__kmpc_threadprivate_cached({{.+}} [[S_ARR]] +// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* {{%.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] +// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] +// CHECK: [[S_ARR_BODY]] +// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}) +// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] + +// threadprivate_var = var; +// CHECK: call i8* @__kmpc_threadprivate_cached({{.+}} [[VAR]] +// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN]]([[S_FLOAT_TY]]* {{%.+}}, [[S_FLOAT_TY]]* {{.*}}[[VAR]]) +// CHECK: [[DONE]] + +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], + +// threadprivate_t_var = t_var; +// CHECK: call i8* @__kmpc_threadprivate_cached({{.+}} [[T_VAR]] +// CHECK: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} +// CHECK: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[T_VAR]] to i{{[0-9]+}}), %{{.+}} +// CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] +// CHECK: [[NOT_MASTER]] +// CHECK: load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR]], +// CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, +// CHECK: [[DONE]] + +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// CHECK: ret void + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN:@.+]]([[S_INT_TY]]* [[TEST]], [[S_INT_TY]]* +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, {{%.+}}*)* [[TMAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, {{%.+}}*)* [[TMAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], + +// threadprivate_t_var = t_var; +// CHECK: call i8* @__kmpc_threadprivate_cached({{.+}} [[TMAIN_T_VAR]] +// CHECK: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} +// CHECK: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[TMAIN_T_VAR]] to i{{[0-9]+}}), %{{.+}} +// CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] +// CHECK: [[NOT_MASTER]] +// CHECK: load i{{[0-9]+}}, i{{[0-9]+}}* [[TMAIN_T_VAR]], +// CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, + +// threadprivate_vec = vec; +// CHECK: call i8* @__kmpc_threadprivate_cached({{.+}} [[TMAIN_VEC]] +// CHECK: call void @llvm.memcpy{{.*}}(i8* %{{.+}}, i8* bitcast ([2 x i{{[0-9]+}}]* [[TMAIN_VEC]] to i8*), + +// threadprivate_s_arr = s_arr; +// CHECK: call i8* @__kmpc_threadprivate_cached({{.+}} [[TMAIN_S_ARR]] +// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* {{%.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] +// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] +// CHECK: [[S_ARR_BODY]] +// CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}) +// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] + +// threadprivate_var = var; +// CHECK: call i8* @__kmpc_threadprivate_cached({{.+}} [[TMAIN_VAR]] +// CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN]]([[S_INT_TY]]* {{%.+}}, [[S_INT_TY]]* {{.*}}[[TMAIN_VAR]]) +// CHECK: [[DONE]] + +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// CHECK: ret void + +// CHECK: define internal void [[TMAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], + +// threadprivate_t_var = t_var; +// CHECK: call i8* @__kmpc_threadprivate_cached({{.+}} [[TMAIN_T_VAR]] +// CHECK: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} +// CHECK: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[TMAIN_T_VAR]] to i{{[0-9]+}}), %{{.+}} +// CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] +// CHECK: [[NOT_MASTER]] +// CHECK: load i{{[0-9]+}}, i{{[0-9]+}}* [[TMAIN_T_VAR]], +// CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, +// CHECK: [[DONE]] + +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// CHECK: ret void + +#endif + diff --git a/test/OpenMP/parallel_copyin_messages.cpp b/test/OpenMP/parallel_copyin_messages.cpp index c1ce363b47..4a9fa2add4 100644 --- a/test/OpenMP/parallel_copyin_messages.cpp +++ b/test/OpenMP/parallel_copyin_messages.cpp @@ -20,17 +20,17 @@ public: S3():a(0) { } S3 &operator =(S3 &s3) { return *this; } }; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; S4(); - S4 &operator =(const S4 &s4); + S4 &operator =(const S4 &s4); // expected-note {{implicitly declared private here}} public: S4(int v):a(v) { } }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; S5():a(0) {} - S5 &operator =(const S5 &s5) { return *this; } + S5 &operator =(const S5 &s5) { return *this; } // expected-note {{implicitly declared private here}} public: S5(int v):a(v) { } }; @@ -40,11 +40,18 @@ public: static T s; }; +namespace A { +double x; +#pragma omp threadprivate(x) +} +namespace B { +using A::x; +} S2 k; S3 h; -S4 l(3); // expected-note {{'l' defined here}} -S5 m(4); // expected-note {{'m' defined here}} +S4 l(3); +S5 m(4); #pragma omp threadprivate(h, k, l, m) int main(int argc, char **argv) { @@ -55,12 +62,13 @@ int main(int argc, char **argv) { #pragma omp parallel copyin (k // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel copyin (h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel copyin (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} - #pragma omp parallel copyin (l) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}} + #pragma omp parallel copyin (l) // expected-error {{'operator=' is a private member of 'S4'}} #pragma omp parallel copyin (S1) // expected-error {{'S1' does not refer to a value}} #pragma omp parallel copyin (argv[1]) // expected-error {{expected variable name}} #pragma omp parallel copyin(i) // expected-error {{copyin variable must be threadprivate}} - #pragma omp parallel copyin(m) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}} + #pragma omp parallel copyin(m) // expected-error {{'operator=' is a private member of 'S5'}} #pragma omp parallel copyin(ST<int>::s) // expected-error {{copyin variable must be threadprivate}} + #pragma omp parallel copyin(B::x) foo(); return 0; diff --git a/test/OpenMP/parallel_firstprivate_codegen.cpp b/test/OpenMP/parallel_firstprivate_codegen.cpp index 7adf8e294c..25a0921d5a 100644 --- a/test/OpenMP/parallel_firstprivate_codegen.cpp +++ b/test/OpenMP/parallel_firstprivate_codegen.cpp @@ -45,6 +45,8 @@ T tmain() { vec[0] = t_var; s_arr[0] = var; } +#pragma omp parallel firstprivate(t_var) + {} return T(); } @@ -52,13 +54,13 @@ int main() { #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main - // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* - // LAMBDA: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) + // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) #pragma omp parallel firstprivate(g) { // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) @@ -68,13 +70,13 @@ int main() { // LAMBDA: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR]] // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]] - // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // LAMBDA: call i32 @__kmpc_cancel_barrier( g = 1; // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] - // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) + // LAMBDA: call{{( x86_thiscallcc)?}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], @@ -90,13 +92,13 @@ int main() { #elif defined(BLOCKS) // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, // BLOCKS-LABEL: @main - // BLOCKS: call void {{%.+}}(i8* + // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* - // BLOCKS: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) + // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) #pragma omp parallel firstprivate(g) { // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) @@ -106,14 +108,14 @@ int main() { // BLOCKS: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR]] // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]] - // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS: call i32 @__kmpc_cancel_barrier( g = 1; // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} - // BLOCKS: call void {{%.+}}(i8* + // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; @@ -136,6 +138,8 @@ int main() { vec[0] = t_var; s_arr[0] = var; } +#pragma omp parallel firstprivate(t_var) + {} return tmain<int>(); #endif } @@ -144,7 +148,7 @@ int main() { // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) // CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret @@ -161,20 +165,13 @@ int main() { // CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], // CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], -// CHECK: br label %[[VEC_PRIV_INIT:.+]] -// CHECK: [[VEC_PRIV_INIT]] // CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* // CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* // CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]], -// CHECK: br label %[[VEC_PRIV_INIT_END:.+]] -// CHECK: [[VEC_PRIV_INIT_END]] // CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 // CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_REF_PTR]], -// CHECK: br label %[[S_ARR_PRIV_INIT:.+]] -// CHECK: [[S_ARR_PRIV_INIT]] -// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[S_ARR_END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[S_ARR_BEGIN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_REF]] to [[S_FLOAT_TY]]* // CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 // CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] // CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] @@ -183,8 +180,6 @@ int main() { // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR:@.+]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] -// CHECK: br label %[[S_ARR_PRIV_INIT_END:.+]] -// CHECK: [[S_ARR_PRIV_INIT_END]] // CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 // CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_REF_PTR]], // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) @@ -200,7 +195,7 @@ int main() { // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) -// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // @@ -216,20 +211,13 @@ int main() { // CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], // CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], -// CHECK: br label %[[VEC_PRIV_INIT:.+]] -// CHECK: [[VEC_PRIV_INIT]] // CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* // CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* // CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]], -// CHECK: br label %[[VEC_PRIV_INIT_END:.+]] -// CHECK: [[VEC_PRIV_INIT_END]] // CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 // CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_REF_PTR]], -// CHECK: br label %[[S_ARR_PRIV_INIT:.+]] -// CHECK: [[S_ARR_PRIV_INIT]] -// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[S_ARR_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[S_ARR_BEGIN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_REF]] to [[S_INT_TY]]* // CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 // CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] // CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] @@ -238,8 +226,6 @@ int main() { // CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] -// CHECK: br label %[[S_ARR_PRIV_INIT_END:.+]] -// CHECK: [[S_ARR_PRIV_INIT_END]] // CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 // CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_REF_PTR]], // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) diff --git a/test/OpenMP/parallel_firstprivate_messages.cpp b/test/OpenMP/parallel_firstprivate_messages.cpp index 7d1e359350..fe534b4089 100644 --- a/test/OpenMP/parallel_firstprivate_messages.cpp +++ b/test/OpenMP/parallel_firstprivate_messages.cpp @@ -47,6 +47,14 @@ public: S3 h; #pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = { 0 }; @@ -70,7 +78,7 @@ int main(int argc, char **argv) { #pragma omp parallel firstprivate(S2::S2s) #pragma omp parallel firstprivate(S2::S2sc) #pragma omp parallel firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} - #pragma omp parallel firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + #pragma omp parallel firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} #pragma omp parallel private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}} foo(); #pragma omp parallel shared(i) diff --git a/test/OpenMP/parallel_for_codegen.cpp b/test/OpenMP/parallel_for_codegen.cpp new file mode 100644 index 0000000000..63ae11bea5 --- /dev/null +++ b/test/OpenMP/parallel_for_codegen.cpp @@ -0,0 +1,398 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp=libiomp5 -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +// CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* } +// CHECK-LABEL: define {{.*void}} @{{.*}}without_schedule_clause{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void without_schedule_clause(float *a, float *b, float *c, float *d) { + #pragma omp parallel for +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1) +// UB = min(UB, GlobalUB) +// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]] +// CHECK-NEXT: [[UBCMP:%.+]] = icmp sgt i32 [[UB]], 4571423 +// CHECK-NEXT: br i1 [[UBCMP]], label [[UB_TRUE:%[^,]+]], label [[UB_FALSE:%[^,]+]] +// CHECK: [[UBRESULT:%.+]] = phi i32 [ 4571423, [[UB_TRUE]] ], [ [[UBVAL:%[^,]+]], [[UB_FALSE]] ] +// CHECK-NEXT: store i32 [[UBRESULT]], i32* [[OMP_UB]] +// CHECK-NEXT: [[LB:%.+]] = load i32, i32* [[OMP_LB]] +// CHECK-NEXT: store i32 [[LB]], i32* [[OMP_IV:[^,]+]] +// Loop header +// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]] +// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]] +// CHECK-NEXT: [[CMP:%.+]] = icmp sle i32 [[IV]], [[UB]] +// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]] + for (int i = 33; i < 32000000; i += 7) { +// CHECK: [[LOOP1_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]] +// CHECK-NEXT: [[CALC_I_1:%.+]] = mul nsw i32 [[IV1_1]], 7 +// CHECK-NEXT: [[CALC_I_2:%.+]] = add nsw i32 33, [[CALC_I_1]] +// CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]] +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* {{%.+}} + a[i] = b[i] * c[i] * d[i]; +// CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}} +// CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1 +// CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]] +// CHECK-NEXT: br label %{{.+}} + } +// CHECK: [[LOOP1_END]] +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: ret void +} + +// CHECK-LABEL: define {{.*void}} @{{.*}}static_not_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void static_not_chunked(float *a, float *b, float *c, float *d) { + #pragma omp parallel for schedule(static) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1) +// UB = min(UB, GlobalUB) +// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]] +// CHECK-NEXT: [[UBCMP:%.+]] = icmp sgt i32 [[UB]], 4571423 +// CHECK-NEXT: br i1 [[UBCMP]], label [[UB_TRUE:%[^,]+]], label [[UB_FALSE:%[^,]+]] +// CHECK: [[UBRESULT:%.+]] = phi i32 [ 4571423, [[UB_TRUE]] ], [ [[UBVAL:%[^,]+]], [[UB_FALSE]] ] +// CHECK-NEXT: store i32 [[UBRESULT]], i32* [[OMP_UB]] +// CHECK-NEXT: [[LB:%.+]] = load i32, i32* [[OMP_LB]] +// CHECK-NEXT: store i32 [[LB]], i32* [[OMP_IV:[^,]+]] +// Loop header +// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]] +// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]] +// CHECK-NEXT: [[CMP:%.+]] = icmp sle i32 [[IV]], [[UB]] +// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]] + for (int i = 32000000; i > 33; i += -7) { +// CHECK: [[LOOP1_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]] +// CHECK-NEXT: [[CALC_I_1:%.+]] = mul nsw i32 [[IV1_1]], 7 +// CHECK-NEXT: [[CALC_I_2:%.+]] = sub nsw i32 32000000, [[CALC_I_1]] +// CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]] +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* {{%.+}} + a[i] = b[i] * c[i] * d[i]; +// CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}} +// CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1 +// CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]] +// CHECK-NEXT: br label %{{.+}} + } +// CHECK: [[LOOP1_END]] +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: ret void +} + +// CHECK-LABEL: define {{.*void}} @{{.*}}static_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void static_chunked(float *a, float *b, float *c, float *d) { + #pragma omp parallel for schedule(static, 5) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 33, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5) +// UB = min(UB, GlobalUB) +// CHECK: [[UB:%.+]] = load i32, i32* [[OMP_UB]] +// CHECK-NEXT: [[UBCMP:%.+]] = icmp ugt i32 [[UB]], 16908288 +// CHECK-NEXT: br i1 [[UBCMP]], label [[UB_TRUE:%[^,]+]], label [[UB_FALSE:%[^,]+]] +// CHECK: [[UBRESULT:%.+]] = phi i32 [ 16908288, [[UB_TRUE]] ], [ [[UBVAL:%[^,]+]], [[UB_FALSE]] ] +// CHECK-NEXT: store i32 [[UBRESULT]], i32* [[OMP_UB]] +// CHECK-NEXT: [[LB:%.+]] = load i32, i32* [[OMP_LB]] +// CHECK-NEXT: store i32 [[LB]], i32* [[OMP_IV:[^,]+]] + +// Outer loop header +// CHECK: [[O_IV:%.+]] = load i32, i32* [[OMP_IV]] +// CHECK-NEXT: [[O_UB:%.+]] = load i32, i32* [[OMP_UB]] +// CHECK-NEXT: [[O_CMP:%.+]] = icmp ule i32 [[O_IV]], [[O_UB]] +// CHECK-NEXT: br i1 [[O_CMP]], label %[[O_LOOP1_BODY:[^,]+]], label %[[O_LOOP1_END:[^,]+]] + +// Loop header +// CHECK: [[O_LOOP1_BODY]] +// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]] +// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]] +// CHECK-NEXT: [[CMP:%.+]] = icmp ule i32 [[IV]], [[UB]] +// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]] + for (unsigned i = 131071; i <= 2147483647; i += 127) { +// CHECK: [[LOOP1_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]] +// CHECK-NEXT: [[CALC_I_1:%.+]] = mul i32 [[IV1_1]], 127 +// CHECK-NEXT: [[CALC_I_2:%.+]] = add i32 131071, [[CALC_I_1]] +// CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]] +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* {{%.+}} + a[i] = b[i] * c[i] * d[i]; +// CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}} +// CHECK-NEXT: [[ADD1_2:%.+]] = add i32 [[IV1_2]], 1 +// CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]] +// CHECK-NEXT: br label %{{.+}} + } +// CHECK: [[LOOP1_END]] +// Update the counters, adding stride +// CHECK: [[LB:%.+]] = load i32, i32* [[OMP_LB]] +// CHECK-NEXT: [[ST:%.+]] = load i32, i32* [[OMP_ST]] +// CHECK-NEXT: [[ADD_LB:%.+]] = add i32 [[LB]], [[ST]] +// CHECK-NEXT: store i32 [[ADD_LB]], i32* [[OMP_LB]] +// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]] +// CHECK-NEXT: [[ST:%.+]] = load i32, i32* [[OMP_ST]] +// CHECK-NEXT: [[ADD_UB:%.+]] = add i32 [[UB]], [[ST]] +// CHECK-NEXT: store i32 [[ADD_UB]], i32* [[OMP_UB]] + +// CHECK: [[O_LOOP1_END]] +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: ret void +} + +// CHECK-LABEL: define {{.*void}} @{{.*}}dynamic1{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void dynamic1(float *a, float *b, float *c, float *d) { + #pragma omp parallel for schedule(dynamic) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 35, i64 0, i64 16908287, i64 1, i64 1) +// +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]]) +// CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 +// CHECK-NEXT: br i1 [[O_CMP]], label %[[O_LOOP1_BODY:[^,]+]], label %[[O_LOOP1_END:[^,]+]] + +// Loop header +// CHECK: [[O_LOOP1_BODY]] +// CHECK: [[LB:%.+]] = load i64, i64* [[OMP_LB]] +// CHECK-NEXT: store i64 [[LB]], i64* [[OMP_IV:[^,]+]] +// CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]] + +// CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]] +// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]] +// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]] + for (unsigned long long i = 131071; i < 2147483647; i += 127) { +// CHECK: [[LOOP1_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV1_1:%.+]] = load i64, i64* [[OMP_IV]] +// CHECK-NEXT: [[CALC_I_1:%.+]] = mul i64 [[IV1_1]], 127 +// CHECK-NEXT: [[CALC_I_2:%.+]] = add i64 131071, [[CALC_I_1]] +// CHECK-NEXT: store i64 [[CALC_I_2]], i64* [[LC_I:.+]] +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* {{%.+}} + a[i] = b[i] * c[i] * d[i]; +// CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}} +// CHECK-NEXT: [[ADD1_2:%.+]] = add i64 [[IV1_2]], 1 +// CHECK-NEXT: store i64 [[ADD1_2]], i64* [[OMP_IV]] +// CHECK-NEXT: br label %{{.+}} + } +// CHECK: [[LOOP1_END]] +// CHECK: [[O_LOOP1_END]] +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: ret void +} + +// CHECK-LABEL: define {{.*void}} @{{.*}}guided7{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void guided7(float *a, float *b, float *c, float *d) { + #pragma omp parallel for schedule(guided, 7) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 36, i64 0, i64 16908287, i64 1, i64 7) +// +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]]) +// CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 +// CHECK-NEXT: br i1 [[O_CMP]], label %[[O_LOOP1_BODY:[^,]+]], label %[[O_LOOP1_END:[^,]+]] + +// Loop header +// CHECK: [[O_LOOP1_BODY]] +// CHECK: [[LB:%.+]] = load i64, i64* [[OMP_LB]] +// CHECK-NEXT: store i64 [[LB]], i64* [[OMP_IV:[^,]+]] +// CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]] + +// CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]] +// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]] +// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]] + for (unsigned long long i = 131071; i < 2147483647; i += 127) { +// CHECK: [[LOOP1_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV1_1:%.+]] = load i64, i64* [[OMP_IV]] +// CHECK-NEXT: [[CALC_I_1:%.+]] = mul i64 [[IV1_1]], 127 +// CHECK-NEXT: [[CALC_I_2:%.+]] = add i64 131071, [[CALC_I_1]] +// CHECK-NEXT: store i64 [[CALC_I_2]], i64* [[LC_I:.+]] +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* {{%.+}} + a[i] = b[i] * c[i] * d[i]; +// CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}} +// CHECK-NEXT: [[ADD1_2:%.+]] = add i64 [[IV1_2]], 1 +// CHECK-NEXT: store i64 [[ADD1_2]], i64* [[OMP_IV]] +// CHECK-NEXT: br label %{{.+}} + } +// CHECK: [[LOOP1_END]] +// CHECK: [[O_LOOP1_END]] +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: ret void +} + +// CHECK-LABEL: define {{.*void}} @{{.*}}test_auto{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void test_auto(float *a, float *b, float *c, float *d) { + unsigned int x = 0; + unsigned int y = 0; + #pragma omp parallel for schedule(auto) collapse(2) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call void @__kmpc_dispatch_init_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 38, i64 0, i64 [[LAST_ITER:%[^,]+]], i64 1, i64 1) +// +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]]) +// CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 +// CHECK-NEXT: br i1 [[O_CMP]], label %[[O_LOOP1_BODY:[^,]+]], label %[[O_LOOP1_END:[^,]+]] + +// Loop header +// CHECK: [[O_LOOP1_BODY]] +// CHECK: [[LB:%.+]] = load i64, i64* [[OMP_LB]] +// CHECK-NEXT: store i64 [[LB]], i64* [[OMP_IV:[^,]+]] +// CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]] + +// CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]] +// CHECK-NEXT: [[CMP:%.+]] = icmp sle i64 [[IV]], [[UB]] +// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]] +// FIXME: When the iteration count of some nested loop is not a known constant, +// we should pre-calculate it, like we do for the total number of iterations! + for (char i = static_cast<char>(y); i <= '9'; ++i) + for (x = 11; x > 0; --x) { +// CHECK: [[LOOP1_BODY]] +// Start of body: indices are calculated from IV: +// CHECK: store i8 {{%[^,]+}}, i8* {{%[^,]+}} +// CHECK: store i32 {{%[^,]+}}, i32* {{%[^,]+}} +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* {{%.+}} + a[i] = b[i] * c[i] * d[i]; +// CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}} +// CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i64 [[IV1_2]], 1 +// CHECK-NEXT: store i64 [[ADD1_2]], i64* [[OMP_IV]] +// CHECK-NEXT: br label %{{.+}} + } +// CHECK: [[LOOP1_END]] +// CHECK: [[O_LOOP1_END]] +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: ret void +} + +// CHECK-LABEL: define {{.*void}} @{{.*}}runtime{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void runtime(float *a, float *b, float *c, float *d) { + int x = 0; + #pragma omp parallel for collapse(2) schedule(runtime) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call void @__kmpc_dispatch_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 37, i32 0, i32 199, i32 1, i32 1) +// +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]]) +// CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 +// CHECK-NEXT: br i1 [[O_CMP]], label %[[O_LOOP1_BODY:[^,]+]], label %[[O_LOOP1_END:[^,]+]] + +// Loop header +// CHECK: [[O_LOOP1_BODY]] +// CHECK: [[LB:%.+]] = load i32, i32* [[OMP_LB]] +// CHECK-NEXT: store i32 [[LB]], i32* [[OMP_IV:[^,]+]] +// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]] + +// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]] +// CHECK-NEXT: [[CMP:%.+]] = icmp sle i32 [[IV]], [[UB]] +// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]] + for (unsigned char i = '0' ; i <= '9'; ++i) + for (x = -10; x < 10; ++x) { +// CHECK: [[LOOP1_BODY]] +// Start of body: indices are calculated from IV: +// CHECK: store i8 {{%[^,]+}}, i8* {{%[^,]+}} +// CHECK: store i32 {{%[^,]+}}, i32* {{%[^,]+}} +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* {{%.+}} + a[i] = b[i] * c[i] * d[i]; +// CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}} +// CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1 +// CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]] +// CHECK-NEXT: br label %{{.+}} + } +// CHECK: [[LOOP1_END]] +// CHECK: [[O_LOOP1_END]] +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: ret void +} + +// TERM_DEBUG-LABEL: foo +int foo() {return 0;}; + +// TERM_DEBUG-LABEL: parallel_for +void parallel_for(float *a) { +#pragma omp parallel for schedule(static, 5) + // TERM_DEBUG-NOT: __kmpc_global_thread_num + // TERM_DEBUG: call void @__kmpc_for_static_init_4u({{.+}}), !dbg [[DBG_LOC_START:![0-9]+]] + // TERM_DEBUG: invoke i32 {{.*}}foo{{.*}}() + // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], + // TERM_DEBUG-NOT: __kmpc_global_thread_num + // TERM_DEBUG: call void @__kmpc_for_static_fini({{.+}}), !dbg [[DBG_LOC_END:![0-9]+]] + // TERM_DEBUG: call {{.+}} @__kmpc_cancel_barrier({{.+}}), !dbg [[DBG_LOC_CANCEL:![0-9]+]] + // TERM_DEBUG: [[TERM_LPAD]] + // TERM_DEBUG: call void @__clang_call_terminate + // TERM_DEBUG: unreachable + for (unsigned i = 131071; i <= 2147483647; i += 127) + a[i] += foo(); +} +// Check source line corresponds to "#pragma omp parallel for schedule(static, 5)" above: +// TERM_DEBUG-DAG: [[DBG_LOC_START]] = !MDLocation(line: [[@LINE-4]], +// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !MDLocation(line: [[@LINE-16]], +// TERM_DEBUG-DAG: [[DBG_LOC_CANCEL]] = !MDLocation(line: [[@LINE-17]], + +#endif // HEADER + diff --git a/test/OpenMP/parallel_for_copyin_messages.cpp b/test/OpenMP/parallel_for_copyin_messages.cpp index 2ebc2ded73..f1368e98b8 100644 --- a/test/OpenMP/parallel_for_copyin_messages.cpp +++ b/test/OpenMP/parallel_for_copyin_messages.cpp @@ -22,18 +22,18 @@ public: S3() : a(0) {} S3 &operator=(S3 &s3) { return *this; } }; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; S4(); - S4 &operator=(const S4 &s4); + S4 &operator=(const S4 &s4); // expected-note {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; S5() : a(0) {} - S5 &operator=(const S5 &s5) { return *this; } + S5 &operator=(const S5 &s5) { return *this; } // expected-note {{implicitly declared private here}} public: S5(int v) : a(v) {} @@ -46,10 +46,18 @@ public: S2 k; S3 h; -S4 l(3); // expected-note {{'l' defined here}} -S5 m(4); // expected-note {{'m' defined here}} +S4 l(3); +S5 m(4); #pragma omp threadprivate(h, k, l, m) +namespace A { +double x; +#pragma omp threadprivate(x) +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { int i; #pragma omp parallel for copyin // expected-error {{expected '(' after 'copyin'}} @@ -70,7 +78,7 @@ int main(int argc, char **argv) { #pragma omp parallel for copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for copyin(l) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel for copyin(l) // expected-error {{'operator=' is a private member of 'S4'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for copyin(S1) // expected-error {{'S1' does not refer to a value}} @@ -82,10 +90,10 @@ int main(int argc, char **argv) { #pragma omp parallel for copyin(i) // expected-error {{copyin variable must be threadprivate}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for copyin(m) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel for copyin(m) // expected-error {{'operator=' is a private member of 'S5'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for copyin(ST < int > ::s) // expected-error {{copyin variable must be threadprivate}} +#pragma omp parallel for copyin(ST<int>::s, B::x) // expected-error {{copyin variable must be threadprivate}} for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/parallel_for_firstprivate_messages.cpp b/test/OpenMP/parallel_for_firstprivate_messages.cpp index b4958733de..37239bc205 100644 --- a/test/OpenMP/parallel_for_firstprivate_messages.cpp +++ b/test/OpenMP/parallel_for_firstprivate_messages.cpp @@ -137,6 +137,14 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; @@ -207,7 +215,7 @@ int main(int argc, char **argv) { #pragma omp parallel for firstprivate(m) // OK for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} +#pragma omp parallel for firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} diff --git a/test/OpenMP/parallel_for_lastprivate_messages.cpp b/test/OpenMP/parallel_for_lastprivate_messages.cpp index 915cbf7c23..6f0945a860 100644 --- a/test/OpenMP/parallel_for_lastprivate_messages.cpp +++ b/test/OpenMP/parallel_for_lastprivate_messages.cpp @@ -15,15 +15,17 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} + S2 &operator=(const S2 &); + const S2 &operator=(const S2 &) const; static float S2s; static const float S2sc; }; const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} const S2 b; const S2 ba[5]; -class S3 { // expected-note 2 {{'S3' declared here}} +class S3 { int a; - S3 &operator=(const S3 &s3); + S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}} public: S3() : a(0) {} @@ -32,17 +34,17 @@ public: const S3 c; // expected-note {{global variable is predetermined as shared}} const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} extern const int f; // expected-note {{global variable is predetermined as shared}} -class S4 { // expected-note 3 {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note 3 {{implicitly declared private here}} S4(const S4 &s4); public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(const S5 &s5) : a(s5.a) {} @@ -62,8 +64,8 @@ S3 h; template <class I, class C> int foomain(int argc, char **argv) { - I e(4); // expected-note {{'e' defined here}} - I g(5); // expected-note {{'g' defined here}} + I e(4); + I g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}} @@ -96,7 +98,7 @@ int foomain(int argc, char **argv) { #pragma omp parallel for lastprivate(argv[1]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; -#pragma omp parallel for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp parallel for lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} @@ -126,12 +128,20 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} - S3 m; // expected-note 2 {{'m' defined here}} + S4 e(4); + S5 g(5); + S3 m; S6 n(2); int i; int &j = i; // expected-note {{'j' defined here}} @@ -190,13 +200,13 @@ int main(int argc, char **argv) { #pragma omp parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel for'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp parallel for lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel for lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} +#pragma omp parallel for lastprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be lastprivate}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}} @@ -216,7 +226,7 @@ int main(int argc, char **argv) { #pragma omp parallel for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel for firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for lastprivate(n) firstprivate(n) // OK diff --git a/test/OpenMP/parallel_for_private_messages.cpp b/test/OpenMP/parallel_for_private_messages.cpp index 31b84588de..8d0ba629b8 100644 --- a/test/OpenMP/parallel_for_private_messages.cpp +++ b/test/OpenMP/parallel_for_private_messages.cpp @@ -108,6 +108,14 @@ int foomain(I argc, C **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { S4 e(4); S5 g(5); @@ -146,7 +154,7 @@ int main(int argc, char **argv) { #pragma omp parallel for private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (int k = 0; k < argc; ++k) ++k; -#pragma omp parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}} +#pragma omp parallel for private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp parallel for'}} diff --git a/test/OpenMP/parallel_for_reduction_messages.cpp b/test/OpenMP/parallel_for_reduction_messages.cpp index 676b86fa59..1f6075761d 100644 --- a/test/OpenMP/parallel_for_reduction_messages.cpp +++ b/test/OpenMP/parallel_for_reduction_messages.cpp @@ -11,7 +11,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+=(const S2 &arg) { return (*this); } + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} public: S2() : a(0) {} @@ -28,17 +28,17 @@ class S3 { public: S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} - S3 operator+=(const S3 &arg1) { return arg1; } + S3 operator+(const S3 &arg1) { return arg1; } }; -int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } S3 c; // expected-note 2 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} S4(const S4 &s4); - S4 &operator+=(const S4 &arg) { return (*this); } + S4 &operator+(const S4 &arg) { return (*this); } public: S4(int v) : a(v) {} @@ -46,26 +46,26 @@ public: S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} S5(const S5 &s5) : a(s5.a) {} - S5 &operator+=(const S5 &arg); + S5 &operator+(const S5 &arg); public: S5(int v) : a(v) {} }; -class S6 { +class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} int a; public: S6() : a(6) {} operator int() { return 6; } -} o; // expected-note 2 {{'o' defined here}} +} o; S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} template <class T> // expected-note {{declared here}} -T tmain(T argc) { // expected-note 2 {{'argc' defined here}} +T tmain(T argc) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -74,7 +74,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} - T fl; // expected-note {{'fl' defined here}} + T fl; #pragma omp parallel for reduction // expected-error {{expected '(' after 'reduction'}} for (int i = 0; i < 10; ++i) foo(); @@ -96,10 +96,10 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} @@ -114,7 +114,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} @@ -132,7 +132,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp parallel for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(&& : S2::S2s) @@ -144,7 +144,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp parallel for reduction(+ : o) // expected-error {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} @@ -177,18 +177,26 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} return T(); } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note 2 {{'j' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; // expected-note {{'q' defined here}} - float fl; // expected-note {{'fl' defined here}} + float fl; #pragma omp parallel for reduction // expected-error {{expected '(' after 'reduction'}} for (int i = 0; i < 10; ++i) foo(); @@ -228,7 +236,7 @@ int main(int argc, char **argv) { #pragma omp parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} @@ -246,7 +254,7 @@ int main(int argc, char **argv) { #pragma omp parallel for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(&& : S2::S2s) @@ -255,13 +263,13 @@ int main(int argc, char **argv) { #pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} +#pragma omp parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} +#pragma omp parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp parallel for reduction(+ : o) // expected-error {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} diff --git a/test/OpenMP/parallel_for_simd_copyin_messages.cpp b/test/OpenMP/parallel_for_simd_copyin_messages.cpp index e0b7e6354e..9ddd92d417 100644 --- a/test/OpenMP/parallel_for_simd_copyin_messages.cpp +++ b/test/OpenMP/parallel_for_simd_copyin_messages.cpp @@ -22,18 +22,18 @@ public: S3() : a(0) {} S3 &operator=(S3 &s3) { return *this; } }; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; S4(); - S4 &operator=(const S4 &s4); + S4 &operator=(const S4 &s4); // expected-note {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; S5() : a(0) {} - S5 &operator=(const S5 &s5) { return *this; } + S5 &operator=(const S5 &s5) { return *this; } // expected-note {{implicitly declared private here}} public: S5(int v) : a(v) {} @@ -46,10 +46,18 @@ public: S2 k; S3 h; -S4 l(3); // expected-note {{'l' defined here}} -S5 m(4); // expected-note {{'m' defined here}} +S4 l(3); +S5 m(4); #pragma omp threadprivate(h, k, l, m) +namespace A { +double x; +#pragma omp threadprivate(x) +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { int i; #pragma omp parallel for simd copyin // expected-error {{expected '(' after 'copyin'}} @@ -70,7 +78,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd copyin(l) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel for simd copyin(l) // expected-error {{'operator=' is a private member of 'S4'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd copyin(S1) // expected-error {{'S1' does not refer to a value}} @@ -82,10 +90,10 @@ int main(int argc, char **argv) { #pragma omp parallel for simd copyin(i) // expected-error {{copyin variable must be threadprivate}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd copyin(m) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel for simd copyin(m) // expected-error {{'operator=' is a private member of 'S5'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd copyin(ST < int > ::s) // expected-error {{copyin variable must be threadprivate}} +#pragma omp parallel for simd copyin(ST < int > ::s, B::x) // expected-error {{copyin variable must be threadprivate}} for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp index 876d422e63..ef74e3c664 100644 --- a/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp +++ b/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp @@ -136,6 +136,14 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; @@ -206,7 +214,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd firstprivate(m) // OK for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} +#pragma omp parallel for simd firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} diff --git a/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp index 3d53259e85..64d6ccc7ad 100644 --- a/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp +++ b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp @@ -15,15 +15,16 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} + const S2 &operator=(const S2 &) const; static float S2s; static const float S2sc; }; const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} const S2 b; const S2 ba[5]; -class S3 { // expected-note 2 {{'S3' declared here}} +class S3 { int a; - S3 &operator=(const S3 &s3); + S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}} public: S3() : a(0) {} @@ -32,17 +33,17 @@ public: const S3 c; // expected-note {{global variable is predetermined as shared}} const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} extern const int f; // expected-note {{global variable is predetermined as shared}} -class S4 { // expected-note 3 {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note 3 {{implicitly declared private here}} S4(const S4 &s4); public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(const S5 &s5) : a(s5.a) {} @@ -62,8 +63,8 @@ S3 h; template <class I, class C> int foomain(int argc, char **argv) { - I e(4); // expected-note {{'e' defined here}} - I g(5); // expected-note {{'g' defined here}} + I e(4); + I g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} @@ -96,7 +97,7 @@ int foomain(int argc, char **argv) { #pragma omp parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; -#pragma omp parallel for simd lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp parallel for simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} @@ -126,12 +127,20 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} - S3 m; // expected-note 2 {{'m' defined here}} + S4 e(4); + S5 g(5); + S3 m; S6 n(2); int i; int &j = i; // expected-note {{'j' defined here}} @@ -190,13 +199,13 @@ int main(int argc, char **argv) { #pragma omp parallel for simd safelen(5) for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp parallel for simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel for simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} +#pragma omp parallel for simd lastprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be lastprivate}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}} @@ -216,7 +225,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel for simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd lastprivate(n) firstprivate(n) // OK diff --git a/test/OpenMP/parallel_for_simd_linear_messages.cpp b/test/OpenMP/parallel_for_simd_linear_messages.cpp index 3918de2681..7dcaca0c3e 100644 --- a/test/OpenMP/parallel_for_simd_linear_messages.cpp +++ b/test/OpenMP/parallel_for_simd_linear_messages.cpp @@ -148,6 +148,14 @@ template<class I, class C> int foomain(I argc, C **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace C { +using A::x; +} + int main(int argc, char **argv) { double darr[100]; // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} @@ -185,7 +193,7 @@ int main(int argc, char **argv) { // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}} #pragma omp parallel for simd linear(e, g) for (int k = 0; k < argc; ++k) ++k; - #pragma omp parallel for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + #pragma omp parallel for simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel { diff --git a/test/OpenMP/parallel_for_simd_private_messages.cpp b/test/OpenMP/parallel_for_simd_private_messages.cpp index 67d8813186..f2719d92b7 100644 --- a/test/OpenMP/parallel_for_simd_private_messages.cpp +++ b/test/OpenMP/parallel_for_simd_private_messages.cpp @@ -108,6 +108,14 @@ int foomain(I argc, C **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { S4 e(4); S5 g(5); @@ -146,7 +154,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (int k = 0; k < argc; ++k) ++k; -#pragma omp parallel for simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} +#pragma omp parallel for simd private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for simd nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp parallel for simd'}} diff --git a/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/test/OpenMP/parallel_for_simd_reduction_messages.cpp index 2395cbd686..f92a9cc42c 100644 --- a/test/OpenMP/parallel_for_simd_reduction_messages.cpp +++ b/test/OpenMP/parallel_for_simd_reduction_messages.cpp @@ -11,7 +11,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+=(const S2 &arg) { return (*this); } + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} public: S2() : a(0) {} @@ -28,17 +28,17 @@ class S3 { public: S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} - S3 operator+=(const S3 &arg1) { return arg1; } + S3 operator+(const S3 &arg1) { return arg1; } }; -int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } S3 c; // expected-note 2 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} S4(const S4 &s4); - S4 &operator+=(const S4 &arg) { return (*this); } + S4 &operator+(const S4 &arg) { return (*this); } public: S4(int v) : a(v) {} @@ -46,26 +46,26 @@ public: S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} S5(const S5 &s5) : a(s5.a) {} - S5 &operator+=(const S5 &arg); + S5 &operator+(const S5 &arg); public: S5(int v) : a(v) {} }; -class S6 { +class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} int a; public: S6() : a(6) {} operator int() { return 6; } -} o; // expected-note 2 {{'o' defined here}} +} o; S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} template <class T> // expected-note {{declared here}} -T tmain(T argc) { // expected-note 2 {{'argc' defined here}} +T tmain(T argc) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -74,7 +74,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} - T fl; // expected-note {{'fl' defined here}} + T fl; #pragma omp parallel for simd reduction // expected-error {{expected '(' after 'reduction'}} for (int i = 0; i < 10; ++i) foo(); @@ -96,10 +96,10 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel for simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} @@ -114,7 +114,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} @@ -132,7 +132,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(&& : S2::S2s) @@ -144,7 +144,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp parallel for simd reduction(+ : o) // expected-error {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} @@ -177,18 +177,26 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} return T(); } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note 2 {{'j' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; // expected-note {{'q' defined here}} - float fl; // expected-note {{'fl' defined here}} + float fl; #pragma omp parallel for simd reduction // expected-error {{expected '(' after 'reduction'}} for (int i = 0; i < 10; ++i) foo(); @@ -228,7 +236,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} @@ -246,7 +254,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(&& : S2::S2s) @@ -255,13 +263,13 @@ int main(int argc, char **argv) { #pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} +#pragma omp parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} +#pragma omp parallel for simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp parallel for simd reduction(+ : o) // expected-error {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} diff --git a/test/OpenMP/parallel_if_codegen.cpp b/test/OpenMP/parallel_if_codegen.cpp index 256f410bfb..7f67dce966 100644 --- a/test/OpenMP/parallel_if_codegen.cpp +++ b/test/OpenMP/parallel_if_codegen.cpp @@ -16,7 +16,7 @@ int Arg; // CHECK-LABEL: define void @{{.+}}gtid_test void gtid_test() { -// CHECK: call void {{.+}}* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, {{.+}}* [[GTID_TEST_REGION1:@.+]] to void +// CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, {{.+}}* [[GTID_TEST_REGION1:@.+]] to void #pragma omp parallel #pragma omp parallel if (false) gtid_test(); diff --git a/test/OpenMP/parallel_num_threads_codegen.cpp b/test/OpenMP/parallel_num_threads_codegen.cpp index f4f7038b04..4026d88d5e 100644 --- a/test/OpenMP/parallel_num_threads_codegen.cpp +++ b/test/OpenMP/parallel_num_threads_codegen.cpp @@ -48,11 +48,11 @@ int main() { // CHECK: [[S_CHAR_OP:%.+]] = invoke{{.*}} i8 [[S_TY_CHAR_OP:@.+]]([[S_TY]]* [[S_ADDR]]) // CHECK: store i8 [[S_CHAR_OP]], i8* [[A_ADDR]] // CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 2) -// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: call void {{.*}} @__kmpc_fork_call( // CHECK: [[A_VAL:%.+]] = load i8, i8* [[A_ADDR]] // CHECK: [[RES:%.+]] = sext i8 [[A_VAL]] to i32 // CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 [[RES]]) -// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: call void {{.*}} @__kmpc_fork_call( // CHECK: invoke{{.*}} [[INT_TY:i[0-9]+]] [[TMAIN_CHAR_5:@.+]]() // CHECK: invoke{{.*}} [[INT_TY]] [[TMAIN_S_1:@.+]]() // CHECK: call {{.*}} [[S_TY_DESTR:@.+]]([[S_TY]]* [[S_ADDR]]) @@ -62,22 +62,22 @@ int main() { // CHECK: define{{.*}} [[INT_TY]] [[TMAIN_CHAR_5]]() // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEF_LOC_2]]) // CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 5) -// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: call void {{.*}} @__kmpc_fork_call( // CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 23) -// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: call void {{.*}} @__kmpc_fork_call( // CHECK: ret [[INT_TY]] 0 // CHECK-NEXT: } // CHECK: define{{.*}} [[INT_TY]] [[TMAIN_S_1]]() // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEF_LOC_2]]) // CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 1) -// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: call void {{.*}} @__kmpc_fork_call( // CHECK: call {{.*}} [[S_TY_CONSTR]]([[S_TY]]* [[S_TEMP:%.+]], [[INTPTR_T_TY]] [[INTPTR_T_TY_ATTR]]23) // CHECK: [[S_CHAR_OP:%.+]] = invoke{{.*}} i8 [[S_TY_CHAR_OP]]([[S_TY]]* [[S_TEMP]]) // CHECK: [[RES:%.+]] = sext {{.*}}i8 [[S_CHAR_OP]] to i32 // CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 [[RES]]) // CHECK: call {{.*}} [[S_TY_DESTR]]([[S_TY]]* [[S_TEMP]]) -// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: call void {{.*}} @__kmpc_fork_call( // CHECK: ret [[INT_TY]] 0 // CHECK: } diff --git a/test/OpenMP/parallel_private_codegen.cpp b/test/OpenMP/parallel_private_codegen.cpp index 7094e4f1be..0744c8c61e 100644 --- a/test/OpenMP/parallel_private_codegen.cpp +++ b/test/OpenMP/parallel_private_codegen.cpp @@ -22,7 +22,6 @@ volatile int g = 1212; // CHECK: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* } // CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } // CHECK: [[CAP_TMAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } -// CHECK: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* template <typename T> T tmain() { S<T> test; @@ -42,24 +41,23 @@ int main() { #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main - // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* - // LAMBDA: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) + // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) #pragma omp parallel private(g) { // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - // LAMBDA: call i32 @__kmpc_cancel_barrier( g = 1; // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] - // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) + // LAMBDA: call{{( x86_thiscallcc)?}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], @@ -75,25 +73,24 @@ int main() { #elif defined(BLOCKS) // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, // BLOCKS-LABEL: @main - // BLOCKS: call void {{%.+}}(i8* + // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* - // BLOCKS: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) + // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) #pragma omp parallel private(g) { // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - // BLOCKS: call i32 @__kmpc_cancel_barrier( g = 1; // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} - // BLOCKS: call void {{%.+}}(i8* + // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; @@ -124,7 +121,7 @@ int main() { // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) // CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void // CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret @@ -143,9 +140,6 @@ int main() { // CHECK-NOT: [[T_VAR_PRIV]] // CHECK-NOT: [[VEC_PRIV]] // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) -// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] -// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* // CHECK: ret void @@ -153,7 +147,7 @@ int main() { // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) -// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void // CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // @@ -171,9 +165,6 @@ int main() { // CHECK-NOT: [[T_VAR_PRIV]] // CHECK-NOT: [[VEC_PRIV]] // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]]) -// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] -// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* // CHECK: ret void diff --git a/test/OpenMP/parallel_private_messages.cpp b/test/OpenMP/parallel_private_messages.cpp index 74949ba343..850b403175 100644 --- a/test/OpenMP/parallel_private_messages.cpp +++ b/test/OpenMP/parallel_private_messages.cpp @@ -41,6 +41,14 @@ public: int threadvar; #pragma omp threadprivate(threadvar) // expected-note {{defined as threadprivate or thread local}} +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}} @@ -63,7 +71,7 @@ int main(int argc, char **argv) { #pragma omp parallel private(da) // expected-error {{shared variable cannot be private}} #pragma omp parallel private(S2::S2s) #pragma omp parallel private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} - #pragma omp parallel private(threadvar) // expected-error {{threadprivate or thread local variable cannot be private}} + #pragma omp parallel private(threadvar, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} #pragma omp parallel shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} foo(); #pragma omp parallel firstprivate(i) private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}} diff --git a/test/OpenMP/parallel_reduction_codegen.cpp b/test/OpenMP/parallel_reduction_codegen.cpp new file mode 100644 index 0000000000..0c00e26718 --- /dev/null +++ b/test/OpenMP/parallel_reduction_codegen.cpp @@ -0,0 +1,697 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +volatile int g = 1212; + +template <class T> +struct S { + T f; + S(T a) : f(a + g) {} + S() : f(g) {} + operator T() { return T(); } + S &operator&(const S &) { return *this; } + ~S() {} +}; + +// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } +// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, float*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float* } +// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*, [[S_INT_TY]]*, i{{[0-9]+}}* } +// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* +// CHECK-DAG: [[REDUCTION_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8* +// CHECK-DAG: [[REDUCTION_LOCK:@.+]] = common global [8 x i32] zeroinitializer + +template <typename T> +T tmain() { + T t; + S<T> test; + T t_var = T(), t_var1; + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> var(3), var1; +#pragma omp parallel reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1) + { + vec[0] = t_var; + s_arr[0] = var; + } + return T(); +} + +int main() { +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, + // LAMBDA-LABEL: @main + // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] + // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* + // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) +#pragma omp parallel reduction(+:g) + { + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + + // Reduction list for runtime. + // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x i8*], + + // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // LAMBDA: [[ARG:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_REF]] + // LAMBDA: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR]] + // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + g = 1; + // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) + + // LAMBDA: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i32 0, i32 0 + // LAMBDA: [[BITCAST:%.+]] = bitcast i32* [[G_PRIVATE_ADDR]] to i8* + // LAMBDA: store i8* [[BITCAST]], i8** [[G_PRIV_REF]], + // LAMBDA: call i32 @__kmpc_reduce_nowait( + // LAMBDA: switch i32 %{{.+}}, label %[[REDUCTION_DONE:.+]] [ + // LAMBDA: i32 1, label %[[CASE1:.+]] + // LAMBDA: i32 2, label %[[CASE2:.+]] + // LAMBDA: [[CASE1]] + // LAMBDA: [[G_VAL:%.+]] = load i32, i32* [[G_REF]] + // LAMBDA: [[G_PRIV_VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]] + // LAMBDA: [[ADD:%.+]] = add nsw i32 [[G_VAL]], [[G_PRIV_VAL]] + // LAMBDA: store i32 [[ADD]], i32* [[G_REF]] + // LAMBDA: call void @__kmpc_end_reduce_nowait( + // LAMBDA: br label %[[REDUCTION_DONE]] + // LAMBDA: [[CASE2]] + // LAMBDA: [[G_PRIV_VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]] + // LAMBDA: atomicrmw add i32* [[G_REF]], i32 [[G_PRIV_VAL]] monotonic + // LAMBDA: br label %[[REDUCTION_DONE]] + // LAMBDA: [[REDUCTION_DONE]] + // LAMBDA: ret void + [&]() { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + g = 2; + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] + // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] + // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* + // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) +#pragma omp parallel reduction(-:g) + { + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + + // Reduction list for runtime. + // BLOCKS: [[RED_LIST:%.+]] = alloca [1 x i8*], + + // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // BLOCKS: [[ARG:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_REF]] + // BLOCKS: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR]] + // BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + g = 1; + // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + + // BLOCKS: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i32 0, i32 0 + // BLOCKS: [[BITCAST:%.+]] = bitcast i32* [[G_PRIVATE_ADDR]] to i8* + // BLOCKS: store i8* [[BITCAST]], i8** [[G_PRIV_REF]], + // BLOCKS: call i32 @__kmpc_reduce_nowait( + // BLOCKS: switch i32 %{{.+}}, label %[[REDUCTION_DONE:.+]] [ + // BLOCKS: i32 1, label %[[CASE1:.+]] + // BLOCKS: i32 2, label %[[CASE2:.+]] + // BLOCKS: [[CASE1]] + // BLOCKS: [[G_VAL:%.+]] = load i32, i32* [[G_REF]] + // BLOCKS: [[G_PRIV_VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]] + // BLOCKS: [[ADD:%.+]] = add nsw i32 [[G_VAL]], [[G_PRIV_VAL]] + // BLOCKS: store i32 [[ADD]], i32* [[G_REF]] + // BLOCKS: call void @__kmpc_end_reduce_nowait( + // BLOCKS: br label %[[REDUCTION_DONE]] + // BLOCKS: [[CASE2]] + // BLOCKS: [[G_PRIV_VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]] + // BLOCKS: atomicrmw add i32* [[G_REF]], i32 [[G_PRIV_VAL]] monotonic + // BLOCKS: br label %[[REDUCTION_DONE]] + // BLOCKS: [[REDUCTION_DONE]] + // BLOCKS: ret void + ^{ + // BLOCKS: define {{.+}} void {{@.+}}(i8* + g = 2; + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: ret + }(); + } + }(); + return 0; +#else + S<float> test; + float t_var = 0, t_var1; + int vec[] = {1, 2}; + S<float> s_arr[] = {1, 2}; + S<float> var(3), var1; +#pragma omp parallel reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1) + { + vec[0] = t_var; + s_arr[0] = var; + } + return tmain<int>(); +#endif +} + +// CHECK: define {{.*}}i{{[0-9]+}} @main() +// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) +// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() +// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: [[T_VAR_PRIV:%.+]] = alloca float, +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[T_VAR1_PRIV:%.+]] = alloca float, + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} +// CHECK: [[T_VAR_REF:%.+]] = load float*, float** [[T_VAR_PTR_REF]], +// For + reduction operation initial value of private variable is 0. +// CHECK: store float 0.0{{.+}}, float* [[T_VAR_PRIV]], + +// CHECK: [[VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} +// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PTR_REF:%.+]], +// For & reduction operation initial value of private variable is ones in all bits. +// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) + +// CHECK: [[VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} +// CHECK: [[VAR1_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PTR_REF:%.+]], +// For && reduction operation initial value of private variable is 1.0. +// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR1_PRIV]]) + +// CHECK: [[T_VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} +// CHECK: [[T_VAR1_REF:%.+]] = load float*, float** [[T_VAR1_PTR_REF]], +// For min reduction operation initial value of private variable is largest repesentable value. +// CHECK: store float 0x47EFFFFFE0000000, float* [[T_VAR1_PRIV]], + +// Skip checks for internal operations. + +// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]}; + +// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 0 +// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]], +// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 1 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]], +// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 2 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]], +// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 3 +// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR1_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]], + +// res = __kmpc_reduce_nowait(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>); + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8* +// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 4, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]]) + +// switch(res) +// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [ +// CHECK: i32 1, label %[[CASE1:.+]] +// CHECK: i32 2, label %[[CASE2:.+]] +// CHECK: ] + +// case 1: +// t_var += t_var_reduction; +// CHECK: [[T_VAR_VAL:%.+]] = load float, float* [[T_VAR_REF]], +// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load float, float* [[T_VAR_PRIV]], +// CHECK: [[UP:%.+]] = fadd float [[T_VAR_VAL]], [[T_VAR_PRIV_VAL]] +// CHECK: store float [[UP]], float* [[T_VAR_REF]], + +// var = var.operator &(var_reduction); +// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_PRIV]]) +// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_REF]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) + +// var1 = var1.operator &&(var1_reduction); +// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_REF]]) +// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 +// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]] +// CHECK: [[TRUE]] +// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_PRIV]]) +// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 +// CHECK: br i1 [[VAR1_REDUCTION_BOOL]], label %[[TRUE2:.+]], label %[[FALSE2:.+]] +// CHECK: [[TRUE2]] +// CHECK: br label %[[END2:.+]] +// CHECK: [[FALSE2]] +// CHECK: br label %[[END2]] +// CHECK: [[END2]] +// CHECK: [[COND_LVALUE:%.+]] = phi [[S_FLOAT_TY]]* [ [[VAR1_REF]], %[[TRUE2]] ], [ [[VAR1_PRIV]], %[[FALSE2]] ] +// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_REF]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) + +// t_var1 = min(t_var1, t_var1_reduction); +// CHECK: [[T_VAR1_VAL:%.+]] = load float, float* [[T_VAR1_REF]], +// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load float, float* [[T_VAR1_PRIV]], +// CHECK: [[CMP:%.+]] = fcmp olt float [[T_VAR1_VAL]], [[T_VAR1_PRIV_VAL]] +// CHECK: [[UP:%.+]] = uitofp i1 [[CMP]] to float +// CHECK: store float [[UP]], float* [[T_VAR1_REF]], + +// __kmpc_end_reduce_nowait(<loc>, <gtid>, &<lock>); +// CHECK: call void @__kmpc_end_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]]) + +// break; +// CHECK: br label %[[RED_DONE]] + +// case 2: +// t_var += t_var_reduction; +// CHECK: load float, float* [[T_VAR_PRIV]] +// CHECK: [[T_VAR_REF_INT:%.+]] = bitcast float* [[T_VAR_REF]] to i32* +// CHECK: load atomic i32, i32* [[T_VAR_REF_INT]] monotonic, +// CHECK: [[OLD1:%.+]] = bitcast i32 %{{.+}} to float +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[ORIG_OLD:%.+]] = phi float [ [[OLD1]], %{{.+}} ], [ [[OLD2:%.+]], %[[CONT]] ] +// CHECK: [[UP:%.+]] = fadd float +// CHECK: [[ORIG_OLD_INT:%.+]] = bitcast float [[ORIG_OLD]] to i32 +// CHECK: [[UP_INT:%.+]] = bitcast float [[UP]] to i32 +// CHECK: [[T_VAR_REF_INT:%.+]] = bitcast float* [[T_VAR_REF]] to i32* +// CHECK: [[RES:%.+]] = cmpxchg i32* [[T_VAR_REF_INT]], i32 [[ORIG_OLD_INT]], i32 [[UP_INT]] monotonic monotonic +// CHECK: [[OLD_VAL_INT:%.+]] = extractvalue { i32, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1 +// CHECK: [[OLD2]] = bitcast i32 [[OLD_VAL_INT]] to float +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[ATOMIC_DONE:.+]], label %[[CONT]] +// CHECK: [[ATOMIC_DONE]] + +// var = var.operator &(var_reduction); +// CHECK: call void @__kmpc_critical( +// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_PRIV]]) +// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_REF]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) +// CHECK: call void @__kmpc_end_critical( + +// var1 = var1.operator &&(var1_reduction); +// CHECK: call void @__kmpc_critical( +// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_REF]]) +// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 +// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]] +// CHECK: [[TRUE]] +// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_PRIV]]) +// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 +// CHECK: br i1 [[VAR1_REDUCTION_BOOL]], label %[[TRUE2:.+]], label %[[FALSE2:.+]] +// CHECK: [[TRUE2]] +// CHECK: br label %[[END2:.+]] +// CHECK: [[FALSE2]] +// CHECK: br label %[[END2]] +// CHECK: [[END2]] +// CHECK: [[COND_LVALUE:%.+]] = phi [[S_FLOAT_TY]]* [ [[VAR1_REF]], %[[TRUE2]] ], [ [[VAR1_PRIV]], %[[FALSE2]] ] +// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_REF]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) +// CHECK: call void @__kmpc_end_critical( + +// t_var1 = min(t_var1, t_var1_reduction); +// CHECK: load float, float* [[T_VAR1_PRIV]] +// CHECK: [[T_VAR1_REF_INT:%.+]] = bitcast float* [[T_VAR1_REF]] to i32* +// CHECK: load atomic i32, i32* [[T_VAR1_REF_INT]] monotonic, +// CHECK: [[OLD1:%.+]] = bitcast i32 %{{.+}} to float +// CHECK: br label %[[CONT:.+]] +// CHECK: [[CONT]] +// CHECK: [[ORIG_OLD:%.+]] = phi float [ [[OLD1]], %{{.+}} ], [ [[OLD2:%.+]], %[[CONT]] ] +// CHECK: [[CMP:%.+]] = fcmp olt float +// CHECK: [[UP:%.+]] = uitofp i1 [[CMP]] to float +// CHECK: [[ORIG_OLD_INT:%.+]] = bitcast float [[ORIG_OLD]] to i32 +// CHECK: [[UP_INT:%.+]] = bitcast float [[UP]] to i32 +// CHECK: [[T_VAR1_REF_INT:%.+]] = bitcast float* [[T_VAR1_REF]] to i32* +// CHECK: [[RES:%.+]] = cmpxchg i32* [[T_VAR1_REF_INT]], i32 [[ORIG_OLD_INT]], i32 [[UP_INT]] monotonic monotonic +// CHECK: [[OLD_VAL_INT:%.+]] = extractvalue { i32, i1 } [[RES]], 0 +// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1 +// CHECK: [[OLD2]] = bitcast i32 [[OLD_VAL_INT]] to float +// CHECK: br i1 [[SUCCESS_FAIL]], label %[[ATOMIC_DONE:.+]], label %[[CONT]] +// CHECK: [[ATOMIC_DONE]] + +// break; +// CHECK: br label %[[RED_DONE]] +// CHECK: [[RED_DONE]] +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) + +// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* +// CHECK: ret void + +// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { +// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); +// ... +// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1], +// *(Type<n>-1*)rhs[<n>-1]); +// } +// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*) +// t_var_lhs = (float*)lhs[0]; +// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i32 0, i32 0 +// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]], +// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to float* +// t_var_rhs = (float*)rhs[0]; +// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i32 0, i32 0 +// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]], +// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to float* + +// var_lhs = (S<float>*)lhs[1]; +// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 1 +// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]], +// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_FLOAT_TY]]* +// var_rhs = (S<float>*)rhs[1]; +// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 1 +// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]], +// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_FLOAT_TY]]* + +// var1_lhs = (S<float>*)lhs[2]; +// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 2 +// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]], +// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_FLOAT_TY]]* +// var1_rhs = (S<float>*)rhs[2]; +// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 2 +// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]], +// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_FLOAT_TY]]* + +// t_var1_lhs = (float*)lhs[3]; +// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 3 +// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]], +// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to float* +// t_var1_rhs = (float*)rhs[3]; +// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 3 +// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]], +// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to float* + +// t_var_lhs += t_var_rhs; +// CHECK: [[T_VAR_LHS_VAL:%.+]] = load float, float* [[T_VAR_LHS]], +// CHECK: [[T_VAR_RHS_VAL:%.+]] = load float, float* [[T_VAR_RHS]], +// CHECK: [[UP:%.+]] = fadd float [[T_VAR_LHS_VAL]], [[T_VAR_RHS_VAL]] +// CHECK: store float [[UP]], float* [[T_VAR_LHS]], + +// var_lhs = var_lhs.operator &(var_rhs); +// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_LHS]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_RHS]]) +// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_LHS]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) + +// var1_lhs = var1_lhs.operator &&(var1_rhs); +// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_LHS]]) +// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 +// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]] +// CHECK: [[TRUE]] +// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_RHS]]) +// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 +// CHECK: br i1 [[VAR1_REDUCTION_BOOL]], label %[[TRUE2:.+]], label %[[FALSE2:.+]] +// CHECK: [[TRUE2]] +// CHECK: br label %[[END2:.+]] +// CHECK: [[FALSE2]] +// CHECK: br label %[[END2]] +// CHECK: [[END2]] +// CHECK: [[COND_LVALUE:%.+]] = phi [[S_FLOAT_TY]]* [ [[VAR1_LHS]], %[[TRUE2]] ], [ [[VAR1_RHS]], %[[FALSE2]] ] +// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_LHS]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) + +// t_var1_lhs = min(t_var1_lhs, t_var1_rhs); +// CHECK: [[T_VAR1_LHS_VAL:%.+]] = load float, float* [[T_VAR1_LHS]], +// CHECK: [[T_VAR1_RHS_VAL:%.+]] = load float, float* [[T_VAR1_RHS]], +// CHECK: [[CMP:%.+]] = fcmp olt float [[T_VAR1_LHS_VAL]], [[T_VAR1_RHS_VAL]] +// CHECK: [[UP:%.+]] = uitofp i1 [[CMP]] to float +// CHECK: store float [[UP]], float* [[T_VAR1_LHS]], +// CHECK: ret void + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) +// CHECK: %{{.+}} = bitcast [[CAP_TMAIN_TY]]* +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[T_VAR1_PRIV:%.+]] = alloca i{{[0-9]+}}, + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], +// For + reduction operation initial value of private variable is 0. +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[T_VAR_PRIV]], + +// CHECK: [[VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} +// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]], +// For & reduction operation initial value of private variable is ones in all bits. +// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]]) + +// CHECK: [[VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} +// CHECK: [[VAR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]], +// For && reduction operation initial value of private variable is 1.0. +// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR1_PRIV]]) + +// CHECK: [[T_VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} +// CHECK: [[T_VAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR1_PTR_REF]], +// For min reduction operation initial value of private variable is largest repesentable value. +// CHECK: store i{{[0-9]+}} 2147483647, i{{[0-9]+}}* [[T_VAR1_PRIV]], + +// Skip checks for internal operations. + +// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]}; + +// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 0 +// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]], +// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 1 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]], +// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 2 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]], +// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 3 +// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR1_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]], + +// res = __kmpc_reduce_nowait(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>); + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8* +// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 4, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]]) + +// switch(res) +// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [ +// CHECK: i32 1, label %[[CASE1:.+]] +// CHECK: i32 2, label %[[CASE2:.+]] +// CHECK: ] + +// case 1: +// t_var += t_var_reduction; +// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], +// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]], +// CHECK: [[UP:%.+]] = add nsw i{{[0-9]+}} [[T_VAR_VAL]], [[T_VAR_PRIV_VAL]] +// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR_REF]], + +// var = var.operator &(var_reduction); +// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* dereferenceable(4) [[VAR_PRIV]]) +// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_REF]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) + +// var1 = var1.operator &&(var1_reduction); +// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_REF]]) +// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 +// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]] +// CHECK: [[TRUE]] +// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_PRIV]]) +// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 +// CHECK: br i1 [[VAR1_REDUCTION_BOOL]], label %[[TRUE2:.+]], label %[[FALSE2:.+]] +// CHECK: [[TRUE2]] +// CHECK: br label %[[END2:.+]] +// CHECK: [[FALSE2]] +// CHECK: br label %[[END2]] +// CHECK: [[END2]] +// CHECK: [[COND_LVALUE:%.+]] = phi [[S_INT_TY]]* [ [[VAR1_REF]], %[[TRUE2]] ], [ [[VAR1_PRIV]], %[[FALSE2]] ] +// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_REF]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) + +// t_var1 = min(t_var1, t_var1_reduction); +// CHECK: [[T_VAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_REF]], +// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_PRIV]], +// CHECK: [[CMP:%.+]] = icmp slt i{{[0-9]+}} [[T_VAR1_VAL]], [[T_VAR1_PRIV_VAL]] +// CHECK: [[UP:%.+]] = zext i1 [[CMP]] to i{{[0-9]+}} +// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR1_REF]], + +// __kmpc_end_reduce_nowait(<loc>, <gtid>, &<lock>); +// CHECK: call void @__kmpc_end_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]]) + +// break; +// CHECK: br label %[[RED_DONE]] + +// case 2: +// t_var += t_var_reduction; +// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]] +// CHECK: atomicrmw add i32* [[T_VAR_REF]], i32 [[T_VAR_PRIV_VAL]] monotonic + +// var = var.operator &(var_reduction); +// CHECK: call void @__kmpc_critical( +// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* dereferenceable(4) [[VAR_PRIV]]) +// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_REF]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) +// CHECK: call void @__kmpc_end_critical( + +// var1 = var1.operator &&(var1_reduction); +// CHECK: call void @__kmpc_critical( +// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_REF]]) +// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 +// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]] +// CHECK: [[TRUE]] +// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_PRIV]]) +// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 +// CHECK: br i1 [[VAR1_REDUCTION_BOOL]], label %[[TRUE2:.+]], label %[[FALSE2:.+]] +// CHECK: [[TRUE2]] +// CHECK: br label %[[END2:.+]] +// CHECK: [[FALSE2]] +// CHECK: br label %[[END2]] +// CHECK: [[END2]] +// CHECK: [[COND_LVALUE:%.+]] = phi [[S_INT_TY]]* [ [[VAR1_REF]], %[[TRUE2]] ], [ [[VAR1_PRIV]], %[[FALSE2]] ] +// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_REF]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) +// CHECK: call void @__kmpc_end_critical( + +// t_var1 = min(t_var1, t_var1_reduction); +// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_PRIV]] +// CHECK: atomicrmw min i32* [[T_VAR1_REF]], i32 [[T_VAR1_PRIV_VAL]] monotonic + +// break; +// CHECK: br label %[[RED_DONE]] +// CHECK: [[RED_DONE]] +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) + +// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* +// CHECK: ret void + +// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { +// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); +// ... +// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1], +// *(Type<n>-1*)rhs[<n>-1]); +// } +// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*) +// t_var_lhs = (i{{[0-9]+}}*)lhs[0]; +// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i32 0, i32 0 +// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]], +// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to i{{[0-9]+}}* +// t_var_rhs = (i{{[0-9]+}}*)rhs[0]; +// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i32 0, i32 0 +// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]], +// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to i{{[0-9]+}}* + +// var_lhs = (S<i{{[0-9]+}}>*)lhs[1]; +// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 1 +// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]], +// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_INT_TY]]* +// var_rhs = (S<i{{[0-9]+}}>*)rhs[1]; +// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 1 +// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]], +// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_INT_TY]]* + +// var1_lhs = (S<i{{[0-9]+}}>*)lhs[2]; +// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 2 +// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]], +// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_INT_TY]]* +// var1_rhs = (S<i{{[0-9]+}}>*)rhs[2]; +// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 2 +// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]], +// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_INT_TY]]* + +// t_var1_lhs = (i{{[0-9]+}}*)lhs[3]; +// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 3 +// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]], +// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to i{{[0-9]+}}* +// t_var1_rhs = (i{{[0-9]+}}*)rhs[3]; +// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 3 +// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]], +// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to i{{[0-9]+}}* + +// t_var_lhs += t_var_rhs; +// CHECK: [[T_VAR_LHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_LHS]], +// CHECK: [[T_VAR_RHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_RHS]], +// CHECK: [[UP:%.+]] = add nsw i{{[0-9]+}} [[T_VAR_LHS_VAL]], [[T_VAR_RHS_VAL]] +// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR_LHS]], + +// var_lhs = var_lhs.operator &(var_rhs); +// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_LHS]], [[S_INT_TY]]* dereferenceable(4) [[VAR_RHS]]) +// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_LHS]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) + +// var1_lhs = var1_lhs.operator &&(var1_rhs); +// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_LHS]]) +// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 +// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]] +// CHECK: [[TRUE]] +// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_RHS]]) +// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 +// CHECK: br i1 [[VAR1_REDUCTION_BOOL]], label %[[TRUE2:.+]], label %[[FALSE2:.+]] +// CHECK: [[TRUE2]] +// CHECK: br label %[[END2:.+]] +// CHECK: [[FALSE2]] +// CHECK: br label %[[END2]] +// CHECK: [[END2]] +// CHECK: [[COND_LVALUE:%.+]] = phi [[S_INT_TY]]* [ [[VAR1_LHS]], %[[TRUE2]] ], [ [[VAR1_RHS]], %[[FALSE2]] ] +// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_LHS]] to i8* +// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) + +// t_var1_lhs = min(t_var1_lhs, t_var1_rhs); +// CHECK: [[T_VAR1_LHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_LHS]], +// CHECK: [[T_VAR1_RHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_RHS]], +// CHECK: [[CMP:%.+]] = icmp slt i{{[0-9]+}} [[T_VAR1_LHS_VAL]], [[T_VAR1_RHS_VAL]] +// CHECK: [[UP:%.+]] = zext i1 [[CMP]] to i{{[0-9]+}} +// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR1_LHS]], +// CHECK: ret void + +#endif + diff --git a/test/OpenMP/parallel_reduction_messages.cpp b/test/OpenMP/parallel_reduction_messages.cpp index 46bc7a58a8..f6883d280b 100644 --- a/test/OpenMP/parallel_reduction_messages.cpp +++ b/test/OpenMP/parallel_reduction_messages.cpp @@ -11,7 +11,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+=(const S2 &arg) { return (*this); } + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} public: S2() : a(0) {} @@ -28,17 +28,17 @@ class S3 { public: S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} - S3 operator+=(const S3 &arg1) { return arg1; } + S3 operator+(const S3 &arg1) { return arg1; } }; -int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } S3 c; // expected-note 2 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} S4(const S4 &s4); - S4 &operator+=(const S4 &arg) { return (*this); } + S4 &operator+(const S4 &arg) { return (*this); } public: S4(int v) : a(v) {} @@ -46,26 +46,26 @@ public: S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} S5(const S5 &s5) : a(s5.a) {} - S5 &operator+=(const S5 &arg); + S5 &operator+(const S5 &arg); public: S5(int v) : a(v) {} }; -class S6 { +class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} int a; public: S6() : a(6) {} operator int() { return 6; } -} o; // expected-note 2 {{'o' defined here}} +} o; S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} template <class T> // expected-note {{declared here}} -T tmain(T argc) { // expected-note 2 {{'argc' defined here}} +T tmain(T argc) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -74,7 +74,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} - T fl; // expected-note {{'fl' defined here}} + T fl; #pragma omp parallel reduction // expected-error {{expected '(' after 'reduction'}} foo(); #pragma omp parallel reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}} @@ -89,9 +89,9 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} foo(); #pragma omp parallel reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} foo(); -#pragma omp parallel reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); -#pragma omp parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp parallel reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} foo(); @@ -101,7 +101,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} foo(); #pragma omp parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}} foo(); -#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} foo(); #pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} foo(); @@ -113,7 +113,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} foo(); #pragma omp parallel reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} foo(); -#pragma omp parallel reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp parallel reduction(&& : S2::S2s) foo(); @@ -121,7 +121,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} foo(); #pragma omp parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} foo(); -#pragma omp parallel reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp parallel reduction(+ : o) // expected-error {{no viable overloaded '='}} foo(); #pragma omp parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} foo(); @@ -150,18 +150,26 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} return T(); } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note 2 {{'j' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; // expected-note {{'q' defined here}} - float fl; // expected-note {{'fl' defined here}} + float fl; #pragma omp parallel reduction // expected-error {{expected '(' after 'reduction'}} foo(); #pragma omp parallel reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}} @@ -188,7 +196,7 @@ int main(int argc, char **argv) { foo(); #pragma omp parallel reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} foo(); -#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} foo(); #pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} foo(); @@ -200,17 +208,17 @@ int main(int argc, char **argv) { foo(); #pragma omp parallel reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} foo(); -#pragma omp parallel reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp parallel reduction(&& : S2::S2s) foo(); #pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} foo(); -#pragma omp parallel reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} +#pragma omp parallel reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} foo(); -#pragma omp parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} +#pragma omp parallel reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} foo(); -#pragma omp parallel reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp parallel reduction(+ : o) // expected-error {{no viable overloaded '='}} foo(); #pragma omp parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} foo(); diff --git a/test/OpenMP/parallel_sections_codegen.cpp b/test/OpenMP/parallel_sections_codegen.cpp new file mode 100644 index 0000000000..89ed37eaa4 --- /dev/null +++ b/test/OpenMP/parallel_sections_codegen.cpp @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -emit-llvm -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -o - %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -include-pch %t -fsyntax-only -verify %s -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-llvm -o - | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER +// CHECK: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* +// CHECK-LABEL: foo +void foo() {}; +// CHECK-LABEL: bar +void bar() {}; + +template <class T> +T tmain() { +#pragma omp parallel sections + { + foo(); + } + return T(); +} + +// CHECK-LABEL: @main +int main() { +// CHECK: call void (%{{.+}}*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK-LABEL: } +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], +#pragma omp parallel sections + { +// CHECK: store i32 0, i32* [[LB_PTR:%.+]], +// CHECK: store i32 1, i32* [[UB_PTR:%.+]], +// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], +// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], +// CHECK: call void @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_PTR:%.+]], i32* [[LB_PTR]], i32* [[UB_PTR]], i32* [[STRIDE_PTR:%.+]], i32 1, i32 1) +// <<UB = min(UB, GlobalUB);>> +// CHECK: [[UB:%.+]] = load i32, i32* [[UB_PTR]] +// CHECK: [[CMP:%.+]] = icmp slt i32 [[UB]], 1 +// CHECK: [[MIN_UB_GLOBALUB:%.+]] = select i1 [[CMP]], i32 [[UB]], i32 1 +// CHECK: store i32 [[MIN_UB_GLOBALUB]], i32* [[UB_PTR]] +// <<IV = LB;>> +// CHECK: [[LB:%.+]] = load i32, i32* [[LB_PTR]] +// CHECK: store i32 [[LB]], i32* [[IV_PTR:%.+]] +// CHECK: br label %[[INNER_FOR_COND:.+]] +// CHECK: [[INNER_FOR_COND]] +// <<IV <= UB?>> +// CHECK: [[IV:%.+]] = load i32, i32* [[IV_PTR]] +// CHECK: [[UB:%.+]] = load i32, i32* [[UB_PTR]] +// CHECK: [[CMP:%.+]] = icmp sle i32 [[IV]], [[UB]] +// CHECK: br i1 [[CMP]], label %[[INNER_LOOP_BODY:.+]], label %[[INNER_LOOP_END:.+]] +// CHECK: [[INNER_LOOP_BODY]] +// <<TRUE>> - > <BODY> +// CHECK: [[IV:%.+]] = load i32, i32* [[IV_PTR]] +// CHECK: switch i32 [[IV]], label %[[SECTIONS_EXIT:.+]] [ +// CHECK-NEXT: i32 0, label %[[SECTIONS_CASE0:.+]] +// CHECK-NEXT: i32 1, label %[[SECTIONS_CASE1:.+]] +#pragma omp section +// CHECK: [[SECTIONS_CASE0]] +// CHECK-NEXT: invoke void @{{.*}}foo{{.*}}() +// CHECK: br label %[[SECTIONS_EXIT]] + foo(); +#pragma omp section +// CHECK: [[SECTIONS_CASE1]] +// CHECK-NEXT: invoke void @{{.*}}bar{{.*}}() +// CHECK: br label %[[SECTIONS_EXIT]] + bar(); +// CHECK: [[SECTIONS_EXIT]] +// <<++IV;>> +// CHECK: [[IV:%.+]] = load i32, i32* [[IV_PTR]] +// CHECK-NEXT: [[INC:%.+]] = add nsw i32 [[IV]], 1 +// CHECK-NEXT: store i32 [[INC]], i32* [[IV_PTR]] +// CHECK-NEXT: br label %[[INNER_FOR_COND]] +// CHECK: [[INNER_LOOP_END]] + } +// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], + return tmain<int>(); +} + +// CHECK-LABEL: tmain +// CHECK: call void {{.*}} @__kmpc_fork_call( +// CHECK-NOT: __kmpc_global_thread_num +// CHECK: [[RES:%.+]] = call i32 @__kmpc_single( +// CHECK-NEXT: [[BOOLRES:%.+]] = icmp ne i32 [[RES]], 0 +// CHECK-NEXT: br i1 [[BOOLRES]], label %[[THEN:.+]], label %[[END:.+]] +// CHECK: [[THEN]] +// CHECK-NEXT: invoke void @{{.*}}foo{{.*}}() +// CHECK-NEXT: unwind label %[[TERM_LPAD:.+]] +// CHECK: call void @__kmpc_end_single( +// CHECK-NEXT: br label %[[END]] +// CHECK: [[END]] +// CHECK-NEXT: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], +// CHECK-NEXT: ret +// CHECK: [[TERM_LPAD]] +// CHECK: call void @__clang_call_terminate(i8* +// CHECK-NEXT: unreachable + +#endif diff --git a/test/OpenMP/parallel_sections_copyin_messages.cpp b/test/OpenMP/parallel_sections_copyin_messages.cpp index 500417e113..d76e580c95 100644 --- a/test/OpenMP/parallel_sections_copyin_messages.cpp +++ b/test/OpenMP/parallel_sections_copyin_messages.cpp @@ -22,18 +22,18 @@ public: S3() : a(0) {} S3 &operator=(S3 &s3) { return *this; } }; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; S4(); - S4 &operator=(const S4 &s4); + S4 &operator=(const S4 &s4); // expected-note {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; S5() : a(0) {} - S5 &operator=(const S5 &s5) { return *this; } + S5 &operator=(const S5 &s5) { return *this; } // expected-note {{implicitly declared private here}} public: S5(int v) : a(v) {} @@ -46,10 +46,18 @@ public: S2 k; S3 h; -S4 l(3); // expected-note {{'l' defined here}} -S5 m(4); // expected-note {{'m' defined here}} +S4 l(3); +S5 m(4); #pragma omp threadprivate(h, k, l, m) +namespace A { +double x; +#pragma omp threadprivate(x) +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { int i; #pragma omp parallel sections copyin // expected-error {{expected '(' after 'copyin'}} @@ -76,7 +84,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections copyin(l) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel sections copyin(l) // expected-error {{'operator=' is a private member of 'S4'}} { foo(); } @@ -92,11 +100,11 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections copyin(m) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel sections copyin(m) // expected-error {{'operator=' is a private member of 'S5'}} { foo(); } -#pragma omp parallel sections copyin(ST < int > ::s) // expected-error {{copyin variable must be threadprivate}} +#pragma omp parallel sections copyin(ST < int > ::s, B::x) // expected-error {{copyin variable must be threadprivate}} { foo(); } diff --git a/test/OpenMP/parallel_sections_firstprivate_messages.cpp b/test/OpenMP/parallel_sections_firstprivate_messages.cpp index 2d27b1a600..23ae12888f 100644 --- a/test/OpenMP/parallel_sections_firstprivate_messages.cpp +++ b/test/OpenMP/parallel_sections_firstprivate_messages.cpp @@ -155,6 +155,14 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; @@ -245,7 +253,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} +#pragma omp parallel sections firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} { foo(); } diff --git a/test/OpenMP/parallel_sections_lastprivate_messages.cpp b/test/OpenMP/parallel_sections_lastprivate_messages.cpp index 6d790e4669..067a5979d1 100644 --- a/test/OpenMP/parallel_sections_lastprivate_messages.cpp +++ b/test/OpenMP/parallel_sections_lastprivate_messages.cpp @@ -15,15 +15,16 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} + const S2 &operator=(const S2 &) const; static float S2s; static const float S2sc; }; const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} const S2 b; const S2 ba[5]; -class S3 { // expected-note 2 {{'S3' declared here}} +class S3 { int a; - S3 &operator=(const S3 &s3); + S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}} public: S3() : a(0) {} @@ -32,17 +33,17 @@ public: const S3 c; // expected-note {{global variable is predetermined as shared}} const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} extern const int f; // expected-note {{global variable is predetermined as shared}} -class S4 { // expected-note 3 {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note 3 {{implicitly declared private here}} S4(const S4 &s4); public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(const S5 &s5) : a(s5.a) {} @@ -62,8 +63,8 @@ S3 h; template <class I, class C> int foomain(int argc, char **argv) { - I e(4); // expected-note {{'e' defined here}} - I g(5); // expected-note {{'g' defined here}} + I e(4); + I g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel sections lastprivate // expected-error {{expected '(' after 'lastprivate'}} @@ -106,7 +107,7 @@ int foomain(int argc, char **argv) { { foo(); } -#pragma omp parallel sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp parallel sections lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} { foo(); } @@ -141,12 +142,20 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} - S3 m; // expected-note 2 {{'m' defined here}} + S4 e(4); + S5 g(5); + S3 m; S6 n(2); int i; int &j = i; // expected-note {{'j' defined here}} @@ -223,15 +232,15 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp parallel sections lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} { foo(); } -#pragma omp parallel sections lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel sections lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} { foo(); } -#pragma omp parallel sections lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} +#pragma omp parallel sections lastprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be lastprivate}} { foo(); } @@ -257,7 +266,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp parallel sections firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} { foo(); } diff --git a/test/OpenMP/parallel_sections_private_messages.cpp b/test/OpenMP/parallel_sections_private_messages.cpp index e0b7488e51..47c904dea7 100644 --- a/test/OpenMP/parallel_sections_private_messages.cpp +++ b/test/OpenMP/parallel_sections_private_messages.cpp @@ -123,6 +123,14 @@ int foomain(I argc, C **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { S4 e(4); S5 g(5); @@ -172,7 +180,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections private(h) // expected-error {{threadprivate or thread local variable cannot be private}} +#pragma omp parallel sections private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} { foo(); } diff --git a/test/OpenMP/parallel_sections_reduction_messages.cpp b/test/OpenMP/parallel_sections_reduction_messages.cpp index 68f494f0fd..d152f49d0d 100644 --- a/test/OpenMP/parallel_sections_reduction_messages.cpp +++ b/test/OpenMP/parallel_sections_reduction_messages.cpp @@ -11,7 +11,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+=(const S2 &arg) { return (*this); } + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} public: S2() : a(0) {} @@ -28,17 +28,17 @@ class S3 { public: S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} - S3 operator+=(const S3 &arg1) { return arg1; } + S3 operator+(const S3 &arg1) { return arg1; } }; -int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } S3 c; // expected-note 2 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} S4(const S4 &s4); - S4 &operator+=(const S4 &arg) { return (*this); } + S4 &operator+(const S4 &arg) { return (*this); } public: S4(int v) : a(v) {} @@ -46,26 +46,26 @@ public: S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} S5(const S5 &s5) : a(s5.a) {} - S5 &operator+=(const S5 &arg); + S5 &operator+(const S5 &arg); public: S5(int v) : a(v) {} }; -class S6 { +class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} int a; public: S6() : a(6) {} operator int() { return 6; } -} o; // expected-note 2 {{'o' defined here}} +} o; S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} template <class T> // expected-note {{declared here}} -T tmain(T argc) { // expected-note 2 {{'argc' defined here}} +T tmain(T argc) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -74,7 +74,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} - T fl; // expected-note {{'fl' defined here}} + T fl; #pragma omp parallel sections reduction // expected-error {{expected '(' after 'reduction'}} { foo(); @@ -103,11 +103,11 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} { foo(); } -#pragma omp parallel sections reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel sections reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} { foo(); } -#pragma omp parallel sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} { foo(); } @@ -127,7 +127,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} { foo(); } -#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} { foo(); } @@ -151,7 +151,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} { foo(); } -#pragma omp parallel sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel sections reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} { foo(); } @@ -167,7 +167,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} { foo(); } -#pragma omp parallel sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp parallel sections reduction(+ : o) // expected-error {{no viable overloaded '='}} { foo(); } @@ -208,18 +208,26 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} return T(); } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note 2 {{'j' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; // expected-note {{'q' defined here}} - float fl; // expected-note {{'fl' defined here}} + float fl; #pragma omp parallel sections reduction // expected-error {{expected '(' after 'reduction'}} { foo(); @@ -272,7 +280,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} { foo(); } @@ -296,7 +304,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp parallel sections reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} { foo(); } @@ -308,15 +316,15 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} +#pragma omp parallel sections reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} { foo(); } -#pragma omp parallel sections reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} +#pragma omp parallel sections reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp parallel sections reduction(+ : o) // expected-error {{no viable overloaded '='}} { foo(); } diff --git a/test/OpenMP/parallel_sections_shared_messages.cpp b/test/OpenMP/parallel_sections_shared_messages.cpp index d4915c8eaa..0f7a147fc7 100644 --- a/test/OpenMP/parallel_sections_shared_messages.cpp +++ b/test/OpenMP/parallel_sections_shared_messages.cpp @@ -48,6 +48,14 @@ public: S3 h; #pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; @@ -83,7 +91,7 @@ int main(int argc, char **argv) { { foo(); } #pragma omp parallel sections shared(e, g) { foo(); } -#pragma omp parallel sections shared(h) // expected-error {{threadprivate or thread local variable cannot be shared}} +#pragma omp parallel sections shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}} { foo(); } #pragma omp parallel sections private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}} { foo(); } diff --git a/test/OpenMP/parallel_shared_messages.cpp b/test/OpenMP/parallel_shared_messages.cpp index 8363989439..7cbc791ac9 100644 --- a/test/OpenMP/parallel_shared_messages.cpp +++ b/test/OpenMP/parallel_shared_messages.cpp @@ -44,6 +44,14 @@ public: S3 h; #pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = { 0 }; @@ -65,7 +73,7 @@ int main(int argc, char **argv) { #pragma omp parallel shared(ca) #pragma omp parallel shared(da) #pragma omp parallel shared(e, g) - #pragma omp parallel shared(h) // expected-error {{threadprivate or thread local variable cannot be shared}} + #pragma omp parallel shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}} #pragma omp parallel private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}} foo(); #pragma omp parallel firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}} diff --git a/test/OpenMP/sections_codegen.cpp b/test/OpenMP/sections_codegen.cpp index 9485d9ffe2..3a1d1260a8 100644 --- a/test/OpenMP/sections_codegen.cpp +++ b/test/OpenMP/sections_codegen.cpp @@ -5,7 +5,8 @@ #ifndef HEADER #define HEADER - +// CHECK: [[IMPLICIT_BARRIER_SECTIONS_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 194, i32 0, i32 0, i8* +// CHECK: [[IMPLICIT_BARRIER_SINGLE_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 322, i32 0, i32 0, i8* // CHECK-LABEL: foo void foo() {}; // CHECK-LABEL: bar @@ -26,7 +27,7 @@ int main() { float l = 0.0; // Used as a base point in checks. // CHECK: [[GTID:%.+]] = call{{.*}} i32 @__kmpc_global_thread_num({{.*}}) // CHECK: store float -#pragma omp sections nowait +#pragma omp sections { // CHECK: store i32 0, i32* [[LB_PTR:%.+]], // CHECK: store i32 1, i32* [[UB_PTR:%.+]], @@ -71,6 +72,13 @@ int main() { // CHECK: [[INNER_LOOP_END]] } // CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_SECTIONS_LOC]], +#pragma omp sections nowait + { + foo(); +#pragma omp section + bar(); + } // CHECK-NOT: __kmpc_cancel_barrier return tmain<int>(); } @@ -87,6 +95,7 @@ int main() { // CHECK: call void @__kmpc_end_single( // CHECK-NEXT: br label %[[END]] // CHECK: [[END]] +// CHECK-NEXT: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_SINGLE_LOC]], // CHECK-NEXT: call i32 @__kmpc_cancel_barrier( // CHECK-NEXT: ret // CHECK: [[TERM_LPAD]] diff --git a/test/OpenMP/sections_firstprivate_messages.cpp b/test/OpenMP/sections_firstprivate_messages.cpp index ecee45900f..6f9f502821 100644 --- a/test/OpenMP/sections_firstprivate_messages.cpp +++ b/test/OpenMP/sections_firstprivate_messages.cpp @@ -170,6 +170,14 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; @@ -281,7 +289,7 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} +#pragma omp sections firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} { foo(); } diff --git a/test/OpenMP/sections_lastprivate_messages.cpp b/test/OpenMP/sections_lastprivate_messages.cpp index 54c6005dce..f513d89de8 100644 --- a/test/OpenMP/sections_lastprivate_messages.cpp +++ b/test/OpenMP/sections_lastprivate_messages.cpp @@ -15,15 +15,16 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} + const S2 &operator=(const S2 &) const; static float S2s; // expected-note {{static data member is predetermined as shared}} static const float S2sc; }; const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} const S2 b; const S2 ba[5]; -class S3 { // expected-note 2 {{'S3' declared here}} +class S3 { int a; - S3 &operator=(const S3 &s3); + S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}} public: S3() : a(0) {} @@ -32,17 +33,17 @@ public: const S3 c; // expected-note {{global variable is predetermined as shared}} const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} extern const int f; // expected-note {{global variable is predetermined as shared}} -class S4 { // expected-note 3 {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note 3 {{implicitly declared private here}} S4(const S4 &s4); public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(const S5 &s5) : a(s5.a) {} @@ -62,8 +63,8 @@ S3 h; template <class I, class C> int foomain(int argc, char **argv) { - I e(4); // expected-note {{'e' defined here}} - I g(5); // expected-note {{'g' defined here}} + I e(4); + I g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel @@ -117,7 +118,7 @@ int foomain(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp sections lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} { foo(); } @@ -155,12 +156,20 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} - S3 m; // expected-note 2 {{'m' defined here}} + S4 e(4); + S5 g(5); + S3 m; S6 n(2); int i; int &j = i; // expected-note {{'j' defined here}} @@ -256,17 +265,17 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp sections lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} { foo(); } #pragma omp parallel -#pragma omp sections lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp sections lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} { foo(); } #pragma omp parallel -#pragma omp sections lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} +#pragma omp sections lastprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be lastprivate}} { foo(); } @@ -296,7 +305,7 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp sections firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} { foo(); } diff --git a/test/OpenMP/sections_private_messages.cpp b/test/OpenMP/sections_private_messages.cpp index 8b330bf710..ea5fe39c08 100644 --- a/test/OpenMP/sections_private_messages.cpp +++ b/test/OpenMP/sections_private_messages.cpp @@ -123,6 +123,14 @@ int foomain(I argc, C **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { S4 e(4); S5 g(5); @@ -172,7 +180,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp sections private(h) // expected-error {{threadprivate or thread local variable cannot be private}} +#pragma omp sections private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} { foo(); } diff --git a/test/OpenMP/sections_reduction_messages.cpp b/test/OpenMP/sections_reduction_messages.cpp index 8c4bdcc2e8..656093757a 100644 --- a/test/OpenMP/sections_reduction_messages.cpp +++ b/test/OpenMP/sections_reduction_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 150 -o - %s void foo() { } @@ -11,7 +11,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+=(const S2 &arg) { return (*this); } + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} public: S2() : a(0) {} @@ -28,17 +28,17 @@ class S3 { public: S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} - S3 operator+=(const S3 &arg1) { return arg1; } + S3 operator+(const S3 &arg1) { return arg1; } }; -int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } S3 c; // expected-note 2 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} S4(const S4 &s4); - S4 &operator+=(const S4 &arg) { return (*this); } + S4 &operator+(const S4 &arg) { return (*this); } public: S4(int v) : a(v) {} @@ -46,26 +46,26 @@ public: S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} S5(const S5 &s5) : a(s5.a) {} - S5 &operator+=(const S5 &arg); + S5 &operator+(const S5 &arg); public: S5(int v) : a(v) {} }; -class S6 { +class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} int a; public: S6() : a(6) {} operator int() { return 6; } -} o; // expected-note 2 {{'o' defined here}} +} o; S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} template <class T> // expected-note {{declared here}} -T tmain(T argc) { // expected-note 2 {{'argc' defined here}} +T tmain(T argc) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -74,7 +74,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} - T fl; // expected-note {{'fl' defined here}} + T fl; #pragma omp parallel #pragma omp sections reduction // expected-error {{expected '(' after 'reduction'}} { @@ -111,12 +111,12 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} foo(); } #pragma omp parallel -#pragma omp sections reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp sections reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} { foo(); } @@ -141,7 +141,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} { foo(); } @@ -171,7 +171,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} foo(); } #pragma omp parallel -#pragma omp sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp sections reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} { foo(); } @@ -191,7 +191,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp sections reduction(+ : o) // expected-error {{no viable overloaded '='}} { foo(); } @@ -235,18 +235,26 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} return T(); } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note 2 {{'j' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; // expected-note {{'q' defined here}} - float fl; // expected-note {{'fl' defined here}} + float fl; #pragma omp parallel #pragma omp sections reduction // expected-error {{expected '(' after 'reduction'}} { @@ -313,7 +321,7 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} { foo(); } @@ -343,7 +351,7 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp sections reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} { foo(); } @@ -358,17 +366,17 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} +#pragma omp sections reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} +#pragma omp sections reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp sections reduction(+ : o) // expected-error {{no viable overloaded '='}} { foo(); } diff --git a/test/OpenMP/simd_lastprivate_messages.cpp b/test/OpenMP/simd_lastprivate_messages.cpp index 55f6058350..24cee01cd9 100644 --- a/test/OpenMP/simd_lastprivate_messages.cpp +++ b/test/OpenMP/simd_lastprivate_messages.cpp @@ -15,15 +15,16 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} + const S2 &operator=(const S2 &) const; static float S2s; // expected-note {{static data member is predetermined as shared}} static const float S2sc; }; const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} const S2 b; const S2 ba[5]; -class S3 { // expected-note {{'S3' declared here}} +class S3 { int a; - S3 &operator=(const S3 &s3); + S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}} public: S3() : a(0) {} @@ -32,17 +33,17 @@ public: const S3 c; // expected-note {{global variable is predetermined as shared}} const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} extern const int f; // expected-note {{global variable is predetermined as shared}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} S4(const S4 &s4); public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(const S5 &s5) : a(s5.a) {} @@ -52,6 +53,14 @@ public: S3 h; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + template <class I, class C> int foomain(I argc, C **argv) { I e(4); @@ -91,7 +100,7 @@ int foomain(I argc, C **argv) { #pragma omp simd lastprivate(e, g) for (int k = 0; k < argc; ++k) ++k; -#pragma omp simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} +#pragma omp simd lastprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be lastprivate}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd firstprivate(i) // expected-error {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}} @@ -121,9 +130,9 @@ int foomain(I argc, C **argv) { int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} - S3 m; // expected-note {{'m' defined here}} + S4 e(4); + S5 g(5); + S3 m; int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} @@ -181,10 +190,10 @@ int main(int argc, char **argv) { #pragma omp simd firstprivate(g) // expected-error {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp simd lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} +#pragma omp simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp simd lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} +#pragma omp simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} for (i = 0; i < argc; ++i) foo(); #pragma omp simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} diff --git a/test/OpenMP/simd_linear_messages.cpp b/test/OpenMP/simd_linear_messages.cpp index b8b7831079..94780fdaa4 100644 --- a/test/OpenMP/simd_linear_messages.cpp +++ b/test/OpenMP/simd_linear_messages.cpp @@ -148,6 +148,14 @@ template<class I, class C> int foomain(I argc, C **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace C { +using A::x; +} + int main(int argc, char **argv) { double darr[100]; // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} @@ -177,7 +185,7 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) ++k; // expected-error@+2 {{linear variable with incomplete type 'S1'}} // expected-error@+1 {{const-qualified variable cannot be linear}} - #pragma omp simd linear (a, b) + #pragma omp simd linear(a, b) for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argv[1]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; @@ -185,7 +193,7 @@ int main(int argc, char **argv) { // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}} #pragma omp simd linear(e, g) for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + #pragma omp simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel { diff --git a/test/OpenMP/simd_private_messages.cpp b/test/OpenMP/simd_private_messages.cpp index 56922e888b..47e6e31596 100644 --- a/test/OpenMP/simd_private_messages.cpp +++ b/test/OpenMP/simd_private_messages.cpp @@ -85,6 +85,14 @@ template<class I, class C> int foomain(I argc, C **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { S4 e(4); S5 g(5); @@ -112,7 +120,7 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) ++k; #pragma omp simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + #pragma omp simd private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp simd'}} for (int k = 0; k < argc; ++k) ++k; diff --git a/test/OpenMP/simd_reduction_messages.cpp b/test/OpenMP/simd_reduction_messages.cpp index 347a5c1a41..530f7434e1 100644 --- a/test/OpenMP/simd_reduction_messages.cpp +++ b/test/OpenMP/simd_reduction_messages.cpp @@ -11,7 +11,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+=(const S2 &arg) { return (*this); } + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} public: S2() : a(0) {} @@ -28,17 +28,17 @@ class S3 { public: S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} - S3 operator+=(const S3 &arg1) { return arg1; } + S3 operator+(const S3 &arg1) { return arg1; } }; -int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } S3 c; // expected-note 2 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} S4(const S4 &s4); - S4 &operator+=(const S4 &arg) { return (*this); } + S4 &operator+(const S4 &arg) { return (*this); } public: S4(int v) : a(v) {} @@ -46,26 +46,26 @@ public: S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} S5(const S5 &s5) : a(s5.a) {} - S5 &operator+=(const S5 &arg); + S5 &operator+(const S5 &arg); public: S5(int v) : a(v) {} }; -class S6 { +class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} int a; public: S6() : a(6) {} operator int() { return 6; } -} o; // expected-note 2 {{'o' defined here}} +} o; S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} template <class T> // expected-note {{declared here}} -T tmain(T argc) { // expected-note 2 {{'argc' defined here}} +T tmain(T argc) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -74,7 +74,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} - T fl; // expected-note {{'fl' defined here}} + T fl; #pragma omp simd reduction // expected-error {{expected '(' after 'reduction'}} for (int i = 0; i < 10; ++i) foo(); @@ -96,10 +96,10 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} @@ -114,7 +114,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp simd reduction(^ : T) // expected-error {{'T' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} @@ -132,7 +132,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} @@ -144,7 +144,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp simd reduction(+ : o) // expected-error {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} @@ -180,18 +180,26 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} return T(); } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note 2 {{'j' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; // expected-note {{'q' defined here}} - float fl; // expected-note {{'fl' defined here}} + float fl; #pragma omp simd reduction // expected-error {{expected '(' after 'reduction'}} for (int i = 0; i < 10; ++i) foo(); @@ -231,7 +239,7 @@ int main(int argc, char **argv) { #pragma omp simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} @@ -249,7 +257,7 @@ int main(int argc, char **argv) { #pragma omp simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} @@ -258,13 +266,13 @@ int main(int argc, char **argv) { #pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} +#pragma omp simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} +#pragma omp simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp simd reduction(+ : o) // expected-error {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} diff --git a/test/OpenMP/single_codegen.cpp b/test/OpenMP/single_codegen.cpp index 2b8a9cd588..298b050fc2 100644 --- a/test/OpenMP/single_codegen.cpp +++ b/test/OpenMP/single_codegen.cpp @@ -18,11 +18,13 @@ public: // CHECK-DAG: [[TEST_CLASS_TY:%.+]] = type { i{{[0-9]+}} } // CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* } +// CHECK: [[IMPLICIT_BARRIER_SINGLE_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 322, i32 0, i32 0, i8* // CHECK: define void [[FOO:@.+]]() TestClass tc; -#pragma omp threadprivate(tc) +TestClass tc2[2]; +#pragma omp threadprivate(tc, tc2) void foo() {} @@ -30,13 +32,15 @@ void foo() {} // TERM_DEBUG-LABEL: @main int main() { // CHECK-DAG: [[A_ADDR:%.+]] = alloca i8 + // CHECK-DAG: [[A2_ADDR:%.+]] = alloca [2 x i8] // CHECK-DAG: [[C_ADDR:%.+]] = alloca [[TEST_CLASS_TY]] char a; + char a2[2]; TestClass c; // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]]) // CHECK-DAG: [[DID_IT:%.+]] = alloca i32, -// CHECK-DAG: [[COPY_LIST:%.+]] = alloca [3 x i8*], +// CHECK-DAG: [[COPY_LIST:%.+]] = alloca [5 x i8*], // CHECK: store i32 0, i32* [[DID_IT]] // CHECK: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) @@ -47,6 +51,7 @@ int main() { // CHECK-NEXT: call void @__kmpc_end_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) // CHECK-NEXT: br label {{%?}}[[EXIT]] // CHECK: [[EXIT]] +// CHECK-NOT: __kmpc_cancel_barrier #pragma omp single nowait a = 2; // CHECK: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) @@ -60,21 +65,29 @@ int main() { // CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) // CHECK-NEXT: br label {{%?}}[[EXIT]] // CHECK: [[EXIT]] -// CHECK: [[A_PTR_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[A_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: store i8* [[A_ADDR]], i8** [[A_PTR_REF]], -// CHECK: [[C_PTR_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[C_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 // CHECK: [[C_PTR_REF_VOID_PTR:%.+]] = bitcast [[TEST_CLASS_TY]]* [[C_ADDR]] to i8* // CHECK: store i8* [[C_PTR_REF_VOID_PTR]], i8** [[C_PTR_REF]], -// CHECK: [[TC_PTR_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[TC_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 // CHECK: [[TC_THREADPRIVATE_ADDR_VOID_PTR:%.+]] = call{{.*}} i8* @__kmpc_threadprivate_cached // CHECK: [[TC_THREADPRIVATE_ADDR:%.+]] = bitcast i8* [[TC_THREADPRIVATE_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]* // CHECK: [[TC_PTR_REF_VOID_PTR:%.+]] = bitcast [[TEST_CLASS_TY]]* [[TC_THREADPRIVATE_ADDR]] to i8* // CHECK: store i8* [[TC_PTR_REF_VOID_PTR]], i8** [[TC_PTR_REF]], -// CHECK: [[COPY_LIST_VOID_PTR:%.+]] = bitcast [3 x i8*]* [[COPY_LIST]] to i8* +// CHECK: [[A2_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[BITCAST:%.+]] = bitcast [2 x i8]* [[A2_ADDR]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[A2_PTR_REF]], +// CHECK: [[TC2_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: [[TC2_THREADPRIVATE_ADDR_VOID_PTR:%.+]] = call{{.*}} i8* @__kmpc_threadprivate_cached +// CHECK: [[TC2_THREADPRIVATE_ADDR:%.+]] = bitcast i8* [[TC2_THREADPRIVATE_ADDR_VOID_PTR]] to [2 x [[TEST_CLASS_TY]]]* +// CHECK: [[TC2_PTR_REF_VOID_PTR:%.+]] = bitcast [2 x [[TEST_CLASS_TY]]]* [[TC2_THREADPRIVATE_ADDR]] to i8* +// CHECK: store i8* [[TC2_PTR_REF_VOID_PTR]], i8** [[TC2_PTR_REF]], +// CHECK: [[COPY_LIST_VOID_PTR:%.+]] = bitcast [5 x i8*]* [[COPY_LIST]] to i8* // CHECK: [[DID_IT_VAL:%.+]] = load i32, i32* [[DID_IT]], -// CHECK: call void @__kmpc_copyprivate([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 24, i8* [[COPY_LIST_VOID_PTR]], void (i8*, i8*)* [[COPY_FUNC:@.+]], i32 [[DID_IT_VAL]]) -// CHECK: call{{.*}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* {{@.+}}, i32 [[GTID]]) -#pragma omp single copyprivate(a, c, tc) +// CHECK: call void @__kmpc_copyprivate([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 40, i8* [[COPY_LIST_VOID_PTR]], void (i8*, i8*)* [[COPY_FUNC:@.+]], i32 [[DID_IT_VAL]]) +// CHECK: call{{.*}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_SINGLE_LOC]], i32 [[GTID]]) +#pragma omp single copyprivate(a, c, tc, a2, tc2) foo(); // CHECK-NOT: call i32 @__kmpc_single // CHECK-NOT: call void @__kmpc_end_single @@ -85,29 +98,43 @@ int main() { // CHECK: store i8* %0, i8** [[DST_ADDR_REF:%.+]], // CHECK: store i8* %1, i8** [[SRC_ADDR_REF:%.+]], // CHECK: [[DST_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[DST_ADDR_REF]], -// CHECK: [[DST_ADDR:%.+]] = bitcast i8* [[DST_ADDR_VOID_PTR]] to [3 x i8*]* +// CHECK: [[DST_ADDR:%.+]] = bitcast i8* [[DST_ADDR_VOID_PTR]] to [5 x i8*]* // CHECK: [[SRC_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[SRC_ADDR_REF]], -// CHECK: [[SRC_ADDR:%.+]] = bitcast i8* [[SRC_ADDR_VOID_PTR]] to [3 x i8*]* -// CHECK: [[SRC_A_ADDR_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[SRC_A_ADDR:%.+]] = load i8*, i8** [[SRC_A_ADDR_REF]], -// CHECK: [[DST_A_ADDR_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SRC_ADDR:%.+]] = bitcast i8* [[SRC_ADDR_VOID_PTR]] to [5 x i8*]* +// CHECK: [[DST_A_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: [[DST_A_ADDR:%.+]] = load i8*, i8** [[DST_A_ADDR_REF]], -// CHECK: [[SRC_C_ADDR_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[SRC_C_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[SRC_C_ADDR_REF]], -// CHECK: [[SRC_C_ADDR:%.+]] = bitcast i8* [[SRC_C_ADDR_VOID_PTR:%.+]] to [[TEST_CLASS_TY]]* -// CHECK: [[DST_C_ADDR_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[DST_C_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[DST_C_ADDR_REF]], -// CHECK: [[DST_C_ADDR:%.+]] = bitcast i8* [[DST_C_ADDR_VOID_PTR:%.+]] to [[TEST_CLASS_TY]]* -// CHECK: [[SRC_TC_ADDR_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[SRC_TC_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[SRC_TC_ADDR_REF]], -// CHECK: [[SRC_TC_ADDR:%.+]] = bitcast i8* [[SRC_TC_ADDR_VOID_PTR:%.+]] to [[TEST_CLASS_TY]]* -// CHECK: [[DST_TC_ADDR_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[DST_TC_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[DST_TC_ADDR_REF]], -// CHECK: [[DST_TC_ADDR:%.+]] = bitcast i8* [[DST_TC_ADDR_VOID_PTR:%.+]] to [[TEST_CLASS_TY]]* +// CHECK: [[SRC_A_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SRC_A_ADDR:%.+]] = load i8*, i8** [[SRC_A_ADDR_REF]], // CHECK: [[SRC_A_VAL:%.+]] = load i8, i8* [[SRC_A_ADDR]], // CHECK: store i8 [[SRC_A_VAL]], i8* [[DST_A_ADDR]], +// CHECK: [[DST_C_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[DST_C_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[DST_C_ADDR_REF]], +// CHECK: [[DST_C_ADDR:%.+]] = bitcast i8* [[DST_C_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]* +// CHECK: [[SRC_C_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[SRC_C_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[SRC_C_ADDR_REF]], +// CHECK: [[SRC_C_ADDR:%.+]] = bitcast i8* [[SRC_C_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]* // CHECK: call{{.*}} [[TEST_CLASS_TY_ASSIGN:@.+]]([[TEST_CLASS_TY]]* [[DST_C_ADDR]], [[TEST_CLASS_TY]]* {{.*}}[[SRC_C_ADDR]]) -// CHECK: call{{.*}} [[TEST_CLASS_TY_ASSIGN:@.+]]([[TEST_CLASS_TY]]* [[DST_TC_ADDR]], [[TEST_CLASS_TY]]* {{.*}}[[SRC_TC_ADDR]]) +// CHECK: [[DST_TC_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[DST_TC_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[DST_TC_ADDR_REF]], +// CHECK: [[DST_TC_ADDR:%.+]] = bitcast i8* [[DST_TC_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]* +// CHECK: [[SRC_TC_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[SRC_TC_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[SRC_TC_ADDR_REF]], +// CHECK: [[SRC_TC_ADDR:%.+]] = bitcast i8* [[SRC_TC_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]* +// CHECK: call{{.*}} [[TEST_CLASS_TY_ASSIGN]]([[TEST_CLASS_TY]]* [[DST_TC_ADDR]], [[TEST_CLASS_TY]]* {{.*}}[[SRC_TC_ADDR]]) +// CHECK: [[DST_A2_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[DST_A2_ADDR:%.+]] = load i8*, i8** [[DST_A2_ADDR_REF]], +// CHECK: [[SRC_A2_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[SRC_A2_ADDR:%.+]] = load i8*, i8** [[SRC_A2_ADDR_REF]], +// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[DST_A2_ADDR]], i8* [[SRC_A2_ADDR]], i{{[0-9]+}} 2, i{{[0-9]+}} 1, i1 false) +// CHECK: [[DST_TC2_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: [[DST_TC2_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[DST_TC2_ADDR_REF]], +// CHECK: [[DST_TC2_ADDR:%.+]] = bitcast i8* [[DST_TC2_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]* +// CHECK: [[SRC_TC2_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: [[SRC_TC2_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[SRC_TC2_ADDR_REF]], +// CHECK: [[SRC_TC2_ADDR:%.+]] = bitcast i8* [[SRC_TC2_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]* +// CHECK: br i1 +// CHECK: call{{.*}} [[TEST_CLASS_TY_ASSIGN]]([[TEST_CLASS_TY]]* %{{.+}}, [[TEST_CLASS_TY]]* {{.*}}) +// CHECK: br i1 // CHECK: ret void // CHECK-LABEL: parallel_single @@ -127,6 +154,6 @@ void parallel_single() { foo(); } // TERM_DEBUG-DAG: [[DBG_LOC_START]] = !MDLocation(line: [[@LINE-12]], -// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !MDLocation(line: [[@LINE-13]], +// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !MDLocation(line: [[@LINE-3]], #endif diff --git a/test/OpenMP/single_copyprivate_messages.cpp b/test/OpenMP/single_copyprivate_messages.cpp index de51bc6b61..793b4d5d0a 100644 --- a/test/OpenMP/single_copyprivate_messages.cpp +++ b/test/OpenMP/single_copyprivate_messages.cpp @@ -105,6 +105,14 @@ T tmain(T argc, C **argv) { return T(); } +namespace A { +double x; +#pragma omp threadprivate(x) +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { int i; static int intA; @@ -121,7 +129,7 @@ int main(int argc, char **argv) { #pragma omp parallel #pragma omp single copyprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} #pragma omp parallel -#pragma omp single copyprivate(l) // expected-error {{'operator=' is a private member of 'S4'}} +#pragma omp single copyprivate(l, B::x) // expected-error {{'operator=' is a private member of 'S4'}} #pragma omp parallel #pragma omp single copyprivate(S1) // expected-error {{'S1' does not refer to a value}} #pragma omp parallel diff --git a/test/OpenMP/single_firstprivate_messages.cpp b/test/OpenMP/single_firstprivate_messages.cpp index 9f6f160835..b4c4712ee2 100644 --- a/test/OpenMP/single_firstprivate_messages.cpp +++ b/test/OpenMP/single_firstprivate_messages.cpp @@ -132,6 +132,14 @@ int foomain(int argc, char **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; @@ -203,7 +211,7 @@ int main(int argc, char **argv) { #pragma omp single firstprivate(m) // OK foo(); #pragma omp parallel -#pragma omp single firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} +#pragma omp single firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} foo(); #pragma omp parallel #pragma omp single private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} diff --git a/test/OpenMP/single_private_messages.cpp b/test/OpenMP/single_private_messages.cpp index 8bdc48f1a5..964fc3a849 100644 --- a/test/OpenMP/single_private_messages.cpp +++ b/test/OpenMP/single_private_messages.cpp @@ -91,6 +91,14 @@ int foomain(I argc, C **argv) { return 0; } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { S4 e(4); S5 g(5); @@ -118,7 +126,7 @@ int main(int argc, char **argv) { foo(); #pragma omp single private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} foo(); -#pragma omp single private(h) // expected-error {{threadprivate or thread local variable cannot be private}} +#pragma omp single private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} foo(); #pragma omp single shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp single'}} foo(); diff --git a/test/OpenMP/task_firstprivate_messages.cpp b/test/OpenMP/task_firstprivate_messages.cpp index 6c5ccfca57..c3c2ae053e 100644 --- a/test/OpenMP/task_firstprivate_messages.cpp +++ b/test/OpenMP/task_firstprivate_messages.cpp @@ -51,6 +51,14 @@ public: S3 h; #pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; @@ -74,7 +82,7 @@ int main(int argc, char **argv) { #pragma omp task firstprivate(S2::S2s) #pragma omp task firstprivate(S2::S2sc) #pragma omp task firstprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} expected-error 2 {{calling a private constructor of class 'S5'}} -#pragma omp task firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} +#pragma omp task firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} #pragma omp task private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}} foo(); #pragma omp task shared(i) diff --git a/test/OpenMP/task_private_messages.cpp b/test/OpenMP/task_private_messages.cpp index 0352694d57..bf2a24a4a0 100644 --- a/test/OpenMP/task_private_messages.cpp +++ b/test/OpenMP/task_private_messages.cpp @@ -45,6 +45,14 @@ public: int threadvar; #pragma omp threadprivate(threadvar) // expected-note {{defined as threadprivate or thread local}} +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} @@ -67,7 +75,7 @@ int main(int argc, char **argv) { #pragma omp task private(da) // expected-error {{shared variable cannot be private}} #pragma omp task private(S2::S2s) #pragma omp task private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} -#pragma omp task private(threadvar) // expected-error {{threadprivate or thread local variable cannot be private}} +#pragma omp task private(threadvar, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} #pragma omp task shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} foo(); #pragma omp task firstprivate(i) private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}} diff --git a/test/OpenMP/task_shared_messages.cpp b/test/OpenMP/task_shared_messages.cpp index 747923721b..2dda25a78b 100644 --- a/test/OpenMP/task_shared_messages.cpp +++ b/test/OpenMP/task_shared_messages.cpp @@ -48,6 +48,14 @@ public: S3 h; #pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; @@ -83,7 +91,7 @@ int main(int argc, char **argv) { foo(); #pragma omp task shared(e, g) foo(); -#pragma omp task shared(h) // expected-error {{threadprivate or thread local variable cannot be shared}} +#pragma omp task shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}} foo(); #pragma omp task private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}} foo(); diff --git a/test/OpenMP/teams_firstprivate_messages.cpp b/test/OpenMP/teams_firstprivate_messages.cpp index 3d4a21999e..c18a22f36e 100644 --- a/test/OpenMP/teams_firstprivate_messages.cpp +++ b/test/OpenMP/teams_firstprivate_messages.cpp @@ -49,6 +49,14 @@ public: S3 h; #pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; @@ -105,7 +113,7 @@ int main(int argc, char **argv) { #pragma omp teams firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} foo(); #pragma omp target -#pragma omp teams firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} +#pragma omp teams firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} foo(); #pragma omp target #pragma omp teams private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}} diff --git a/test/OpenMP/teams_private_messages.cpp b/test/OpenMP/teams_private_messages.cpp index 65caaed381..771b8d3405 100644 --- a/test/OpenMP/teams_private_messages.cpp +++ b/test/OpenMP/teams_private_messages.cpp @@ -41,6 +41,14 @@ public: int threadvar; #pragma omp threadprivate(threadvar) // expected-note {{defined as threadprivate or thread local}} +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}} @@ -94,7 +102,7 @@ int main(int argc, char **argv) { #pragma omp teams private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} foo(); #pragma omp target - #pragma omp teams private(threadvar) // expected-error {{threadprivate or thread local variable cannot be private}} + #pragma omp teams private(threadvar, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} foo(); #pragma omp target #pragma omp teams shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} diff --git a/test/OpenMP/teams_reduction_messages.cpp b/test/OpenMP/teams_reduction_messages.cpp index 18b7cd4bc3..df2c2e801f 100644 --- a/test/OpenMP/teams_reduction_messages.cpp +++ b/test/OpenMP/teams_reduction_messages.cpp @@ -11,7 +11,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+=(const S2 &arg) { return (*this); } + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} public: S2() : a(0) {} @@ -28,17 +28,17 @@ class S3 { public: S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} - S3 operator+=(const S3 &arg1) { return arg1; } + S3 operator+(const S3 &arg1) { return arg1; } }; -int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } S3 c; // expected-note 2 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} S4(const S4 &s4); - S4 &operator+=(const S4 &arg) { return (*this); } + S4 &operator+(const S4 &arg) { return (*this); } public: S4(int v) : a(v) {} @@ -46,26 +46,26 @@ public: S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} S5(const S5 &s5) : a(s5.a) {} - S5 &operator+=(const S5 &arg); + S5 &operator+(const S5 &arg); public: S5(int v) : a(v) {} }; -class S6 { +class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} int a; public: S6() : a(6) {} operator int() { return 6; } -} o; // expected-note 2 {{'o' defined here}} +} o; S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} template <class T> // expected-note {{declared here}} -T tmain(T argc) { // expected-note 2 {{'argc' defined here}} +T tmain(T argc) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -74,7 +74,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} - T fl; // expected-note {{'fl' defined here}} + T fl; #pragma omp target #pragma omp teams reduction // expected-error {{expected '(' after 'reduction'}} foo(); @@ -97,10 +97,10 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp teams reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} foo(); #pragma omp target -#pragma omp teams reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp teams reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp target -#pragma omp teams reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp teams reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp target #pragma omp teams reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} @@ -115,7 +115,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp teams reduction(^ : T) // expected-error {{'T' does not refer to a value}} foo(); #pragma omp target -#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} foo(); #pragma omp target #pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} @@ -133,7 +133,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp teams reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} foo(); #pragma omp target -#pragma omp teams reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp target #pragma omp teams reduction(&& : S2::S2s) @@ -145,7 +145,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp teams reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp teams reduction(+ : o) // expected-error {{no viable overloaded '='}} foo(); #pragma omp target #pragma omp teams private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} @@ -183,18 +183,26 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} return T(); } +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note 2 {{'j' defined here}} S3 &p = k; // expected-note 2 {{'p' defined here}} const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; // expected-note {{'q' defined here}} - float fl; // expected-note {{'fl' defined here}} + float fl; #pragma omp target #pragma omp teams reduction // expected-error {{expected '(' after 'reduction'}} foo(); @@ -235,7 +243,7 @@ int main(int argc, char **argv) { #pragma omp teams reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} foo(); #pragma omp target -#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} foo(); #pragma omp target #pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} @@ -253,7 +261,7 @@ int main(int argc, char **argv) { #pragma omp teams reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} foo(); #pragma omp target -#pragma omp teams reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} +#pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp target #pragma omp teams reduction(&& : S2::S2s) @@ -262,13 +270,13 @@ int main(int argc, char **argv) { #pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} +#pragma omp teams reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} foo(); #pragma omp target -#pragma omp teams reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} +#pragma omp teams reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} +#pragma omp teams reduction(+ : o) // expected-error {{no viable overloaded '='}} foo(); #pragma omp target #pragma omp teams private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} diff --git a/test/OpenMP/teams_shared_messages.cpp b/test/OpenMP/teams_shared_messages.cpp index ce2f917e20..630f449f07 100644 --- a/test/OpenMP/teams_shared_messages.cpp +++ b/test/OpenMP/teams_shared_messages.cpp @@ -44,6 +44,14 @@ public: S3 h; #pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + int main(int argc, char **argv) { const int d = 5; const int da[5] = { 0 }; @@ -94,7 +102,7 @@ int main(int argc, char **argv) { #pragma omp teams shared(e, g) foo(); #pragma omp target - #pragma omp teams shared(h) // expected-error {{threadprivate or thread local variable cannot be shared}} + #pragma omp teams shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}} foo(); #pragma omp target #pragma omp teams private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}} diff --git a/test/OpenMP/threadprivate_ast_print.cpp b/test/OpenMP/threadprivate_ast_print.cpp index 4d0d40e213..3227822d97 100644 --- a/test/OpenMP/threadprivate_ast_print.cpp +++ b/test/OpenMP/threadprivate_ast_print.cpp @@ -22,6 +22,8 @@ int a, b; // CHECK: int a; // CHECK: int b; #pragma omp threadprivate(a) +#pragma omp threadprivate(a) +// CHECK-NEXT: #pragma omp threadprivate(a) // CHECK-NEXT: #pragma omp threadprivate(a) #pragma omp threadprivate(d, b) // CHECK-NEXT: #pragma omp threadprivate(d,b) diff --git a/test/OpenMP/threadprivate_codegen.cpp b/test/OpenMP/threadprivate_codegen.cpp index c7758931e9..03bc08a9b3 100644 --- a/test/OpenMP/threadprivate_codegen.cpp +++ b/test/OpenMP/threadprivate_codegen.cpp @@ -133,25 +133,25 @@ struct S5 { // CHECK-DEBUG-DAG: [[ST_FLOAT_ST:@.+]] = linkonce_odr global float 2.300000e+01 // CHECK-DEBUG-DAG: [[ST_S4_ST:@.+]] = linkonce_odr global %struct.S4 zeroinitializer // CHECK-DEBUG-DAG: [[LOC1:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;162;9;;\00" -// CHECK-DEBUG-DAG: [[LOC2:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;216;9;;\00" -// CHECK-DEBUG-DAG: [[LOC3:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;303;19;;\00" -// CHECK-DEBUG-DAG: [[LOC4:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;328;9;;\00" -// CHECK-DEBUG-DAG: [[LOC5:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;341;9;;\00" -// CHECK-DEBUG-DAG: [[LOC6:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;358;10;;\00" -// CHECK-DEBUG-DAG: [[LOC7:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;375;10;;\00" -// CHECK-DEBUG-DAG: [[LOC8:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;401;10;;\00" -// CHECK-DEBUG-DAG: [[LOC9:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;422;10;;\00" -// CHECK-DEBUG-DAG: [[LOC10:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;437;10;;\00" -// CHECK-DEBUG-DAG: [[LOC11:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;454;27;;\00" -// CHECK-DEBUG-DAG: [[LOC12:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;471;10;;\00" -// CHECK-DEBUG-DAG: [[LOC13:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;550;9;;\00" -// CHECK-DEBUG-DAG: [[LOC14:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;567;10;;\00" -// CHECK-DEBUG-DAG: [[LOC15:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;593;10;;\00" -// CHECK-DEBUG-DAG: [[LOC16:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;614;10;;\00" -// CHECK-DEBUG-DAG: [[LOC17:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;629;10;;\00" -// CHECK-DEBUG-DAG: [[LOC18:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;646;27;;\00" -// CHECK-DEBUG-DAG: [[LOC19:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;663;10;;\00" -// CHECK-DEBUG-DAG: [[LOC20:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;275;9;;\00" +// CHECK-DEBUG-DAG: [[LOC2:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;217;9;;\00" +// CHECK-DEBUG-DAG: [[LOC3:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;304;19;;\00" +// CHECK-DEBUG-DAG: [[LOC4:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;329;9;;\00" +// CHECK-DEBUG-DAG: [[LOC5:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;342;9;;\00" +// CHECK-DEBUG-DAG: [[LOC6:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;359;10;;\00" +// CHECK-DEBUG-DAG: [[LOC7:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;376;10;;\00" +// CHECK-DEBUG-DAG: [[LOC8:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;402;10;;\00" +// CHECK-DEBUG-DAG: [[LOC9:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;423;10;;\00" +// CHECK-DEBUG-DAG: [[LOC10:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;438;10;;\00" +// CHECK-DEBUG-DAG: [[LOC11:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;455;27;;\00" +// CHECK-DEBUG-DAG: [[LOC12:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;472;10;;\00" +// CHECK-DEBUG-DAG: [[LOC13:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;551;9;;\00" +// CHECK-DEBUG-DAG: [[LOC14:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;568;10;;\00" +// CHECK-DEBUG-DAG: [[LOC15:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;594;10;;\00" +// CHECK-DEBUG-DAG: [[LOC16:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;615;10;;\00" +// CHECK-DEBUG-DAG: [[LOC17:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;630;10;;\00" +// CHECK-DEBUG-DAG: [[LOC18:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;647;27;;\00" +// CHECK-DEBUG-DAG: [[LOC19:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;664;10;;\00" +// CHECK-DEBUG-DAG: [[LOC20:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;276;9;;\00" struct Static { static S3 s; @@ -160,6 +160,7 @@ struct Static { static S1 gs1(5); #pragma omp threadprivate(gs1) +#pragma omp threadprivate(gs1) // CHECK: define {{.*}} [[S1_CTOR:@.*]]([[S1]]* {{.*}}, // CHECK: define {{.*}} [[S1_DTOR:@.*]]([[S1]]* {{.*}}) // CHECK: define internal {{.*}}i8* [[GS1_CTOR:@\.__kmpc_global_ctor_\..*]](i8*) diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp index 1aaf2d0cf7..bf26c4f313 100644 --- a/test/OpenMP/threadprivate_messages.cpp +++ b/test/OpenMP/threadprivate_messages.cpp @@ -17,7 +17,7 @@ int a; // expected-note {{'a' defined here}} #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'}} +#pragma omp threadprivate(d, a) int foo() { // expected-note {{declared here}} static int l; #pragma omp threadprivate(l)) // expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} @@ -25,21 +25,20 @@ int foo() { // expected-note {{declared here}} } #pragma omp threadprivate (a) ( -// expected-error@-1 {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning@-1 {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} -#pragma omp threadprivate (a) [ // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} -#pragma omp threadprivate (a) { // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} -#pragma omp threadprivate (a) ) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} -#pragma omp threadprivate (a) ] // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} -#pragma omp threadprivate (a) } // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} +// expected-warning@-1 {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} +#pragma omp threadprivate (a) [ // expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} +#pragma omp threadprivate (a) { // expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} +#pragma omp threadprivate (a) ) // expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} +#pragma omp threadprivate (a) ] // expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} +#pragma omp threadprivate (a) } // expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} #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)) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'd'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} +#pragma omp threadprivate(d // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp threadprivate(d)) // expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} int x, y; #pragma omp threadprivate(x)) // expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} #pragma omp threadprivate(y)), // expected-warning@-1 {{extra tokens at the end of '#pragma omp threadprivate' are ignored}} #pragma omp threadprivate(a,d) -// expected-error@-1 {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-error@-1 {{'#pragma omp threadprivate' must precede all references to variable 'd'}} #pragma omp threadprivate(d.a) // expected-error {{expected identifier}} #pragma omp threadprivate((float)a) // expected-error {{expected unqualified-id}} int foa; // expected-note {{'foa' declared here}} @@ -73,8 +72,8 @@ namespace ns { #pragma omp threadprivate (m) } #pragma omp threadprivate (m) // expected-error {{use of undeclared identifier 'm'}} -#pragma omp threadprivate (ns::m) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'ns::m'}} -#pragma omp threadprivate (ns:m) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}} expected-error {{'#pragma omp threadprivate' must precede all references to variable 'ns::m'}} +#pragma omp threadprivate (ns::m) +#pragma omp threadprivate (ns:m) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}} const int h = 12; const volatile int i = 10; @@ -104,10 +103,10 @@ 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) -#pragma omp threadprivate (o) // expected-error {{'#pragma omp threadprivate' must precede all references to variable '(anonymous namespace)::o'}} +#pragma omp threadprivate (o) } #pragma omp threadprivate (o) // expected-error {{reference to 'o' is ambiguous}} -#pragma omp threadprivate (::o) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'o'}} +#pragma omp threadprivate (::o) int main(int argc, char **argv) { // expected-note {{'argc' defined here}} diff --git a/test/PCH/cxx1y-lambdas.mm b/test/PCH/cxx1y-lambdas.mm index 1cd270661a..5235fc5a4c 100644 --- a/test/PCH/cxx1y-lambdas.mm +++ b/test/PCH/cxx1y-lambdas.mm @@ -1,58 +1,58 @@ -// RUN: %clang_cc1 -pedantic-errors -fblocks -std=c++1y -emit-pch %s -o %t-cxx1y
-// RUN: %clang_cc1 -ast-print -pedantic-errors -fblocks -std=c++1y -include-pch %t-cxx1y %s | FileCheck -check-prefix=CHECK-PRINT %s
-
-#ifndef HEADER_INCLUDED
-
-#define HEADER_INCLUDED
-template<typename T>
-T add_slowly(const T& x, const T &y) {
- return [](auto z, int y = 0) { return z + y; }(5);
-};
-
-inline int add_int_slowly_twice(int x, int y) {
- int i = add_slowly(x, y);
- auto lambda = [](auto z) { return z + z; };
- return i + lambda(y);
-}
-
-inline int sum_array(int n) {
- auto lambda = [](auto N) -> int {
- int sum = 0;
- int array[5] = { 1, 2, 3, 4, 5};
-
- for (unsigned I = 0; I < N; ++I)
- sum += array[N];
- return sum;
- };
-
- return lambda(n);
-}
-
-inline int to_block_pointer(int n) {
- auto lambda = [=](int m) { return n + m; };
- int (^block)(int) = lambda;
- return block(17);
-}
-
-template<typename T>
-int init_capture(T t) {
- return [&, x(t)] { return sizeof(x); };
-}
-
-#else
-
-// CHECK-PRINT: T add_slowly
-// CHECK-PRINT: return []
-template float add_slowly(const float&, const float&);
-
-int add(int x, int y) {
- return add_int_slowly_twice(x, y) + sum_array(4) + to_block_pointer(5);
-}
-
-// CHECK-PRINT: inline int add_int_slowly_twice
-// CHECK-PRINT: lambda = [] (type-parameter-0-0 z
-
-// CHECK-PRINT: init_capture
-// CHECK-PRINT: [&, x(t)]
-
-#endif
+// RUN: %clang_cc1 -pedantic-errors -fblocks -std=c++1y -emit-pch %s -o %t-cxx1y +// RUN: %clang_cc1 -ast-print -pedantic-errors -fblocks -std=c++1y -include-pch %t-cxx1y %s | FileCheck -check-prefix=CHECK-PRINT %s + +#ifndef HEADER_INCLUDED + +#define HEADER_INCLUDED +template<typename T> +T add_slowly(const T& x, const T &y) { + return [](auto z, int y = 0) { return z + y; }(5); +}; + +inline int add_int_slowly_twice(int x, int y) { + int i = add_slowly(x, y); + auto lambda = [](auto z) { return z + z; }; + return i + lambda(y); +} + +inline int sum_array(int n) { + auto lambda = [](auto N) -> int { + int sum = 0; + int array[5] = { 1, 2, 3, 4, 5}; + + for (unsigned I = 0; I < N; ++I) + sum += array[N]; + return sum; + }; + + return lambda(n); +} + +inline int to_block_pointer(int n) { + auto lambda = [=](int m) { return n + m; }; + int (^block)(int) = lambda; + return block(17); +} + +template<typename T> +int init_capture(T t) { + return [&, x(t)] { return sizeof(x); }; +} + +#else + +// CHECK-PRINT: T add_slowly +// CHECK-PRINT: return [] +template float add_slowly(const float&, const float&); + +int add(int x, int y) { + return add_int_slowly_twice(x, y) + sum_array(4) + to_block_pointer(5); +} + +// CHECK-PRINT: inline int add_int_slowly_twice +// CHECK-PRINT: lambda = [] (type-parameter-0-0 z + +// CHECK-PRINT: init_capture +// CHECK-PRINT: [&, x(t)] + +#endif diff --git a/test/PCH/emit-pth.c b/test/PCH/emit-pth.c new file mode 100644 index 0000000000..2c0fba7f09 --- /dev/null +++ b/test/PCH/emit-pth.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-pth -o %t1 %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-pth -o - %s > %t2 +// RUN: cmp %t1 %t2 +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-pth -o - %s | \ +// RUN: FileCheck %s + +// CHECK: cfe-pth diff --git a/test/Parser/atomic.c b/test/Parser/atomic.c index 07a83dddcd..e435518d85 100644 --- a/test/Parser/atomic.c +++ b/test/Parser/atomic.c @@ -36,3 +36,5 @@ typedef _Atomic(int __attribute__((vector_size(16)))) atomic_vector_int; struct S _Atomic atomic_s_no_missing_semicolon; + +int *const _Atomic atomic_return_type(); diff --git a/test/Parser/cxx-class.cpp b/test/Parser/cxx-class.cpp index 215c941a46..f46e752bcb 100644 --- a/test/Parser/cxx-class.cpp +++ b/test/Parser/cxx-class.cpp @@ -159,6 +159,7 @@ namespace DtorErrors { ~D::D() throw(X) {} // expected-error {{'~' in destructor name should be after nested name specifier}} ~Undeclared::Undeclared() {} // expected-error {{use of undeclared identifier 'Undeclared'}} expected-error {{'~' in destructor name should be after nested name specifier}} + ~Undeclared:: {} // expected-error {{expected identifier}} expected-error {{'~' in destructor name should be after nested name specifier}} struct S { // For another struct's destructor, emit the same diagnostic like for diff --git a/test/Parser/cxx0x-attributes.cpp b/test/Parser/cxx0x-attributes.cpp index 33987f94c2..7eec5761ea 100644 --- a/test/Parser/cxx0x-attributes.cpp +++ b/test/Parser/cxx0x-attributes.cpp @@ -346,3 +346,10 @@ namespace { deprecated ]] void bad(); } + +#define attr_name bitand +#define attr_name_2(x) x +#define attr_name_3(x, y) x##y +[[attr_name, attr_name_2(bitor), attr_name_3(com, pl)]] int macro_attrs; // expected-warning {{unknown attribute 'compl' ignored}} \ + expected-warning {{unknown attribute 'bitor' ignored}} \ + expected-warning {{unknown attribute 'bitand' ignored}} diff --git a/test/Preprocessor/aarch64-target-features.c b/test/Preprocessor/aarch64-target-features.c index 45a6c89962..85c0f24684 100644 --- a/test/Preprocessor/aarch64-target-features.c +++ b/test/Preprocessor/aarch64-target-features.c @@ -109,3 +109,11 @@ // RUN: %clang -target aarch64 -march=armv8-a+neon -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR-NEON %s // RUN: %clang -target aarch64 -march=armv8-a+noneon -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR-NEON %s // CHECK-ERROR-NEON: error: [no]neon is not accepted as modifier, please use [no]simd instead + +// RUN: %clang -target aarch64 -march=armv8.1a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-FEATURE-1 %s +// RUN: %clang -target aarch64 -march=armv8.1a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-FEATURE-2 %s +// RUN: %clang -target aarch64 -march=armv8.1a+nosimd -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-FEATURE-3 %s +// CHECK-V81A-FEATURE-1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+v8.1a" "-target-feature" "+crypto" +// CHECK-V81A-FEATURE-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+v8.1a" "-target-feature" "-crypto" +// CHECK-V81A-FEATURE-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "-neon" + diff --git a/test/Preprocessor/arm-target-features.c b/test/Preprocessor/arm-target-features.c index 926a7534c9..b16b744f8e 100644 --- a/test/Preprocessor/arm-target-features.c +++ b/test/Preprocessor/arm-target-features.c @@ -264,6 +264,24 @@ // A53-THUMB:#define __ARM_ARCH_EXT_IDIV__ 1 // A53-THUMB:#define __ARM_FEATURE_DSP +// Test whether predefines are as expected when targeting cortex-r4. +// RUN: %clang -target armv7 -mcpu=cortex-r4 -x c -E -dM %s -o - | FileCheck --check-prefix=R4-ARM %s +// R4-ARM-NOT:#define __ARM_ARCH_EXT_IDIV__ +// R4-ARM:#define __ARM_FEATURE_DSP + +// RUN: %clang -target armv7 -mthumb -mcpu=cortex-r4 -x c -E -dM %s -o - | FileCheck --check-prefix=R4-THUMB %s +// R4-THUMB:#define __ARM_ARCH_EXT_IDIV__ 1 +// R4-THUMB:#define __ARM_FEATURE_DSP + +// Test whether predefines are as expected when targeting cortex-r4f. +// RUN: %clang -target armv7 -mcpu=cortex-r4f -x c -E -dM %s -o - | FileCheck --check-prefix=R4F-ARM %s +// R4F-ARM-NOT:#define __ARM_ARCH_EXT_IDIV__ +// R4F-ARM:#define __ARM_FEATURE_DSP + +// RUN: %clang -target armv7 -mthumb -mcpu=cortex-r4f -x c -E -dM %s -o - | FileCheck --check-prefix=R4F-THUMB %s +// R4F-THUMBT:#define __ARM_ARCH_EXT_IDIV__ 1 +// R4F-THUMB:#define __ARM_FEATURE_DSP + // Test whether predefines are as expected when targeting cortex-r5. // RUN: %clang -target armv7 -mcpu=cortex-r5 -x c -E -dM %s -o - | FileCheck --check-prefix=R5-ARM %s // R5-ARM:#define __ARM_ARCH_EXT_IDIV__ 1 diff --git a/test/Preprocessor/has_include.c b/test/Preprocessor/has_include.c index 131e51919f..ad7329390e 100644 --- a/test/Preprocessor/has_include.c +++ b/test/Preprocessor/has_include.c @@ -163,6 +163,18 @@ __has_include #if __has_include #endif +// expected-error@+1 {{missing '(' after '__has_include'}} +#if __has_include'x' +#endif + +// expected-error@+1 {{expected "FILENAME" or <FILENAME>}} +#if __has_include('x' +#endif + +// expected-error@+1 {{expected "FILENAME" or <FILENAME}} expected-error@+1 {{expected end of line in preprocessor expression}} +#if __has_include('x') +#endif + // expected-error@+1 {{missing ')' after '__has_include'}} // expected-error@+1 {{expected value in expression}} // expected-note@+1 {{to match this '('}} #if __has_include(<stdint.h> #endif diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c index ad63d01e2d..91ec4d77b5 100644 --- a/test/Preprocessor/init.c +++ b/test/Preprocessor/init.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -E -dM -x assembler-with-cpp < /dev/null | FileCheck -check-prefix ASM %s +/PtrDiffType / RUN: %clang_cc1 -E -dM -x assembler-with-cpp < /dev/null | FileCheck -check-prefix ASM %s // // ASM:#define __ASSEMBLER__ 1 // @@ -4416,11 +4416,16 @@ // RUN: | FileCheck -check-prefix MIPS-MSA %s // MIPS-MSA:#define __mips_msa 1 // -// RUN: %clang_cc1 -target-feature +nan2008 \ +// RUN: %clang_cc1 -target-cpu mips32r3 -target-feature +nan2008 \ // RUN: -E -dM -triple=mips-none-none < /dev/null \ // RUN: | FileCheck -check-prefix MIPS-NAN2008 %s // MIPS-NAN2008:#define __mips_nan2008 1 // +// RUN: %clang_cc1 -target-cpu mips32r3 -target-feature -nan2008 \ +// RUN: -E -dM -triple=mips-none-none < /dev/null \ +// RUN: | FileCheck -check-prefix NOMIPS-NAN2008 %s +// NOMIPS-NAN2008-NOT:#define __mips_nan2008 1 +// // RUN: %clang_cc1 -target-feature -fp64 \ // RUN: -E -dM -triple=mips-none-none < /dev/null \ // RUN: | FileCheck -check-prefix MIPS32-MFP32 %s @@ -4769,7 +4774,7 @@ // NVPTX32:#define __NVPTX__ 1 // NVPTX32:#define __POINTER_WIDTH__ 32 // NVPTX32:#define __PRAGMA_REDEFINE_EXTNAME 1 -// NVPTX32:#define __PTRDIFF_TYPE__ unsigned int +// NVPTX32:#define __PTRDIFF_TYPE__ int // NVPTX32:#define __PTRDIFF_WIDTH__ 32 // NVPTX32:#define __PTX__ 1 // NVPTX32:#define __SCHAR_MAX__ 127 @@ -4898,10 +4903,10 @@ // NVPTX64:#define __INTMAX_MAX__ 9223372036854775807LL // NVPTX64:#define __INTMAX_TYPE__ long long int // NVPTX64:#define __INTMAX_WIDTH__ 64 -// NVPTX64:#define __INTPTR_FMTd__ "lld" -// NVPTX64:#define __INTPTR_FMTi__ "lli" -// NVPTX64:#define __INTPTR_MAX__ 9223372036854775807LL -// NVPTX64:#define __INTPTR_TYPE__ long long int +// NVPTX64:#define __INTPTR_FMTd__ "ld" +// NVPTX64:#define __INTPTR_FMTi__ "li" +// NVPTX64:#define __INTPTR_MAX__ 9223372036854775807L +// NVPTX64:#define __INTPTR_TYPE__ long int // NVPTX64:#define __INTPTR_WIDTH__ 64 // NVPTX64:#define __INT_FAST16_FMTd__ "hd" // NVPTX64:#define __INT_FAST16_FMTi__ "hi" @@ -4956,7 +4961,7 @@ // NVPTX64:#define __NVPTX__ 1 // NVPTX64:#define __POINTER_WIDTH__ 64 // NVPTX64:#define __PRAGMA_REDEFINE_EXTNAME 1 -// NVPTX64:#define __PTRDIFF_TYPE__ long long unsigned int +// NVPTX64:#define __PTRDIFF_TYPE__ long int // NVPTX64:#define __PTRDIFF_WIDTH__ 64 // NVPTX64:#define __PTX__ 1 // NVPTX64:#define __SCHAR_MAX__ 127 @@ -4976,7 +4981,7 @@ // 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_TYPE__ long unsigned int // NVPTX64:#define __SIZE_WIDTH__ 64 // NVPTX64:#define __UINT16_C_SUFFIX__ {{$}} // NVPTX64:#define __UINT16_MAX__ 65535 @@ -4994,8 +4999,8 @@ // NVPTX64:#define __UINTMAX_MAX__ 18446744073709551615ULL // NVPTX64:#define __UINTMAX_TYPE__ long long unsigned int // NVPTX64:#define __UINTMAX_WIDTH__ 64 -// NVPTX64:#define __UINTPTR_MAX__ 18446744073709551615ULL -// NVPTX64:#define __UINTPTR_TYPE__ long long unsigned int +// NVPTX64:#define __UINTPTR_MAX__ 18446744073709551615UL +// NVPTX64:#define __UINTPTR_TYPE__ long unsigned int // NVPTX64:#define __UINTPTR_WIDTH__ 64 // NVPTX64:#define __UINT_FAST16_MAX__ 65535 // NVPTX64:#define __UINT_FAST16_TYPE__ unsigned short @@ -6641,21 +6646,21 @@ // S390X:#define __INT32_FMTi__ "i" // S390X:#define __INT32_MAX__ 2147483647 // S390X:#define __INT32_TYPE__ int -// S390X:#define __INT64_C_SUFFIX__ LL -// S390X:#define __INT64_FMTd__ "lld" -// S390X:#define __INT64_FMTi__ "lli" -// S390X:#define __INT64_MAX__ 9223372036854775807LL -// S390X:#define __INT64_TYPE__ long long int +// S390X:#define __INT64_C_SUFFIX__ L +// S390X:#define __INT64_FMTd__ "ld" +// S390X:#define __INT64_FMTi__ "li" +// S390X:#define __INT64_MAX__ 9223372036854775807L +// S390X:#define __INT64_TYPE__ long int // S390X:#define __INT8_C_SUFFIX__ {{$}} // S390X:#define __INT8_FMTd__ "hhd" // S390X:#define __INT8_FMTi__ "hhi" // S390X:#define __INT8_MAX__ 127 // S390X:#define __INT8_TYPE__ signed char -// S390X:#define __INTMAX_C_SUFFIX__ LL -// S390X:#define __INTMAX_FMTd__ "lld" -// S390X:#define __INTMAX_FMTi__ "lli" -// S390X:#define __INTMAX_MAX__ 9223372036854775807LL -// S390X:#define __INTMAX_TYPE__ long long int +// S390X:#define __INTMAX_C_SUFFIX__ L +// S390X:#define __INTMAX_FMTd__ "ld" +// S390X:#define __INTMAX_FMTi__ "li" +// S390X:#define __INTMAX_MAX__ 9223372036854775807L +// S390X:#define __INTMAX_TYPE__ long int // S390X:#define __INTMAX_WIDTH__ 64 // S390X:#define __INTPTR_FMTd__ "ld" // S390X:#define __INTPTR_FMTi__ "li" @@ -6738,15 +6743,15 @@ // S390X:#define __UINT32_C_SUFFIX__ U // S390X:#define __UINT32_MAX__ 4294967295U // S390X:#define __UINT32_TYPE__ unsigned int -// S390X:#define __UINT64_C_SUFFIX__ ULL -// S390X:#define __UINT64_MAX__ 18446744073709551615ULL -// S390X:#define __UINT64_TYPE__ long long unsigned int +// S390X:#define __UINT64_C_SUFFIX__ UL +// S390X:#define __UINT64_MAX__ 18446744073709551615UL +// S390X:#define __UINT64_TYPE__ long unsigned int // S390X:#define __UINT8_C_SUFFIX__ {{$}} // S390X:#define __UINT8_MAX__ 255 // S390X:#define __UINT8_TYPE__ unsigned char -// S390X:#define __UINTMAX_C_SUFFIX__ ULL -// S390X:#define __UINTMAX_MAX__ 18446744073709551615ULL -// S390X:#define __UINTMAX_TYPE__ long long unsigned int +// S390X:#define __UINTMAX_C_SUFFIX__ UL +// S390X:#define __UINTMAX_MAX__ 18446744073709551615UL +// S390X:#define __UINTMAX_TYPE__ long unsigned int // S390X:#define __UINTMAX_WIDTH__ 64 // S390X:#define __UINTPTR_MAX__ 18446744073709551615UL // S390X:#define __UINTPTR_TYPE__ long unsigned int diff --git a/test/Preprocessor/predefined-arch-macros.c b/test/Preprocessor/predefined-arch-macros.c index 6e3743da95..9fee3b6294 100644 --- a/test/Preprocessor/predefined-arch-macros.c +++ b/test/Preprocessor/predefined-arch-macros.c @@ -1675,3 +1675,30 @@ // // CHECK_PPC_CRYPTO_M64: #define __CRYPTO__ // + +// Begin SystemZ/GCC/Linux tests ---------------- +// +// RUN: %clang -march=z10 -E -dM %s -o - 2>&1 \ +// RUN: -target s390x-unknown-linux \ +// RUN: | FileCheck %s -check-prefix=CHECK_SYSTEMZ_Z10 +// +// CHECK_SYSTEMZ_Z10: #define __LONG_DOUBLE_128__ 1 +// CHECK_SYSTEMZ_Z10: #define __s390__ 1 +// CHECK_SYSTEMZ_Z10: #define __s390x__ 1 +// CHECK_SYSTEMZ_Z10: #define __zarch__ 1 +// +// RUN: %clang -march=zEC12 -E -dM %s -o - 2>&1 \ +// RUN: -target s390x-unknown-linux \ +// RUN: | FileCheck %s -check-prefix=CHECK_SYSTEMZ_ZEC12 +// +// CHECK_SYSTEMZ_ZEC12: #define __HTM__ 1 +// CHECK_SYSTEMZ_ZEC12: #define __LONG_DOUBLE_128__ 1 +// CHECK_SYSTEMZ_ZEC12: #define __s390__ 1 +// CHECK_SYSTEMZ_ZEC12: #define __s390x__ 1 +// CHECK_SYSTEMZ_ZEC12: #define __zarch__ 1 +// +// RUN: %clang -mhtm -E -dM %s -o - 2>&1 \ +// RUN: -target s390x-unknown-linux \ +// RUN: | FileCheck %s -check-prefix=CHECK_SYSTEMZ_HTM +// +// CHECK_SYSTEMZ_HTM: #define __HTM__ 1 diff --git a/test/Preprocessor/stdint.c b/test/Preprocessor/stdint.c index 9bc1aa7cc5..28ccfef9f4 100644 --- a/test/Preprocessor/stdint.c +++ b/test/Preprocessor/stdint.c @@ -851,8 +851,8 @@ // // RUN: %clang_cc1 -E -ffreestanding -triple=s390x-none-none %s | FileCheck -check-prefix S390X %s // -// S390X:typedef long long int int64_t; -// S390X:typedef long long unsigned int uint64_t; +// S390X:typedef long int int64_t; +// S390X:typedef long unsigned int uint64_t; // S390X:typedef int64_t int_least64_t; // S390X:typedef uint64_t uint_least64_t; // S390X:typedef int64_t int_fast64_t; @@ -882,8 +882,8 @@ // 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:typedef long int intmax_t; +// S390X:typedef long unsigned int uintmax_t; // // S390X:INT8_MAX_ 127 // S390X:INT8_MIN_ (-127 -1) @@ -916,23 +916,23 @@ // S390X:UINT_FAST32_MAX_ 4294967295U // // S390X:INT64_MAX_ 9223372036854775807L -// S390X:INT64_MIN_ (-9223372036854775807LL -1) +// S390X:INT64_MIN_ (-9223372036854775807L -1) // S390X:UINT64_MAX_ 18446744073709551615UL -// S390X:INT_LEAST64_MIN_ (-9223372036854775807LL -1) +// S390X:INT_LEAST64_MIN_ (-9223372036854775807L -1) // S390X:INT_LEAST64_MAX_ 9223372036854775807L // S390X:UINT_LEAST64_MAX_ 18446744073709551615UL -// S390X:INT_FAST64_MIN_ (-9223372036854775807LL -1) +// S390X:INT_FAST64_MIN_ (-9223372036854775807L -1) // S390X:INT_FAST64_MAX_ 9223372036854775807L // S390X:UINT_FAST64_MAX_ 18446744073709551615UL // -// S390X:INTPTR_MIN_ (-9223372036854775807LL -1) +// S390X:INTPTR_MIN_ (-9223372036854775807L -1) // S390X:INTPTR_MAX_ 9223372036854775807L // S390X:UINTPTR_MAX_ 18446744073709551615UL -// S390X:PTRDIFF_MIN_ (-9223372036854775807LL -1) +// S390X:PTRDIFF_MIN_ (-9223372036854775807L -1) // S390X:PTRDIFF_MAX_ 9223372036854775807L // S390X:SIZE_MAX_ 18446744073709551615UL // -// S390X:INTMAX_MIN_ (-9223372036854775807LL -1) +// S390X:INTMAX_MIN_ (-9223372036854775807L -1) // S390X:INTMAX_MAX_ 9223372036854775807L // S390X:UINTMAX_MAX_ 18446744073709551615UL // diff --git a/test/Profile/cxx-lambda.cpp b/test/Profile/cxx-lambda.cpp index 6790149c7f..34e185715b 100644 --- a/test/Profile/cxx-lambda.cpp +++ b/test/Profile/cxx-lambda.cpp @@ -19,8 +19,8 @@ void lambdas() { int i = 1; - // LMBGEN-LABEL: define internal{{( zeroext)?}} i1 @"_ZZ7lambdasvENK3$_0clEi"( - // LMBUSE-LABEL: define internal{{( zeroext)?}} i1 @"_ZZ7lambdasvENK3$_0clEi"( + // LMBGEN-LABEL: define internal{{( x86_thiscallcc)?( zeroext)?}} i1 @"_ZZ7lambdasvENK3$_0clEi"( + // LMBUSE-LABEL: define internal{{( x86_thiscallcc)?( zeroext)?}} i1 @"_ZZ7lambdasvENK3$_0clEi"( // LMBGEN: store {{.*}} @[[LFC]], i64 0, i64 0 auto f = [&i](int k) { // LMBGEN: store {{.*}} @[[LFC]], i64 0, i64 1 diff --git a/test/Profile/profile-does-not-exist.c b/test/Profile/profile-does-not-exist.c new file mode 100644 index 0000000000..89609bd945 --- /dev/null +++ b/test/Profile/profile-does-not-exist.c @@ -0,0 +1,4 @@ +// RUN: not %clang_cc1 -emit-llvm %s -o - -fprofile-instr-use=%t.nonexistent.profdata 2>&1 | FileCheck %s + +// CHECK: error: Could not read profile: +// CHECK-NOT: Assertion failed diff --git a/test/Rewriter/objc-modern-boxing.mm b/test/Rewriter/objc-modern-boxing.mm index 40eeafbe29..22d092fecd 100644 --- a/test/Rewriter/objc-modern-boxing.mm +++ b/test/Rewriter/objc-modern-boxing.mm @@ -61,12 +61,12 @@ int main(int argc, const char *argv[]) { NSString *duplicateString = @(strdup("Hello")); } -// CHECK: NSNumber *theLetterZ = ((NSNumber *(*)(id, SEL, char))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithChar:"), ('Z')); -// CHECK: NSNumber *fortyTwo = ((NSNumber *(*)(id, SEL, int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithInt:"), (42)); -// CHECK: NSNumber *fortyTwoUnsigned = ((NSNumber *(*)(id, SEL, unsigned int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithUnsignedInt:"), (42U)); -// CHECK: NSNumber *fortyTwoLong = ((NSNumber *(*)(id, SEL, long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLong:"), (42L)); -// CHECK: NSNumber *fortyTwoLongLong = ((NSNumber *(*)(id, SEL, long long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLongLong:"), (42LL)); -// CHECK: NSNumber *piFloat = ((NSNumber *(*)(id, SEL, float))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithFloat:"), (3.14159274F)); -// CHECK: NSNumber *piDouble = ((NSNumber *(*)(id, SEL, double))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithDouble:"), (3.1415926535000001)); -// CHECK: NSNumber *nsb = ((NSNumber *(*)(id, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), (BOOL)(b)); -// CHECK: NSString *duplicateString = ((NSString *(*)(id, SEL, const char *))(void *)objc_msgSend)(objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), (const char *)(strdup("Hello"))); +// CHECK: NSNumber *theLetterZ = ((NSNumber *(*)(Class, SEL, char))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithChar:"), ('Z')); +// CHECK: NSNumber *fortyTwo = ((NSNumber *(*)(Class, SEL, int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithInt:"), (42)); +// CHECK: NSNumber *fortyTwoUnsigned = ((NSNumber *(*)(Class, SEL, unsigned int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithUnsignedInt:"), (42U)); +// CHECK: NSNumber *fortyTwoLong = ((NSNumber *(*)(Class, SEL, long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLong:"), (42L)); +// CHECK: NSNumber *fortyTwoLongLong = ((NSNumber *(*)(Class, SEL, long long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLongLong:"), (42LL)); +// CHECK: NSNumber *piFloat = ((NSNumber *(*)(Class, SEL, float))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithFloat:"), (3.14159274F)); +// CHECK: NSNumber *piDouble = ((NSNumber *(*)(Class, SEL, double))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithDouble:"), (3.1415926535000001)); +// CHECK: NSNumber *nsb = ((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), (BOOL)(b)); +// CHECK: NSString *duplicateString = ((NSString *(*)(Class, SEL, const char *))(void *)objc_msgSend)(objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), (const char *)(strdup("Hello"))); diff --git a/test/Rewriter/objc-modern-numeric-literal.mm b/test/Rewriter/objc-modern-numeric-literal.mm index 57f7ca2d9a..aff1d474f7 100644 --- a/test/Rewriter/objc-modern-numeric-literal.mm +++ b/test/Rewriter/objc-modern-numeric-literal.mm @@ -56,14 +56,14 @@ int main(int argc, const char *argv[]) { NSNumber *falseNumber = @false; // equivalent to [NSNumber numberWithBool:(BOOL)false] } -// CHECK: NSNumber *theLetterZ = ((NSNumber *(*)(id, SEL, char))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithChar:"), 'Z'); -// CHECK: NSNumber *fortyTwo = ((NSNumber *(*)(id, SEL, int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithInt:"), 42); -// CHECK: NSNumber *fortyTwoUnsigned = ((NSNumber *(*)(id, SEL, unsigned int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithUnsignedInt:"), 42U); -// CHECK: NSNumber *fortyTwoLong = ((NSNumber *(*)(id, SEL, long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLong:"), 42L); -// CHECK: NSNumber *fortyTwoLongLong = ((NSNumber *(*)(id, SEL, long long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLongLong:"), 42LL); -// CHECK: NSNumber *piFloat = ((NSNumber *(*)(id, SEL, float))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithFloat:"), 3.14159274F); -// CHECK: NSNumber *piDouble = ((NSNumber *(*)(id, SEL, double))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithDouble:"), 3.1415926535000001); -// CHECK: NSNumber *yesNumber = ((NSNumber *(*)(id, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), true); -// CHECK: NSNumber *noNumber = ((NSNumber *(*)(id, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), false); -// CHECK: NSNumber *trueNumber = ((NSNumber *(*)(id, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), true); -// CHECK: NSNumber *falseNumber = ((NSNumber *(*)(id, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), false); +// CHECK: NSNumber *theLetterZ = ((NSNumber *(*)(Class, SEL, char))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithChar:"), 'Z'); +// CHECK: NSNumber *fortyTwo = ((NSNumber *(*)(Class, SEL, int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithInt:"), 42); +// CHECK: NSNumber *fortyTwoUnsigned = ((NSNumber *(*)(Class, SEL, unsigned int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithUnsignedInt:"), 42U); +// CHECK: NSNumber *fortyTwoLong = ((NSNumber *(*)(Class, SEL, long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLong:"), 42L); +// CHECK: NSNumber *fortyTwoLongLong = ((NSNumber *(*)(Class, SEL, long long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLongLong:"), 42LL); +// CHECK: NSNumber *piFloat = ((NSNumber *(*)(Class, SEL, float))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithFloat:"), 3.14159274F); +// CHECK: NSNumber *piDouble = ((NSNumber *(*)(Class, SEL, double))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithDouble:"), 3.1415926535000001); +// CHECK: NSNumber *yesNumber = ((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), true); +// CHECK: NSNumber *noNumber = ((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), false); +// CHECK: NSNumber *trueNumber = ((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), true); +// CHECK: NSNumber *falseNumber = ((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), false); diff --git a/test/Rewriter/rewrite-modern-array-literal.mm b/test/Rewriter/rewrite-modern-array-literal.mm index 208e646eb3..c1431ea48b 100644 --- a/test/Rewriter/rewrite-modern-array-literal.mm +++ b/test/Rewriter/rewrite-modern-array-literal.mm @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -x objective-c++ -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp +// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp // rdar://10803676 extern "C" void *sel_registerName(const char *); diff --git a/test/Rewriter/rewrite-modern-container-literal.mm b/test/Rewriter/rewrite-modern-container-literal.mm index 2c2f61df1d..8a52791a1d 100644 --- a/test/Rewriter/rewrite-modern-container-literal.mm +++ b/test/Rewriter/rewrite-modern-container-literal.mm @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -x objective-c++ -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp +// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp // rdar://10803676 void *sel_registerName(const char *); diff --git a/test/Sema/__try.c b/test/Sema/__try.c index 925dbcc55e..8be93ddaee 100644 --- a/test/Sema/__try.c +++ b/test/Sema/__try.c @@ -281,3 +281,9 @@ void test_jump_out_of___finally() { }(); } } + +void test_typo_in_except() { + __try { + } __except(undeclared_identifier) { // expected-error {{use of undeclared identifier 'undeclared_identifier'}} expected-error {{expected expression}} + } +} diff --git a/test/Sema/anonymous-struct-union.c b/test/Sema/anonymous-struct-union.c index 652383eabb..c33bc52971 100644 --- a/test/Sema/anonymous-struct-union.c +++ b/test/Sema/anonymous-struct-union.c @@ -22,6 +22,7 @@ struct X { }; void test_unqual_references(struct X x, const struct X xc) { + // expected-note@-1 3{{variable 'xc' declared const here}} x.i = 0; x.f = 0.0; x.f2 = x.f; @@ -29,9 +30,9 @@ void test_unqual_references(struct X x, const struct X xc) { x.f3 = 0; // expected-error{{no member named 'f3'}} x.a = 0; - xc.d = 0.0; // expected-error{{read-only variable is not assignable}} - xc.f = 0; // expected-error{{read-only variable is not assignable}} - xc.a = 0; // expected-error{{read-only variable is not assignable}} + xc.d = 0.0; // expected-error{{cannot assign to variable 'xc' with const-qualified type 'const struct X'}} + xc.f = 0; // expected-error{{cannot assign to variable 'xc' with const-qualified type 'const struct X'}} + xc.a = 0; // expected-error{{cannot assign to variable 'xc' with const-qualified type 'const struct X'}} } diff --git a/test/Sema/assign.c b/test/Sema/assign.c index 2d57029fc0..1fff778644 100644 --- a/test/Sema/assign.c +++ b/test/Sema/assign.c @@ -3,7 +3,10 @@ void *test1(void) { return 0; } void test2 (const struct {int a;} *x) { - x->a = 10; // expected-error {{read-only variable is not assignable}} + // expected-note@-1 {{variable 'x' declared const here}} + + x->a = 10; + // expected-error-re@-1 {{cannot assign to variable 'x' with const-qualified type 'const struct (anonymous struct at {{.*}}assign.c:5:19) *'}} } typedef int arr[10]; diff --git a/test/Sema/block-misc.c b/test/Sema/block-misc.c index 0ca4f20f36..c57b3e1410 100644 --- a/test/Sema/block-misc.c +++ b/test/Sema/block-misc.c @@ -184,8 +184,8 @@ void test17() { } void test18() { - void (^const blockA)(void) = ^{ }; - blockA = ^{ }; // expected-error {{read-only variable is not assignable}} + void (^const blockA)(void) = ^{ }; // expected-note {{variable 'blockA' declared const here}} + blockA = ^{ }; // expected-error {{cannot assign to variable 'blockA' with const-qualified type 'void (^const)(void)}} } // rdar://7072507 diff --git a/test/Sema/builtin-assume.c b/test/Sema/builtin-assume.c index 512eeeccdc..43b31375f2 100644 --- a/test/Sema/builtin-assume.c +++ b/test/Sema/builtin-assume.c @@ -1,16 +1,28 @@ // RUN: %clang_cc1 -triple i386-mingw32 -fms-extensions -fsyntax-only -verify %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify %s +int nonconst(void); +int isconst(void) __attribute__((const)); +int ispure(int) __attribute__((pure)); + int foo(int *a, int i) { #ifdef _MSC_VER __assume(i != 4); __assume(++i > 2); //expected-warning {{the argument to '__assume' has side effects that will be discarded}} + __assume(nonconst() > 2); //expected-warning {{the argument to '__assume' has side effects that will be discarded}} + __assume(isconst() > 2); + __assume(ispure(i) > 2); + __assume(ispure(++i) > 2); //expected-warning {{the argument to '__assume' has side effects that will be discarded}} int test = sizeof(struct{char qq[(__assume(i != 5), 7)];}); #else __builtin_assume(i != 4); __builtin_assume(++i > 2); //expected-warning {{the argument to '__builtin_assume' has side effects that will be discarded}} - + __builtin_assume(nonconst() > 2); //expected-warning {{the argument to '__builtin_assume' has side effects that will be discarded}} + __builtin_assume(isconst() > 2); + __builtin_assume(ispure(i) > 2); + __builtin_assume(ispure(++i) > 2); //expected-warning {{the argument to '__builtin_assume' has side effects that will be discarded}} + int test = sizeof(struct{char qq[(__builtin_assume(i != 5), 7)];}); #endif return a[i]; diff --git a/test/Sema/builtins-ppc.c b/test/Sema/builtins-ppc.c new file mode 100644 index 0000000000..60872a614e --- /dev/null +++ b/test/Sema/builtins-ppc.c @@ -0,0 +1,51 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -faltivec -target-feature +htm \ +// RUN: -triple powerpc64-unknown-unknown -DTEST_HTM -fsyntax-only \ +// RUN: -verify %s + +// RUN: %clang_cc1 -faltivec -target-feature +crypto \ +// RUN: -triple powerpc64le-unknown-unknown -DTEST_CRYPTO -fsyntax-only \ +// RUN: -verify %s + +#ifdef TEST_HTM +void test_htm() { + __builtin_tbegin(4); // expected-error {{argument should be a value from 0 to 1}} + __builtin_tend(-1); // expected-error {{argument should be a value from 0 to 1}} + __builtin_tsr(55); // expected-error {{argument should be a value from 0 to 7}} + __builtin_tabortwc(-5, 2, 3); // expected-error {{argument should be a value from 0 to 31}} + __builtin_tabortdc(55, 2, 3); // expected-error {{argument should be a value from 0 to 31}} + __builtin_tabortwci(-5, 2, 5); // expected-error {{argument should be a value from 0 to 31}} + __builtin_tabortwci(5, 2, 55); // expected-error {{argument should be a value from 0 to 31}} + __builtin_tabortdci(-5, 2, 5); // expected-error {{argument should be a value from 0 to 31}} + __builtin_tabortdci(5, 2, 55); // expected-error {{argument should be a value from 0 to 31}} +} +#endif + + +#ifdef TEST_CRYPTO +#include <altivec.h> + +#define W_INIT { 0x01020304, 0x05060708, 0x090A0B0C, 0x0D0E0F10 }; +#define D_INIT { 0x0102030405060708, 0x090A0B0C0D0E0F10 }; +vector unsigned int test_vshasigmaw_or(void) +{ + vector unsigned int a = W_INIT + vector unsigned int b = __builtin_crypto_vshasigmaw(a, 2, 15); // expected-error {{argument should be a value from 0 to 1}} + vector unsigned int c = __builtin_crypto_vshasigmaw(a, -1, 15); // expected-error {{argument should be a value from 0 to 1}} + vector unsigned int d = __builtin_crypto_vshasigmaw(a, 0, 85); // expected-error {{argument should be a value from 0 to 15}} + vector unsigned int e = __builtin_crypto_vshasigmaw(a, 1, -15); // expected-error {{argument should be a value from 0 to 15}} + return __builtin_crypto_vshasigmaw(a, 1, 15); +} + +vector unsigned long long test_vshasigmad_or(void) +{ + vector unsigned long long a = D_INIT + vector unsigned long long b = __builtin_crypto_vshasigmad(a, 2, 15); // expected-error {{argument should be a value from 0 to 1}} + vector unsigned long long c = __builtin_crypto_vshasigmad(a, -1, 15); // expected-error {{argument should be a value from 0 to 1}} + vector unsigned long long d = __builtin_crypto_vshasigmad(a, 0, 85); // expected-error {{argument should be a value from 0 to 1}} + vector unsigned long long e = __builtin_crypto_vshasigmad(a, 1, -15); // expected-error {{argument should be a value from 0 to 1}} + return __builtin_crypto_vshasigmad(a, 0, 15); +} + +#endif + diff --git a/test/Sema/builtins.cl b/test/Sema/builtins.cl new file mode 100644 index 0000000000..8cde8f3d10 --- /dev/null +++ b/test/Sema/builtins.cl @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic +// expected-no-diagnostics + +kernel void test(global float *out, global float *in, global int* in2) { + out[0] = __builtin_nanf(""); + __builtin_memcpy(out, in, 32); + out[0] = __builtin_frexpf(in[0], in2); +} diff --git a/test/Sema/member-reference.c b/test/Sema/member-reference.c index 8939fd5157..4004673dfd 100644 --- a/test/Sema/member-reference.c +++ b/test/Sema/member-reference.c @@ -20,5 +20,5 @@ void g(void) { } int PR17762(struct simple c) { - return c->i; // expected-error {{member reference type 'struct simple' is not a pointer; maybe you meant to use '.'?}} + return c->i; // expected-error {{member reference type 'struct simple' is not a pointer; did you mean to use '.'?}} } diff --git a/test/Sema/pragma-section-invalid.c b/test/Sema/pragma-section-invalid.c new file mode 100644 index 0000000000..b9075c4550 --- /dev/null +++ b/test/Sema/pragma-section-invalid.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple x86_64-apple-darwin + +// expected-error@+1 {{argument to 'section' attribute is not valid for this target: mach-o section specifier requires a segment and section separated by a comma}} +#pragma data_seg(".my_const") +int a = 1; +#pragma data_seg("__THINGY,thingy") +int b = 1; diff --git a/test/Sema/vla.c b/test/Sema/vla.c index e03dda8c5f..b9576bf8cf 100644 --- a/test/Sema/vla.c +++ b/test/Sema/vla.c @@ -61,6 +61,9 @@ void pr5185(int a[*]) // expected-error {{variable length array must be bound in { } +void pr23151(int (*p1)[*]) // expected-error {{variable length array must be bound in function definition}} +{} + // Make sure this isn't treated as an error int TransformBug(int a) { return sizeof(*(int(*)[({ goto v; v: a;})]) 0); // expected-warning {{use of GNU statement expression extension}} diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp index 4375cfcf56..5d866359aa 100644 --- a/test/Sema/warn-documentation.cpp +++ b/test/Sema/warn-documentation.cpp @@ -1038,6 +1038,12 @@ int test_nocrash12(); ///@param x@param y int test_nocrash13(int x, int y); +/** + * \verbatim + * Aaa + **/ +int test_nocrash14(); + // rdar://12379114 // expected-warning@+2 {{'@union' command should not be used in a comment attached to a non-union declaration}} /*! diff --git a/test/SemaCUDA/function-target-disabled-check.cu b/test/SemaCUDA/function-target-disabled-check.cu new file mode 100644 index 0000000000..979d4edbf8 --- /dev/null +++ b/test/SemaCUDA/function-target-disabled-check.cu @@ -0,0 +1,26 @@ +// Test that we can disable cross-target call checks in Sema with the +// -fcuda-disable-target-call-checks flag. Without this flag we'd get a bunch +// of errors here, since there are invalid cross-target calls present. + +// RUN: %clang_cc1 -fsyntax-only -verify %s -fcuda-disable-target-call-checks +// RUN: %clang_cc1 -fsyntax-only -fcuda-is-device -verify %s -fcuda-disable-target-call-checks + +// expected-no-diagnostics + +#define __device__ __attribute__((device)) +#define __global__ __attribute__((global)) +#define __host__ __attribute__((host)) + +__attribute__((host)) void h1(); + +__attribute__((device)) void d1() { + h1(); +} + +__attribute__((host)) void h2() { + d1(); +} + +__attribute__((global)) void g1() { + h2(); +} diff --git a/test/SemaCXX/alignof.cpp b/test/SemaCXX/alignof.cpp index f51146ccd3..e3690ea926 100644 --- a/test/SemaCXX/alignof.cpp +++ b/test/SemaCXX/alignof.cpp @@ -84,3 +84,16 @@ template <typename T> void n(T) { static_assert(sizeof(k) == alignof(long long), ""); } template void n(long long); + +namespace PR22042 { +template <typename T> +void Fun(T A) { + typedef int __attribute__((__aligned__(A))) T1; // expected-error {{requested alignment is dependent but declaration is not dependent}} + int k1[__alignof__(T1)]; +} + +template <int N> +struct S { + typedef __attribute__((aligned(N))) int Field[sizeof(N)]; // expected-error {{requested alignment is dependent but declaration is not dependent}} +}; +} diff --git a/test/SemaCXX/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp index 46d426cf0c..3520245a03 100644 --- a/test/SemaCXX/anonymous-union.cpp +++ b/test/SemaCXX/anonymous-union.cpp @@ -39,13 +39,14 @@ void X::test_unqual_references() { a = 0; } -void X::test_unqual_references_const() const { +void X::test_unqual_references_const() const { // expected-note 2{{member function 'X::test_unqual_references_const' is declared const here}} d = 0.0; - f2 = 0; // expected-error{{read-only variable is not assignable}} - a = 0; // expected-error{{read-only variable is not assignable}} + f2 = 0; // expected-error{{cannot assign to non-static data member within const member function 'test_unqual_references_const'}} + a = 0; // expected-error{{cannot assign to non-static data member within const member function 'test_unqual_references_const'}} } void test_unqual_references(X x, const X xc) { + // expected-note@-1 2{{variable 'xc' declared const here}} x.i = 0; x.f = 0.0; x.f2 = x.f; @@ -54,8 +55,8 @@ void test_unqual_references(X x, const X xc) { x.a = 0; xc.d = 0.0; - xc.f = 0; // expected-error{{read-only variable is not assignable}} - xc.a = 0; // expected-error{{read-only variable is not assignable}} + xc.f = 0; // expected-error{{cannot assign to variable 'xc' with const-qualified type 'const X'}} + xc.a = 0; // expected-error{{cannot assign to variable 'xc' with const-qualified type 'const X'}} } diff --git a/test/SemaCXX/captured-statements.cpp b/test/SemaCXX/captured-statements.cpp index 5fb686c3c9..d8f77e6017 100644 --- a/test/SemaCXX/captured-statements.cpp +++ b/test/SemaCXX/captured-statements.cpp @@ -81,11 +81,11 @@ void test_capture_var() { } template <typename S, typename T> -S template_capture_var(S x, T y) { +S template_capture_var(S x, T y) { // expected-note{{variable 'y' declared const here}} #pragma clang _debug captured { x++; - y++; // expected-error{{read-only variable is not assignable}} + y++; // expected-error{{cannot assign to variable 'y' with const-qualified type 'const int'}} } return x; diff --git a/test/SemaCXX/cxx0x-constexpr-const.cpp b/test/SemaCXX/cxx0x-constexpr-const.cpp index 197edeb097..a4398b32a1 100644 --- a/test/SemaCXX/cxx0x-constexpr-const.cpp +++ b/test/SemaCXX/cxx0x-constexpr-const.cpp @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -constexpr int x = 1; +constexpr int x = 1; // expected-note {{variable 'x' declared const here}} constexpr int id(int x) { return x; } void foo(void) { - x = 2; // expected-error {{read-only variable is not assignable}} + x = 2; // expected-error {{cannot assign to variable 'x' with const-qualified type 'const int'}} int (*idp)(int) = id; } diff --git a/test/SemaCXX/cxx11-ast-print.cpp b/test/SemaCXX/cxx11-ast-print.cpp index 5604374c56..27726dedb4 100644 --- a/test/SemaCXX/cxx11-ast-print.cpp +++ b/test/SemaCXX/cxx11-ast-print.cpp @@ -38,6 +38,11 @@ const char *p8 = 4.9_quux; const char *p9 = 0x42e3F_fritz; // CHECK: const char *p10 = 3.300e+15_fritz; const char *p10 = 3.300e+15_fritz; + +template <class C, C...> const char *operator"" _suffix(); +// CHECK: const char *PR23120 = operator "" _suffix<char32_t, 66615>(); +const char *PR23120 = U"𐐷"_suffix; + // CHECK: ; ; // CHECK-NOT: ; diff --git a/test/SemaCXX/cxx11-call-to-deleted-constructor.cpp b/test/SemaCXX/cxx11-call-to-deleted-constructor.cpp new file mode 100644 index 0000000000..dd04345281 --- /dev/null +++ b/test/SemaCXX/cxx11-call-to-deleted-constructor.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// rdar://20281011 + +namespace std { +template<class _Ep> class initializer_list { }; +} + +namespace cva { + +template <class VT, unsigned int ROWS = 0, unsigned int COLS = 0> +class Matrix { +public: + + typedef VT value_type; + inline __attribute__((always_inline)) value_type& at(); +}; + +template <class VT, unsigned int SIZE> using Vector = Matrix<VT, SIZE, 1>; + +template <class VT> +using RGBValue = Vector<VT, 3>; +using RGBFValue = RGBValue<float>; + +template <class VT> class Matrix<VT, 0, 0> { // expected-note {{passing argument to parameter here}} +public: + typedef VT value_type; + Matrix(const unsigned int nRows, const unsigned int nColumns, const value_type* data = nullptr); + + Matrix(const std::initializer_list<value_type>& list) = delete; // expected-note {{'Matrix' has been explicitly marked deleted here}} + +}; + +void getLaplacianClosedForm() +{ + Matrix<double> winI(0, 3); + RGBFValue* inputPreL; + winI = { inputPreL->at() }; // expected-error {{call to deleted constructor of 'cva::Matrix<double, 0, 0> &&'}} +} + +} diff --git a/test/SemaCXX/decl-microsoft-call-conv.cpp b/test/SemaCXX/decl-microsoft-call-conv.cpp index a4b68cdbc7..6c392ea942 100644 --- a/test/SemaCXX/decl-microsoft-call-conv.cpp +++ b/test/SemaCXX/decl-microsoft-call-conv.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -verify %s -// RUN: %clang_cc1 -triple i686-pc-mingw32 -verify %s -// RUN: %clang_cc1 -triple i686-pc-mingw32 -fms-extensions -verify %s +// RUN: %clang_cc1 -std=c++14 -triple i686-pc-win32 -fms-extensions -verify %s +// RUN: %clang_cc1 -std=c++14 -triple i686-pc-mingw32 -verify %s +// RUN: %clang_cc1 -std=c++14 -triple i686-pc-mingw32 -fms-extensions -verify %s typedef void void_fun_t(); typedef void __cdecl cdecl_fun_t(); @@ -242,3 +242,19 @@ namespace test8 { s.f(p); // expected-note {{in instantiation of member function 'test8::S<void *>::f' requested here}} } } + +namespace test9 { + // Used to fail when we forgot to make lambda call operators use __thiscall. + template <typename F> + decltype(auto) deduce(F f) { + return &decltype(f)::operator(); + } + template <typename C, typename R, typename A> + decltype(auto) signaturehelper(R (C::*f)(A) const) { + return R(); + } + void f() { + auto l = [](int x) { return x * 2; }; + decltype(signaturehelper(deduce(l))) p; + } +} diff --git a/test/SemaCXX/enum-bitfield.cpp b/test/SemaCXX/enum-bitfield.cpp index ec849b79a7..676ae44b37 100644 --- a/test/SemaCXX/enum-bitfield.cpp +++ b/test/SemaCXX/enum-bitfield.cpp @@ -28,3 +28,11 @@ struct D { A::B : C; }; } + +enum WithUnderlying : unsigned { wu_value }; +struct WithUnderlyingBitfield { + WithUnderlying wu : 3; +} wu = { wu_value }; +int want_unsigned(unsigned); +int want_unsigned(int) = delete; +int check_enum_bitfield_promotes_correctly = want_unsigned(wu.wu); diff --git a/test/SemaCXX/err_typecheck_assign_const.cpp b/test/SemaCXX/err_typecheck_assign_const.cpp new file mode 100644 index 0000000000..376b6e6491 --- /dev/null +++ b/test/SemaCXX/err_typecheck_assign_const.cpp @@ -0,0 +1,124 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +const int global = 5; // expected-note{{variable 'global' declared const here}} +void test1() { + global = 2; // expected-error{{cannot assign to variable 'global' with const-qualified type 'const int'}} +} + +void test2 () { + const int local = 5; // expected-note{{variable 'local' declared const here}} + local = 0; // expected-error{{cannot assign to variable 'local' with const-qualified type 'const int'}} +} + +void test2 (const int parameter) { // expected-note{{variable 'parameter' declared const here}} + parameter = 2; // expected-error{{cannot assign to variable 'parameter' with const-qualified type 'const int'}} +} + +class test3 { + int field; + const int const_field = 1; // expected-note 2{{non-static data member 'const_field' declared const here}} + static const int static_const_field = 1; // expected-note 2{{variable 'static_const_field' declared const here}} + void test() { + const_field = 4; // expected-error{{cannot assign to non-static data member 'const_field' with const-qualified type 'const int'}} + static_const_field = 4; // expected-error{{cannot assign to variable 'static_const_field' with const-qualified type 'const int'}} + } + void test_const() const { // expected-note 2{{member function 'test3::test_const' is declared const here}} + field = 4; // expected-error{{cannot assign to non-static data member within const member function 'test_const'}} + const_field = 4 ; // expected-error{{cannot assign to non-static data member 'const_field' with const-qualified type 'const int'}} + static_const_field = 4; // expected-error{{cannot assign to variable 'static_const_field' with const-qualified type 'const int'}} + } +}; + +const int &return_const_ref(); // expected-note{{function 'return_const_ref' which returns const-qualified type 'const int &' declared here}} + +void test4() { + return_const_ref() = 10; // expected-error{{cannot assign to return value because function 'return_const_ref' returns a const value}} +} + +struct S5 { + int field; + const int const_field = 4; // expected-note {{non-static data member 'const_field' declared const here}} +}; + +void test5() { + S5 s5; + s5.field = 5; + s5.const_field = 5; // expected-error{{cannot assign to non-static data member 'const_field' with const-qualified type 'const int'}} +} + +struct U1 { + int a = 5; +}; + +struct U2 { + U1 u1; +}; + +struct U3 { + const U2 u2 = U2(); // expected-note{{non-static data member 'u2' declared const here}} +}; + +struct U4 { + U3 u3; +}; + +void test6() { + U4 u4; + u4.u3.u2.u1.a = 5; // expected-error{{cannot assign to non-static data member 'u2' with const-qualified type 'const U2'}} +} + +struct A { + int z; +}; +struct B { + A a; +}; +struct C { + B b; + C(); +}; +const C &getc(); // expected-note{{function 'getc' which returns const-qualified type 'const C &' declared here}} +void test7() { + const C c; // expected-note{{variable 'c' declared const here}} + c.b.a.z = 5; // expected-error{{cannot assign to variable 'c' with const-qualified type 'const C'}} + + getc().b.a.z = 5; // expected-error{{cannot assign to return value because function 'getc' returns a const value}} +} + +struct D { const int n; }; // expected-note 2{{non-static data member 'n' declared const here}} +struct E { D *const d = 0; }; +void test8() { + extern D *const d; + d->n = 0; // expected-error{{cannot assign to non-static data member 'n' with const-qualified type 'const int'}} + + E e; + e.d->n = 0; // expected-error{{cannot assign to non-static data member 'n' with const-qualified type 'const int'}} +} + +struct F { int n; }; +struct G { const F *f; }; // expected-note{{non-static data member 'f' declared const here}} +void test10() { + const F *f; // expected-note{{variable 'f' declared const here}} + f->n = 0; // expected-error{{cannot assign to variable 'f' with const-qualified type 'const F *'}} + + G g; + g.f->n = 0; // expected-error{{cannot assign to non-static data member 'f' with const-qualified type 'const F *'}} +} + +void test11( + const int x, // expected-note{{variable 'x' declared const here}} + const int& y // expected-note{{variable 'y' declared const here}} + ) { + x = 5; // expected-error{{cannot assign to variable 'x' with const-qualified type 'const int'}} + y = 5; // expected-error{{cannot assign to variable 'y' with const-qualified type 'const int &'}} +} + +struct H { + const int a = 0; // expected-note{{non-static data member 'a' declared const here}} + const int &b = a; // expected-note{{non-static data member 'b' declared const here}} +}; + +void test12(H h) { + h.a = 1; // expected-error {{cannot assign to non-static data member 'a' with const-qualified type 'const int'}} + h.b = 2; // expected-error {{cannot assign to non-static data member 'b' with const-qualified type 'const int &'}} +} diff --git a/test/SemaCXX/err_typecheck_assign_const_filecheck.cpp b/test/SemaCXX/err_typecheck_assign_const_filecheck.cpp new file mode 100644 index 0000000000..0d29b1e12f --- /dev/null +++ b/test/SemaCXX/err_typecheck_assign_const_filecheck.cpp @@ -0,0 +1,252 @@ +// RUN: not %clang_cc1 -fsyntax-only -std=c++11 %s 2>&1 | FileCheck %s + +struct E { + int num; + const int Cnum = 0; + mutable int Mnum; + static int Snum; + const static int CSnum; +}; + +struct D { + E e; + const E Ce; + mutable E Me; + static E Se; + const static E CSe; + E &getE() const; + const E &getCE() const; +}; + +struct C { + D d; + const D Cd; + mutable D Md; + static D Sd; + const static D CSd; + D &getD() const; + const D &getCD() const; +}; + +struct B { + C c; + const C Cc; + mutable C Mc; + static C Sc; + const static C CSc; + C &getC() const; + static C &getSC(); + const C &getCC() const; + static const C &getSCC(); +}; + +struct A { + B b; + const B Cb; + mutable B Mb; + static B Sb; + const static B CSb; + B &getB() const; + static B &getSB(); + const B &getCB() const; + static const B &getSCB(); +}; + +A& getA(); + +// Valid assignment +void test1(A a, const A Ca) { + a.b.c.d.e.num = 5; + a.b.c.d.e.Mnum = 5; + Ca.b.c.d.e.Mnum = 5; + a.b.c.d.e.Snum = 5; + Ca.b.c.d.e.Snum = 5; + Ca.b.c.Md.e.num = 5; + Ca.Mb.Cc.d.e.Mnum = 5; + Ca.Mb.getC().d.e.num = 5; + Ca.getSB().c.d.e.num = 5; + a.getSCB().c.d.Me.num = 5; + Ca.Cb.Cc.Cd.Ce.Snum = 5; + // CHECK-NOT: error: + // CHECK-NOT: note: +} + +// One note +void test2(A a, const A Ca) { + Ca.b.c.d.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ca' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ca' + // CHECK-NOT: note: + + a.Cb.c.d.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cb' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cb' + // CHECK-NOT: note: + + a.b.c.Cd.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + + a.b.c.d.e.CSnum = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'CSnum' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'CSnum' + // CHECK-NOT: note: + + a.b.c.d.e.Cnum = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cnum' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cnum' + // CHECK-NOT: note: + + a.getCB().c.d.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'getCB' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'getCB' + // CHECK-NOT: note: + + a.getSCB().c.d.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'getSCB' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'getSCB' + // CHECK-NOT: note: +} + +// Two notes +void test3(A a, const A Ca) { + + a.getSCB().Cc.d.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cc' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cc' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'getSCB' + // CHECK-NOT: note: + + Ca.b.c.Cd.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ca' + // CHECK-NOT: note: + + a.getCB().c.Cd.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'getCB' + // CHECK-NOT: note: + + a.b.getCC().d.e.Cnum = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cnum' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cnum' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'getCC' + // CHECK-NOT: note: + + a.b.c.Cd.Ce.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + + a.b.CSc.Cd.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'CSc' + // CHECK-NOT: note: + + a.CSb.c.Cd.e.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Cd' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'CSb' + // CHECK-NOT: note: +} + +// No errors +void test4(const A Ca) { + // Mutable cases + Ca.Mb.c.d.e.num = 5; + Ca.CSb.Mc.d.e.num = 5; + Ca.getCB().Mc.d.e.num = 5; + Ca.getSCB().Mc.d.e.num = 5; + + // Returning non-const reference + Ca.getB().c.d.e.num = 5; + Ca.CSb.getC().d.e.num = 5; + Ca.getCB().getC().d.e.num = 5; + Ca.getSCB().getC().d.e.num = 5; + + // Returning non-const reference + Ca.getSB().c.d.e.num = 5; + Ca.CSb.getSC().d.e.num = 5; + Ca.getCB().getSC().d.e.num = 5; + Ca.getSCB().getSC().d.e.num = 5; + + // Static member + Ca.Sb.c.d.e.num = 5; + Ca.CSb.Sc.d.e.num = 5; + Ca.getCB().Sc.d.e.num = 5; + Ca.getSCB().Sc.d.e.num = 5; + + // CHECK-NOT: error: + // CHECK-NOT: note: +} + +// Only display notes for relavent cases. +void test5(const A Ca) { + Ca.Mb.c.d.Ce.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ce' + // CHECK-NOT: note: + + Ca.getB().c.d.Ce.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ce' + // CHECK-NOT: note: + + Ca.getSB().c.d.Ce.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ce' + // CHECK-NOT: note: + + Ca.Sb.c.d.Ce.num = 5; + // CHECK-NOT: error: + // CHECK: error:{{.*}} 'Ce' + // CHECK-NOT: note: + // CHECK: note:{{.*}} 'Ce' + // CHECK-NOT: note: +} diff --git a/test/SemaCXX/exceptions.cpp b/test/SemaCXX/exceptions.cpp index 6ac51b32e4..9802a1a1d6 100644 --- a/test/SemaCXX/exceptions.cpp +++ b/test/SemaCXX/exceptions.cpp @@ -146,6 +146,82 @@ namespace Decay { void rval_ref() throw (int &&); // expected-error {{rvalue reference type 'int &&' is not allowed in exception specification}} expected-warning {{C++11}} +namespace HandlerInversion { +struct B {}; +struct D : B {}; +struct D2 : D {}; + +void f1() { + try { + } catch (B &b) { // expected-note {{for type 'HandlerInversion::B &'}} + } catch (D &d) { // expected-warning {{exception of type 'HandlerInversion::D &' will be caught by earlier handler}} + } +} + +void f2() { + try { + } catch (B *b) { // expected-note {{for type 'HandlerInversion::B *'}} + } catch (D *d) { // expected-warning {{exception of type 'HandlerInversion::D *' will be caught by earlier handler}} + } +} + +void f3() { + try { + } catch (D &d) { // Ok + } catch (B &b) { + } +} + +void f4() { + try { + } catch (B &b) { // Ok + } +} + +void f5() { + try { + } catch (int) { + } catch (float) { + } +} + +void f6() { + try { + } catch (B &b) { // expected-note {{for type 'HandlerInversion::B &'}} + } catch (D2 &d) { // expected-warning {{exception of type 'HandlerInversion::D2 &' will be caught by earlier handler}} + } +} + +void f7() { + try { + } catch (B *b) { // Ok + } catch (D &d) { // Ok + } + + try { + } catch (B b) { // Ok + } catch (D *d) { // Ok + } +} + +void f8() { + try { + } catch (const B &b) { // expected-note {{for type 'const HandlerInversion::B &'}} + } catch (D2 &d) { // expected-warning {{exception of type 'HandlerInversion::D2 &' will be caught by earlier handler}} + } + + try { + } catch (B &b) { // expected-note {{for type 'HandlerInversion::B &'}} + } catch (const D2 &d) { // expected-warning {{exception of type 'const HandlerInversion::D2 &' will be caught by earlier handler}} + } + + try { + } catch (B b) { // expected-note {{for type 'HandlerInversion::B'}} + } catch (D &d) { // expected-warning {{exception of type 'HandlerInversion::D &' will be caught by earlier handler}} + } +} +} + namespace ConstVolatileThrow { struct S { S() {} // expected-note{{candidate constructor not viable}} diff --git a/test/SemaCXX/function-type-qual.cpp b/test/SemaCXX/function-type-qual.cpp index 613ac9b200..bb25c17e83 100644 --- a/test/SemaCXX/function-type-qual.cpp +++ b/test/SemaCXX/function-type-qual.cpp @@ -17,8 +17,8 @@ class C { x = 0; } - void m2() const { - x = 0; // expected-error {{read-only variable is not assignable}} + void m2() const { // expected-note {{member function 'C::m2' is declared const here}} + x = 0; // expected-error {{cannot assign to non-static data member within const member function 'm2'}} } int x; diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp index f5ca76c38c..9db95e80d0 100644 --- a/test/SemaCXX/functional-cast.cpp +++ b/test/SemaCXX/functional-cast.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s // REQUIRES: LP64 // ------------ not interpreted as C-style cast ------------ @@ -11,7 +11,7 @@ struct InitViaConstructor { InitViaConstructor(int i = 7); }; -struct NoValueInit { // expected-note 2 {{candidate constructor (the implicit copy constructor)}} +struct NoValueInit { // expected-note 2 {{candidate constructor (the implicit copy constructor)}} expected-note 2 {{candidate constructor (the implicit move constructor)}} NoValueInit(int i, int j); // expected-note 2 {{candidate constructor}} }; @@ -25,6 +25,7 @@ void test_cxx_function_cast_multi() { (void)NoValueInit(0, 0); (void)NoValueInit(0, 0, 0); // expected-error{{no matching constructor for initialization}} (void)int(1, 2); // expected-error{{excess elements in scalar initializer}} + (void)int({}, 2); // expected-error{{excess elements in scalar initializer}} } diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp index e0955aeb9c..5b3393efc0 100644 --- a/test/SemaCXX/member-expr.cpp +++ b/test/SemaCXX/member-expr.cpp @@ -87,7 +87,7 @@ namespace test5 { } void test2(A &x) { - x->A::foo<int>(); // expected-error {{'test5::A' is not a pointer; maybe you meant to use '.'?}} + x->A::foo<int>(); // expected-error {{'test5::A' is not a pointer; did you mean to use '.'?}} } } @@ -181,7 +181,7 @@ namespace PR15045 { int f() { Cl0 c; - return c->a; // expected-error {{member reference type 'PR15045::Cl0' is not a pointer; maybe you meant to use '.'?}} + return c->a; // expected-error {{member reference type 'PR15045::Cl0' is not a pointer; did you mean to use '.'?}} } struct bar { @@ -202,7 +202,7 @@ namespace PR15045 { foo f; // Show that recovery has happened by also triggering typo correction - e->Func(); // expected-error {{member reference type 'PR15045::bar' is not a pointer; maybe you meant to use '.'?}} \ + e->Func(); // expected-error {{member reference type 'PR15045::bar' is not a pointer; did you mean to use '.'?}} \ // expected-error {{no member named 'Func' in 'PR15045::bar'; did you mean 'func'?}} // Make sure a fixit isn't given in the case that the '->' isn't actually @@ -221,6 +221,6 @@ namespace pr16676 { int f(S* s) { T t; return t.get_s // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}} - .i; // expected-error {{member reference type 'pr16676::S *' is a pointer; maybe you meant to use '->'}} + .i; // expected-error {{member reference type 'pr16676::S *' is a pointer; did you mean to use '->'}} } } diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp index 3971881a6b..45f1eafba1 100644 --- a/test/SemaCXX/pseudo-destructors.cpp +++ b/test/SemaCXX/pseudo-destructors.cpp @@ -46,7 +46,7 @@ void f(A* a, Foo *f, int *i, double *d, int ii) { i->N::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}} i->Integer::~Double(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('Double' (aka 'double')) in pseudo-destructor expression}} - ii->~Integer(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}} + ii->~Integer(); // expected-error{{member reference type 'int' is not a pointer; did you mean to use '.'?}} ii.~Integer(); cv_test(a); diff --git a/test/SemaCXX/typo-correction-cxx11.cpp b/test/SemaCXX/typo-correction-cxx11.cpp new file mode 100644 index 0000000000..573c6aa117 --- /dev/null +++ b/test/SemaCXX/typo-correction-cxx11.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +namespace PR23186 { +decltype(ned); // expected-error-re {{use of undeclared identifier 'ned'{{$}}}} +// The code below was triggering an UNREACHABLE in ASTContext::getTypeInfoImpl +// once the above code failed to recover properly after making the bogus +// correction of 'ned' to 'new'. +template <typename> +struct S { + enum { V }; + void f() { + switch (0) + case V: + ; + } +}; +} diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp index 324900150c..174b1403e2 100644 --- a/test/SemaCXX/typo-correction.cpp +++ b/test/SemaCXX/typo-correction.cpp @@ -634,3 +634,9 @@ namespace testArraySubscriptIndex { } }; } + +namespace crash_has_include { +int has_include(int); // expected-note {{'has_include' declared here}} +// expected-error@+1 {{__has_include must be used within a preprocessing directive}} +int foo = __has_include(42); // expected-error {{use of undeclared identifier '__has_include'; did you mean 'has_include'?}} +} diff --git a/test/SemaCXX/unreachable-catch-clauses.cpp b/test/SemaCXX/unreachable-catch-clauses.cpp index c75067f393..8dcb47b13c 100644 --- a/test/SemaCXX/unreachable-catch-clauses.cpp +++ b/test/SemaCXX/unreachable-catch-clauses.cpp @@ -8,7 +8,6 @@ void f(); void test() try {} -catch (BaseEx &e) { f(); } -catch (Ex1 &e) { f(); } // expected-note {{for type class Ex1 &}} -catch (Ex2 &e) { f(); } // expected-warning {{exception of type Ex2 & will be caught by earlier handler}} - +catch (BaseEx &e) { f(); } // expected-note 2{{for type 'BaseEx &'}} +catch (Ex1 &e) { f(); } // expected-warning {{exception of type 'Ex1 &' will be caught by earlier handler}} +catch (Ex2 &e) { f(); } // expected-warning {{exception of type 'Ex2 &' (aka 'Ex1 &') will be caught by earlier handler}} diff --git a/test/SemaCXX/vla.cpp b/test/SemaCXX/vla.cpp index dae6450553..6efb648e78 100644 --- a/test/SemaCXX/vla.cpp +++ b/test/SemaCXX/vla.cpp @@ -17,3 +17,6 @@ namespace PR18581 { incomplete c[n]; // expected-error {{incomplete}} } } + +void pr23151(int (&)[*]) { // expected-error {{variable length array must be bound in function definition}} +} diff --git a/test/SemaCXX/warn-consumed-analysis.cpp b/test/SemaCXX/warn-consumed-analysis.cpp index 977b862a92..0a6aed6186 100644 --- a/test/SemaCXX/warn-consumed-analysis.cpp +++ b/test/SemaCXX/warn-consumed-analysis.cpp @@ -638,6 +638,18 @@ void testWhileLoop1() { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} } +// Tests if state information is correctly discarded for certain shapes of CFGs. +void testSwitchGOTO(void) { + int a; + + LABEL0: + switch (a) + case 0: + goto LABEL0; + + goto LABEL0; +} + typedef const int*& IntegerPointerReference; void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {} diff --git a/test/SemaCXX/warn-range-loop-analysis.cpp b/test/SemaCXX/warn-range-loop-analysis.cpp new file mode 100644 index 0000000000..91756b970e --- /dev/null +++ b/test/SemaCXX/warn-range-loop-analysis.cpp @@ -0,0 +1,299 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wloop-analysis -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wrange-loop-analysis -verify %s + +template <typename return_type> +struct Iterator { + return_type operator*(); + Iterator operator++(); + bool operator!=(const Iterator); +}; + +template <typename T> +struct Container { + typedef Iterator<T> I; + + I begin(); + I end(); +}; + +struct Foo {}; +struct Bar { + Bar(Foo); + Bar(int); + operator int(); +}; + +// Testing notes: +// test0 checks that the full text of the warnings and notes is correct. The +// rest of the tests checks a smaller portion of the text. +// test1-6 are set in pairs, the odd numbers are the non-reference returning +// versions of the even numbers. +// test7-9 use an array instead of a range object +// tests use all four versions of the loop varaible, const &T, const T, T&, and +// T. Versions producing errors and are commented out. +// +// Conversion chart: +// double <=> int +// int <=> Bar +// double => Bar +// Foo => Bar +// +// Conversions during tests: +// test1-2 +// int => int +// int => double +// int => Bar +// test3-4 +// Bar => Bar +// Bar => int +// test5-6 +// Foo => Bar +// test7 +// double => double +// double => int +// double => Bar +// test8 +// Foo => Foo +// Foo => Bar +// test9 +// Bar => Bar +// Bar => int + +void test0() { + Container<int> int_non_ref_container; + Container<int&> int_container; + Container<Bar&> bar_container; + + for (const int &x : int_non_ref_container) {} + // expected-warning@-1 {{loop variable 'x' is always a copy because the range of type 'Container<int>' does not return a reference}} + // expected-note@-2 {{use non-reference type 'int'}} + + for (const double &x : int_container) {} + // expected-warning@-1 {{loop variable 'x' has type 'const double &' but is initialized with type 'int' resulting in a copy}} + // expected-note@-2 {{use non-reference type 'double' to keep the copy or type 'const int &' to prevent copying}} + + for (const Bar x : bar_container) {} + // expected-warning@-1 {{loop variable 'x' of type 'const Bar' creates a copy from type 'const Bar'}} + // expected-note@-2 {{use reference type 'const Bar &' to prevent copying}} +} + +void test1() { + Container<int> A; + + for (const int &x : A) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'int'}} + for (const int x : A) {} + // No warning, non-reference type indicates copy is made + //for (int &x : A) {} + // Binding error + for (int x : A) {} + // No warning, non-reference type indicates copy is made + + for (const double &x : A) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'double'}} + for (const double x : A) {} + // No warning, non-reference type indicates copy is made + //for (double &x : A) {} + // Binding error + for (double x : A) {} + // No warning, non-reference type indicates copy is made + + for (const Bar &x : A) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'Bar'}} + for (const Bar x : A) {} + // No warning, non-reference type indicates copy is made + //for (Bar &x : A) {} + // Binding error + for (Bar x : A) {} + // No warning, non-reference type indicates copy is made +} + +void test2() { + Container<int&> B; + + for (const int &x : B) {} + // No warning, this reference is not a temporary + for (const int x : B) {} + // No warning on POD copy + for (int &x : B) {} + // No warning + for (int x : B) {} + // No warning + + for (const double &x : B) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'double'{{.*}}'const int &'}} + for (const double x : B) {} + //for (double &x : B) {} + // Binding error + for (double x : B) {} + // No warning + + for (const Bar &x : B) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note@-2 {{'Bar'}} + for (const Bar x : B) {} + //for (Bar &x : B) {} + // Binding error + for (Bar x : B) {} + // No warning +} + +void test3() { + Container<Bar> C; + + for (const Bar &x : C) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'Bar'}} + for (const Bar x : C) {} + // No warning, non-reference type indicates copy is made + //for (Bar &x : C) {} + // Binding error + for (Bar x : C) {} + // No warning, non-reference type indicates copy is made + + for (const int &x : C) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'int'}} + for (const int x : C) {} + // No warning, copy made + //for (int &x : C) {} + // Binding error + for (int x : C) {} + // No warning, copy made +} + +void test4() { + Container<Bar&> D; + + for (const Bar &x : D) {} + // No warning, this reference is not a temporary + for (const Bar x : D) {} + // expected-warning@-1 {{creates a copy}} + // expected-note@-2 {{'const Bar &'}} + for (Bar &x : D) {} + // No warning + for (Bar x : D) {} + // No warning + + for (const int &x : D) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} + for (const int x : D) {} + // No warning + //for (int &x : D) {} + // Binding error + for (int x : D) {} + // No warning +} + +void test5() { + Container<Foo> E; + + for (const Bar &x : E) {} + // expected-warning@-1 {{always a copy}} + // expected-note@-2 {{'Bar'}} + for (const Bar x : E) {} + // No warning, non-reference type indicates copy is made + //for (Bar &x : E) {} + // Binding error + for (Bar x : E) {} + // No warning, non-reference type indicates copy is made +} + +void test6() { + Container<Foo&> F; + + for (const Bar &x : F) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} + for (const Bar x : F) {} + // No warning. + //for (Bar &x : F) {} + // Binding error + for (Bar x : F) {} + // No warning +} + +void test7() { + double G[2]; + + for (const double &x : G) {} + // No warning + for (const double x : G) {} + // No warning on POD copy + for (double &x : G) {} + // No warning + for (double x : G) {} + // No warning + + for (const int &x : G) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'int'{{.*}}'const double &'}} + for (const int x : G) {} + // No warning + //for (int &x : G) {} + // Binding error + for (int x : G) {} + // No warning + + for (const Bar &x : G) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}} + for (const Bar x : G) {} + // No warning + //for (int &Bar : G) {} + // Binding error + for (int Bar : G) {} + // No warning +} + +void test8() { + Foo H[2]; + + for (const Foo &x : H) {} + // No warning + for (const Foo x : H) {} + // No warning on POD copy + for (Foo &x : H) {} + // No warning + for (Foo x : H) {} + // No warning + + for (const Bar &x : H) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} + for (const Bar x : H) {} + // No warning + //for (Bar &x: H) {} + // Binding error + for (Bar x: H) {} + // No warning +} + +void test9() { + Bar I[2] = {1,2}; + + for (const Bar &x : I) {} + // No warning + for (const Bar x : I) {} + // expected-warning@-1 {{creates a copy}} + // expected-note@-2 {{'const Bar &'}} + for (Bar &x : I) {} + // No warning + for (Bar x : I) {} + // No warning + + for (const int &x : I) {} + // expected-warning@-1 {{resulting in a copy}} + // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} + for (const int x : I) {} + // No warning + //for (int &x : I) {} + // Binding error + for (int x : I) {} + // No warning +} diff --git a/test/SemaCXX/warn-unused-result.cpp b/test/SemaCXX/warn-unused-result.cpp index 7bdb4245a9..01bc457ec2 100644 --- a/test/SemaCXX/warn-unused-result.cpp +++ b/test/SemaCXX/warn-unused-result.cpp @@ -44,6 +44,12 @@ void bah() { } namespace warn_unused_CXX11 { +class Status; +class Foo { + public: + Status doStuff(); +}; + struct [[clang::warn_unused_result]] Status { bool ok() const; Status& operator=(const Status& x); @@ -73,10 +79,23 @@ void lazy() { (void)DoYetAnotherThing(); DoSomething(); // expected-warning {{ignoring return value}} - DoSomethingElse(); // expected-warning {{ignoring return value}} - DoAnotherThing(); // expected-warning {{ignoring return value}} + DoSomethingElse(); + DoAnotherThing(); DoYetAnotherThing(); } + +template <typename T> +class [[clang::warn_unused_result]] StatusOr { +}; +StatusOr<int> doit(); +void test() { + Foo f; + f.doStuff(); // expected-warning {{ignoring return value}} + doit(); // expected-warning {{ignoring return value}} + + auto func = []() { return Status(); }; + func(); // expected-warning {{ignoring return value}} +} } namespace PR17587 { diff --git a/test/SemaObjC/arc-bridged-cast.m b/test/SemaObjC/arc-bridged-cast.m index 9e716f9d40..0ba7792146 100644 --- a/test/SemaObjC/arc-bridged-cast.m +++ b/test/SemaObjC/arc-bridged-cast.m @@ -80,3 +80,12 @@ void testObjCBridgeId() { ref = (__bridge_retained CFAnnotatedObjectRef) CreateSomething(); ref = (__bridge_retained CFAnnotatedObjectRef) CreateNSString(); } + +// rdar://20113785 +typedef const struct __attribute__((objc_bridge(UIFont))) __CTFont * CTFontRef; + +id testObjCBridgeUnknownTypeToId(CTFontRef font) { + id x = (__bridge id)font; + return x; +} + diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m index 54a7db7b11..60bd6735db 100644 --- a/test/SemaObjC/arc.m +++ b/test/SemaObjC/arc.m @@ -293,8 +293,8 @@ void test12(id collection) { x = 0; // expected-error {{fast enumeration variables can't be modified in ARC by default; declare the variable __strong to allow this}} } - for (const id x in collection) { - x = 0; // expected-error {{read-only variable is not assignable}} + for (const id x in collection) { // expected-note {{variable 'x' declared const here}} + x = 0; // expected-error {{cannot assign to variable 'x' with const-qualified type 'const __strong id'}} } for (__strong id x in collection) { diff --git a/test/SemaObjC/multiple-property-deprecated-decl.m b/test/SemaObjC/multiple-property-deprecated-decl.m new file mode 100644 index 0000000000..d7dbd458a4 --- /dev/null +++ b/test/SemaObjC/multiple-property-deprecated-decl.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-macosx10.11 -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -triple x86_64-apple-macosx10.11 -verify -Wno-objc-root-class %s +// expected-no-diagnostics +// rdar://20408445 + +@protocol NSFileManagerDelegate @end + +@interface NSFileManager +@property (assign) id <NSFileManagerDelegate> delegate; +@end + +@interface NSFontManager +@property (assign) id delegate __attribute__((availability(macosx,introduced=10.0 ,deprecated=10.11,message="" "NSFontManager doesn't have any delegate method. This property should not be used."))); + +@end + +id Test20408445(id p) { + return [p delegate]; +} diff --git a/test/SemaObjC/nonnull.m b/test/SemaObjC/nonnull.m index cacca07240..e1f31937a5 100644 --- a/test/SemaObjC/nonnull.m +++ b/test/SemaObjC/nonnull.m @@ -123,3 +123,5 @@ void PR18795(int (^g)(const char *h, ...) __attribute__((nonnull(1))) __attribut void PR18795_helper() { PR18795(0); // expected-warning{{null passed to a callee that requires a non-null argument}} } + +void (^PR23117)(int *) = ^(int *p1) __attribute__((nonnull(1))) {}; diff --git a/test/SemaObjC/objc-independent-class-attribute.m b/test/SemaObjC/objc-independent-class-attribute.m new file mode 100644 index 0000000000..2fc13f0cf1 --- /dev/null +++ b/test/SemaObjC/objc-independent-class-attribute.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://20255473 + +@interface NSObject @end + +typedef NSObject * __attribute__((objc_independent_class))dispatch_queue_t; + +typedef struct S {int ii; } * __attribute__((objc_independent_class))dispatch_queue_t_2; // expected-warning {{Objective-C object}} + +typedef struct { // expected-warning {{'objc_independent_class' attribute may be put on a typedef only; attribute is ignored}} + NSObject *__attribute__((objc_independent_class)) ns; // expected-warning {{'objc_independent_class' attribute may be put on a typedef only; attribute is ignored}} +} __attribute__((objc_independent_class)) T; + +dispatch_queue_t dispatch_queue_create(); + +@interface DispatchQPointerCastIssue : NSObject { + NSObject *__attribute__((objc_independent_class)) Ivar; // expected-warning {{'objc_independent_class' attribute may be put on a typedef only; attribute is ignored}} +} + +@property (copy) NSObject *__attribute__((objc_independent_class)) Prop; // expected-warning {{'objc_independent_class' attribute may be put on a typedef only; attribute is ignored}} + +typedef NSObject * __attribute__((objc_independent_class))dispatch_queue_t_1; + +@end + +@implementation DispatchQPointerCastIssue ++ (dispatch_queue_t) newDispatchQueue { + return dispatch_queue_create(); +} +@end + +NSObject *get_nsobject() { + typedef NSObject * __attribute__((objc_independent_class))dispatch_queue_t; + dispatch_queue_t dt; + return dt; +} diff --git a/test/SemaObjC/objcbridge-attribute-arc.m b/test/SemaObjC/objcbridge-attribute-arc.m index e08bd3d023..3bcfdf48e7 100644 --- a/test/SemaObjC/objcbridge-attribute-arc.m +++ b/test/SemaObjC/objcbridge-attribute-arc.m @@ -77,7 +77,8 @@ void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2 // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}} (void)(MyError*)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \ // expected-note {{__bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}} + // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}} \ + // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'MyError'}} (void)(NSUColor *)cf2; // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \ // expected-note {{use __bridge to convert directly (no change in ownership)}} \ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') into ARC}} @@ -216,7 +217,7 @@ void Test8(CFMyPersonalErrorRef cf) { void Test9(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) { (void)(__bridge NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}} (void)(__bridge NSError *)cf; // okay - (void)(__bridge MyError*)cf; // okay, + (void)(__bridge MyError*)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'MyError'}} (void)(__bridge NSUColor *)cf2; // okay (void)(__bridge CFErrorRef)ns; // okay (void)(__bridge CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} diff --git a/test/SemaObjC/objcbridge-attribute.m b/test/SemaObjC/objcbridge-attribute.m index 2969ebef36..9cab64ec6b 100644 --- a/test/SemaObjC/objcbridge-attribute.m +++ b/test/SemaObjC/objcbridge-attribute.m @@ -73,7 +73,7 @@ typedef CFErrorRef1 CFErrorRef2; // expected-note {{declared here}} void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) { (void)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}} (void)(NSError *)cf; // okay - (void)(MyError*)cf; // okay, + (void)(MyError*)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'MyError'}} (void)(NSUColor *)cf2; // okay (void)(CFErrorRef)ns; // okay (void)(CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} @@ -141,3 +141,14 @@ CFDictionaryRef bar() __attribute__((cf_returns_not_retained)); void Test9() { NSNumber *w2 = (NSNumber*) bar(); // expected-error {{CF object of type 'CFDictionaryRef' (aka 'struct __CFDictionary *') is bridged to 'NSDictionary', which is not an Objective-C class}} } + +// rdar://18311183 +@interface NSObject @end + +@interface NSFont : NSObject @end + +typedef struct __attribute__ ((objc_bridge(NSFont))) __CFFontRef * CFFontRef; + +void Test10(CFFontRef cf) { + (void)(__bridge NSObject *)cf; +} diff --git a/test/SemaObjC/objcbridgemutable-attribute.m b/test/SemaObjC/objcbridgemutable-attribute.m index 4ec8de0b54..524e6868fa 100644 --- a/test/SemaObjC/objcbridgemutable-attribute.m +++ b/test/SemaObjC/objcbridgemutable-attribute.m @@ -23,7 +23,8 @@ void Test(NSMutableDictionary *md, NSDictionary *nd, CFMutableDictionaryRef mcf, (void) (CFMutableDictionaryRef)md; (void) (CFMutableDictionaryRef)nd; // expected-warning {{'NSDictionary' cannot bridge to 'CFMutableDictionaryRef' (aka 'struct __CFDictionary *')}} - (void) (NSDictionary *)mcf; // expected-warning {{'CFMutableDictionaryRef' (aka 'struct __CFDictionary *') bridges to NSMutableDictionary, not 'NSDictionary'}} + (void) (NSDictionary *)mcf; // ok, bridgt_type NSMutableDictionary can be type-cast to its super class. + NSDictionary *nsdobj = (NSMutableDictionary*)0; (void) (NSMutableDictionary *)mcf; // ok; (void) (NSMutableDictionary *)bmcf; // expected-error {{CF object of type 'CFMutableDictionaryB2Ref' (aka 'struct __CFDictionaryB2 *') is bridged to 'P', which is not an Objective-C class}} diff --git a/test/SemaObjC/property-9.m b/test/SemaObjC/property-9.m index 4bed8751b6..623143d549 100644 --- a/test/SemaObjC/property-9.m +++ b/test/SemaObjC/property-9.m @@ -106,3 +106,18 @@ id f0(MDATestDocument *d) { return d.instance.path; // expected-error {{property 'path' cannot be found in forward class object 'MDAInstance'}} } +// rdar://20469452 +@interface UIView @end + +@interface FRFakeBannerView : UIView +@end + +@interface FRAdCollectionViewCell +@property (nonatomic, weak, readonly) UIView *bannerView; +@end + +@interface FRAdCollectionViewCell () + +@property (nonatomic, weak, readwrite) FRFakeBannerView *bannerView; + +@end diff --git a/test/SemaObjC/undef-arg-super-method-call.m b/test/SemaObjC/undef-arg-super-method-call.m new file mode 100644 index 0000000000..6a27acb630 --- /dev/null +++ b/test/SemaObjC/undef-arg-super-method-call.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://20350364 + +@interface NSObject @end + +@interface DBGViewDebuggerSupport : NSObject ++ (void)addViewLayerInfo:(id)view; +- (void)addInstViewLayerInfo:(id)view; +@end + +@interface DBGViewDebuggerSupport_iOS : DBGViewDebuggerSupport +@end + +@implementation DBGViewDebuggerSupport_iOS ++ (void)addViewLayerInfo:(id)aView; // expected-note {{'aView' declared here}} +{ + [super addViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'; did you mean 'aView'?}} +} +- (void)addInstViewLayerInfo:(id)aView; // expected-note {{'aView' declared here}} +{ + [super addInstViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'; did you mean 'aView'?}} +} +@end diff --git a/test/SemaObjC/warn-strict-selector-match.m b/test/SemaObjC/warn-strict-selector-match.m index 9f22e73edc..13e9bac462 100644 --- a/test/SemaObjC/warn-strict-selector-match.m +++ b/test/SemaObjC/warn-strict-selector-match.m @@ -13,23 +13,24 @@ int main() { [(id)0 method]; } // expected-warning {{multiple methods named 'met @interface Object @end @interface Class1 -- (void)setWindow:(Object *)wdw; // expected-note {{using}} +- (void)setWindow:(Object *)wdw; // expected-note 2 {{using}} @end @interface Class2 -- (void)setWindow:(Class1 *)window; // expected-note {{also found}} +- (void)setWindow:(Class1 *)window; // expected-note 2 {{also found}} @end id foo(void) { Object *obj = 0; id obj2 = obj; - [obj setWindow:0]; // expected-warning {{Object' may not respond to 'setWindow:'}} + [obj setWindow:0]; // expected-warning {{Object' may not respond to 'setWindow:'}} \ + // expected-warning {{multiple methods named 'setWindow:' found}} [obj2 setWindow:0]; // expected-warning {{multiple methods named 'setWindow:' found}} return obj; } @protocol MyObject -- (id)initWithData:(Object *)data; // expected-note {{using}} +- (id)initWithData:(Object *)data; // expected-note {{also found}} @end @protocol SomeOther @@ -37,7 +38,7 @@ id foo(void) { @end @protocol MyCoding -- (id)initWithData:(id<MyObject, MyCoding>)data; // expected-note {{also found}} +- (id)initWithData:(id<MyObject, MyCoding>)data; // expected-note {{using}} @end @interface NTGridDataObject: Object <MyCoding> @@ -71,3 +72,29 @@ void foo1(void) { [(Class)0 port]; // OK - gcc issues warning but there is only one Class method so no ambiguity to warn } +// rdar://19265430 +@interface NSObject +- (id)class; +- (id) alloc; +@end + +@class NSString; + +@interface A : NSObject +- (instancetype)initWithType:(NSString *)whatever; // expected-note {{also found}} +@end + +@interface Test : NSObject +@end + +@implementation Test ++ (instancetype)foo +{ + return [[[self class] alloc] initWithType:3]; // expected-warning {{multiple methods named 'initWithType:'}} +} + +- (instancetype)initWithType:(unsigned int)whatever // expected-note {{using}} +{ + return 0; +} +@end diff --git a/test/SemaObjCXX/objcbridge-attribute-arc.mm b/test/SemaObjCXX/objcbridge-attribute-arc.mm index 43c8e2b4d2..ccede2afd4 100644 --- a/test/SemaObjCXX/objcbridge-attribute-arc.mm +++ b/test/SemaObjCXX/objcbridge-attribute-arc.mm @@ -62,7 +62,8 @@ void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2 // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} (void)(MyError*)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \ // expected-note {{__bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} + // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} \ + // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'MyError'}} (void)(NSUColor *)cf2; // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka '__CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \ // expected-note {{use __bridge to convert directly (no change in ownership)}} \ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFUColor2Ref' (aka '__CFUPrimeColor *') into ARC}} @@ -201,7 +202,6 @@ void Test8(CFMyPersonalErrorRef cf) { void Test9(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) { (void)(__bridge NSString *)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}} (void)(__bridge NSError *)cf; // okay - (void)(__bridge MyError*)cf; // okay, (void)(__bridge NSUColor *)cf2; // okay (void)(__bridge CFErrorRef)ns; // okay (void)(__bridge CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} diff --git a/test/SemaObjCXX/objcbridge-attribute.mm b/test/SemaObjCXX/objcbridge-attribute.mm index e777774d13..83a3438b74 100644 --- a/test/SemaObjCXX/objcbridge-attribute.mm +++ b/test/SemaObjCXX/objcbridge-attribute.mm @@ -62,7 +62,8 @@ void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2 // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} (void)(MyError*)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \ // expected-note {{__bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} + // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} \ + // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'MyError'}} (void)(NSUColor *)cf2; // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka '__CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \ // expected-note {{use __bridge to convert directly (no change in ownership)}} \ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFUColor2Ref' (aka '__CFUPrimeColor *') into ARC}} @@ -201,7 +202,7 @@ void Test8(CFMyPersonalErrorRef cf) { void Test9(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) { (void)(__bridge NSString *)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}} (void)(__bridge NSError *)cf; // okay - (void)(__bridge MyError*)cf; // okay, + (void)(__bridge MyError*)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'MyError'}} (void)(__bridge NSUColor *)cf2; // okay (void)(__bridge CFErrorRef)ns; // okay (void)(__bridge CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} diff --git a/test/SemaObjCXX/objcbridge-static-cast.mm b/test/SemaObjCXX/objcbridge-static-cast.mm index 97cc5c010a..03e6145740 100644 --- a/test/SemaObjCXX/objcbridge-static-cast.mm +++ b/test/SemaObjCXX/objcbridge-static-cast.mm @@ -62,7 +62,8 @@ void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2 // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} (void)static_cast<MyError*>(cf); // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \ // expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} + // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} \ + // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'MyError'}} (void)static_cast<NSUColor *>(cf2); // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka '__CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \ // expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFUColor2Ref' (aka '__CFUPrimeColor *') into ARC}} diff --git a/test/SemaTemplate/dependent-type-identity.cpp b/test/SemaTemplate/dependent-type-identity.cpp index 5b9da5d892..6b23a38f84 100644 --- a/test/SemaTemplate/dependent-type-identity.cpp +++ b/test/SemaTemplate/dependent-type-identity.cpp @@ -111,7 +111,9 @@ namespace PR18275 { void A<T>::f(int x) { x = 0; } template<typename T> - void A<T>::g(const int x) { x = 0; } // expected-error {{not assignable}} + void A<T>::g(const int x) { // expected-note {{declared const here}} + x = 0; // expected-error {{cannot assign to variable 'x'}} + } template<typename T> void A<T>::h(T) {} // FIXME: Should reject this. Type is different from prior decl if T is an array type. diff --git a/test/SemaTemplate/friend.cpp b/test/SemaTemplate/friend.cpp index e78a067ef8..ef1aed50e6 100644 --- a/test/SemaTemplate/friend.cpp +++ b/test/SemaTemplate/friend.cpp @@ -31,3 +31,19 @@ namespace PR6770 { friend class f1; // expected-error{{'friend' used outside of class}} } } + +namespace friend_redecl_inline { +// We had a bug where instantiating the foo friend declaration would check the +// defined-ness of the most recent decl while checking if the canonical decl was +// inlined. +void foo(); +void bar(); +template <typename T> +class C { + friend void foo(); + friend inline void bar(); +}; +inline void foo() {} +inline void bar() {} +C<int> c; +} |