diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
commit | 4c8b24812ddcd1dedaca343a6d4e76f91f398981 (patch) | |
tree | 137ebebcae16fb0ce7ab4af456992bbd8d22fced /test | |
parent | 5362a71c02e7d448a8ce98cf00c47e353fba5d04 (diff) | |
download | src-4c8b24812ddcd1dedaca343a6d4e76f91f398981.tar.gz src-4c8b24812ddcd1dedaca343a6d4e76f91f398981.zip |
Notes
Diffstat (limited to 'test')
694 files changed, 17634 insertions, 1407 deletions
diff --git a/test/Analysis/CFDateGC.m b/test/Analysis/CFDateGC.m index dfc736627bfc..557e7e8f915c 100644 --- a/test/Analysis/CFDateGC.m +++ b/test/Analysis/CFDateGC.m @@ -1,6 +1,6 @@ -// RUN: clang-cc -analyze -checker-cfref -verify -fobjc-gc -analyzer-constraints=basic %s && -// RUN: clang-cc -analyze -checker-cfref -verify -fobjc-gc -analyzer-constraints=range %s && -// RUN: clang-cc -analyze -checker-cfref -verify -fobjc-gc -disable-free %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=basic %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=range %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify -fobjc-gc -disable-free %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify -fobjc-gc %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify -fobjc-gc %s @@ -25,7 +25,7 @@ extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); typedef struct objc_object {} *id; typedef signed char BOOL; -static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef cf) {} +static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef cf) { return 0; } @protocol NSObject - (BOOL)isEqual:(id)object; - (oneway void)release; - (id)retain; diff --git a/test/Analysis/CheckNSError.m b/test/Analysis/CheckNSError.m index 779b865aff8c..5f92594f30d8 100644 --- a/test/Analysis/CheckNSError.m +++ b/test/Analysis/CheckNSError.m @@ -24,7 +24,7 @@ extern NSString * const NSXMLParserErrorDomain ; @end @implementation A -- (void)myMethodWhichMayFail:(NSError **)error { // expected-warning {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occured.}} +- (void)myMethodWhichMayFail:(NSError **)error { // expected-warning {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occurred}} *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference.}} } @@ -37,7 +37,7 @@ extern NSString * const NSXMLParserErrorDomain ; struct __CFError {}; typedef struct __CFError* CFErrorRef; -void foo(CFErrorRef* error) { // expected-warning {{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occured.}} +void foo(CFErrorRef* error) { // expected-warning {{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occurred}} *error = 0; // expected-warning {{Potential null dereference.}} } diff --git a/test/Analysis/NSPanel.m b/test/Analysis/NSPanel.m index c4d4c22540f2..801620a181bf 100644 --- a/test/Analysis/NSPanel.m +++ b/test/Analysis/NSPanel.m @@ -28,7 +28,7 @@ typedef struct _NSZone NSZone; @end typedef float CGFloat; typedef struct _NSPoint {} NSRect; -static __inline__ __attribute__((always_inline)) NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h) {} +static __inline__ __attribute__((always_inline)) NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h) { NSRect r; return r; } typedef struct {} NSFastEnumerationState; @protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; diff --git a/test/Analysis/NSString.m b/test/Analysis/NSString.m index b707071990f8..0ba3cda6d580 100644 --- a/test/Analysis/NSString.m +++ b/test/Analysis/NSString.m @@ -1,9 +1,7 @@ // RUN: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s && -// RUN: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s - - -// NOTWORK: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s && -// NOTWORK: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s +// RUN: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s && +// RUN: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s && +// RUN: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s //===----------------------------------------------------------------------===// // The following code is reduced using delta-debugging from @@ -157,6 +155,7 @@ NSString* f11(CFDictionaryRef dict, const char* key) { if (s) { [s release]; } + return 0; } // Test case for passing a tracked object by-reference to a function we @@ -285,6 +284,12 @@ void testOSCompareAndSwap32Barrier() { [old release]; } +int testOSCompareAndSwap32Barrier_id(Class myclass, id xclass) { + if (OSAtomicCompareAndSwap32Barrier(0, (int32_t) myclass, (int32_t*) &xclass)) + return 1; + return 0; +} + void test_objc_atomicCompareAndSwap() { NSString *old = 0; NSString *s = [[NSString alloc] init]; // no-warning diff --git a/test/Analysis/PR2978.m b/test/Analysis/PR2978.m index 7bc90b8d03e0..0cb3dea8ea86 100644 --- a/test/Analysis/PR2978.m +++ b/test/Analysis/PR2978.m @@ -55,6 +55,7 @@ [self setW:@"newW"]; // This will release '_W', but retain the new value self.O = 0; // no-warning [super dealloc]; + return 0; } @end diff --git a/test/Analysis/PR3991.m b/test/Analysis/PR3991.m index 20d4b5b96059..bbc1377b0415 100644 --- a/test/Analysis/PR3991.m +++ b/test/Analysis/PR3991.m @@ -43,6 +43,7 @@ typedef struct _NSZone NSZone; - (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex; - (NSURL *)folderFeedURL; @end @implementation IHGoogleDocsAdapter - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject <IHGoogleDocsAdapterDelegate> *)owner { + return 0; } //===----------------------------------------------------------------------===// diff --git a/test/Analysis/array-struct.c b/test/Analysis/array-struct.c index da7df4b28e30..d6b6076a14b2 100644 --- a/test/Analysis/array-struct.c +++ b/test/Analysis/array-struct.c @@ -1,7 +1,5 @@ // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s && -// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s - -// RegionStore now has an infinite recursion with this test case. +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s @@ -145,7 +143,7 @@ void f15() { int a[10]; bar(a); if (a[1]) // no-warning - 1; + (void)1; } struct s3 p[1]; diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c index 5e4222bc84be..ae51ffb69aa5 100644 --- a/test/Analysis/casts.c +++ b/test/Analysis/casts.c @@ -1,9 +1,16 @@ -// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region --verify %s +// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -checker-cfref -analyzer-store=region --verify %s // Test if the 'storage' region gets properly initialized after it is cast to // 'struct sockaddr *'. -#include <sys/socket.h> +typedef unsigned char __uint8_t; +typedef unsigned int __uint32_t; +typedef __uint32_t __darwin_socklen_t; +typedef __uint8_t sa_family_t; +typedef __darwin_socklen_t socklen_t; +struct sockaddr { sa_family_t sa_family; }; +struct sockaddr_storage {}; + void f(int sock) { struct sockaddr_storage storage; struct sockaddr* sockaddr = (struct sockaddr*)&storage; @@ -19,14 +26,14 @@ struct s { struct s *value; }; -int f1(struct s **pval) { +void f1(struct s **pval) { int *tbool = ((void*)0); struct s *t = *pval; pval = &(t->value); - tbool = (int *)pval; // Should record the cast-to type here. + tbool = (int *)pval; // use the cast-to type 'int *' to create element region. char c = (unsigned char) *tbool; // Should use cast-to type to create symbol. - if (*tbool == -1) - 3; + if (*tbool == -1) // here load the element region with the correct type 'int' + (void)3; } void f2(const char *str) { diff --git a/test/Analysis/cfref_rdar6080742.c b/test/Analysis/cfref_rdar6080742.c index 5d957615d0dd..9bbaf9b5ae06 100644 --- a/test/Analysis/cfref_rdar6080742.c +++ b/test/Analysis/cfref_rdar6080742.c @@ -44,15 +44,15 @@ Boolean DebugDisplayOSStatusMsg(OSStatus status, const char *statusStr, #define AssertNoErr(err){ DebugDisplayOSStatusMsg((err), #err, __FILE__, __LINE__); } #define RequireNoErr(err, action){ if( DebugDisplayOSStatusMsg((err), #err, __FILE__, __LINE__) ) { action }} -void DebugStop(const char *format,...); /* Not an abort function. */ +void DebugStop(const char *format,...); /* Not an abort function. */ int main(int argc, char *argv[]) { - CFStringRef cfString; - OSStatus status = noErr; - cfString = CFStringCreateWithCString(0, "hello", kCFStringEncodingUTF8); - RequireAction(cfString != 0, return memFullErr;) //no - warning - printf("cfstring %p\n", cfString); -Exit: - CFRelease(cfString); - return 0; + CFStringRef cfString; + OSStatus status = noErr; + cfString = CFStringCreateWithCString(0, "hello", kCFStringEncodingUTF8); + RequireAction(cfString != 0, return memFullErr;) //no - warning + printf("cfstring %p\n", cfString); + Exit: + CFRelease(cfString); + return 0; } diff --git a/test/Analysis/complex.c b/test/Analysis/complex.c index cef624577a6d..3633b2148413 100644 --- a/test/Analysis/complex.c +++ b/test/Analysis/complex.c @@ -5,7 +5,7 @@ #include <stdint.h> -int f1(int * p) { +void f1(int * p) { // This branch should be infeasible // because __imag__ p is 0. diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c index 6d3b7e6f540d..c4ff7fa0e860 100644 --- a/test/Analysis/dead-stores.c +++ b/test/Analysis/dead-stores.c @@ -57,7 +57,7 @@ int f7(int *p) { int f8(int *p) { extern int *baz(); - if (p = baz()) // expected-warning{{Although the value}} + if ((p = baz())) // expected-warning{{Although the value}} return 1; return 0; } @@ -129,14 +129,15 @@ int f16(int x) { } // Self-assignments should not be flagged as dead stores. -int f17() { +void f17() { int x = 1; x = x; // no-warning } // <rdar://problem/6506065> // The values of dead stores are only "consumed" in an enclosing expression -// what that value is actually used. In other words, don't say "Although the value stored to 'x' is used...". +// what that value is actually used. In other words, don't say "Although the +// value stored to 'x' is used...". int f18() { int x = 0; // no-warning if (1) @@ -171,3 +172,167 @@ void f20(void) { #pragma unused(x) } +void halt() __attribute__((noreturn)); +int f21() { + int x = 4; + + ++x; // expected-warning{{never read}} + if (1) { + halt(); + (void)x; + } + return 1; +} + +int j; +void f22() { + int x = 4; + int y1 = 4; + int y2 = 4; + int y3 = 4; + int y4 = 4; + int y5 = 4; + int y6 = 4; + int y7 = 4; + int y8 = 4; + int y9 = 4; + int y10 = 4; + int y11 = 4; + int y12 = 4; + int y13 = 4; + int y14 = 4; + int y15 = 4; + int y16 = 4; + int y17 = 4; + int y18 = 4; + int y19 = 4; + int y20 = 4; + + ++x; // expected-warning{{never read}} + ++y1; + ++y2; + ++y3; + ++y4; + ++y5; + ++y6; + ++y7; + ++y8; + ++y9; + ++y10; + ++y11; + ++y12; + ++y13; + ++y14; + ++y15; + ++y16; + ++y17; + ++y18; + ++y19; + ++y20; + + switch (j) { + case 1: + if (0) + (void)x; + if (1) { + (void)y1; + return; + } + (void)x; + break; + case 2: + if (0) + (void)x; + else { + (void)y2; + return; + } + (void)x; + break; + case 3: + if (1) { + (void)y3; + return; + } else + (void)x; + (void)x; + break; + case 4: + 0 ? : ((void)y4, ({ return; })); + (void)x; + break; + case 5: + 1 ? : (void)x; + 0 ? (void)x : ((void)y5, ({ return; })); + (void)x; + break; + case 6: + 1 ? ((void)y6, ({ return; })) : (void)x; + (void)x; + break; + case 7: + (void)(0 && x); + (void)y7; + (void)(0 || (y8, ({ return; }), 1)); + (void)x; + break; + case 8: + (void)(1 && (y9, ({ return; }), 1)); + (void)x; + break; + case 9: + (void)(1 || x); + (void)y10; + break; + case 10: + while (0) { + (void)x; + } + (void)y11; + break; + case 11: + while (1) { + (void)y12; + } + (void)x; + break; + case 12: + do { + (void)y13; + } while (0); + (void)y14; + break; + case 13: + do { + (void)y15; + } while (1); + (void)x; + break; + case 14: + for (;;) { + (void)y16; + } + (void)x; + break; + case 15: + for (;1;) { + (void)y17; + } + (void)x; + break; + case 16: + for (;0;) { + (void)x; + } + (void)y18; + break; + case 17: + __builtin_choose_expr(0, (void)x, ((void)y19, ({ return; }))); + (void)x; + break; + case 19: + __builtin_choose_expr(1, ((void)y20, ({ return; })), (void)x); + (void)x; + break; + } +} diff --git a/test/Analysis/dead-stores.cpp b/test/Analysis/dead-stores.cpp new file mode 100644 index 000000000000..9ddb7979ca69 --- /dev/null +++ b/test/Analysis/dead-stores.cpp @@ -0,0 +1,19 @@ +// RUN: clang-cc -analyze -warn-dead-stores -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -warn-dead-stores -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -warn-dead-stores -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -warn-dead-stores -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -warn-dead-stores -verify %s + +int j; +void f1() { + int x = 4; + + ++x; // expected-warning{{never read}} + + switch (j) { + case 1: + throw 1; + (void)x; + break; + } +} diff --git a/test/Analysis/exercise-ps.c b/test/Analysis/exercise-ps.c index c309349ab3a9..1e31b1888e1f 100644 --- a/test/Analysis/exercise-ps.c +++ b/test/Analysis/exercise-ps.c @@ -5,7 +5,7 @@ // (i.e., no assertions or crashes). -static const char * f1(const char *x, char *y) { +static void f1(const char *x, char *y) { while (*x != 0) { *y++ = *x++; } diff --git a/test/Analysis/misc-ps-basic-store.m b/test/Analysis/misc-ps-basic-store.m index 1207f8663e90..c6ae20c86a36 100644 --- a/test/Analysis/misc-ps-basic-store.m +++ b/test/Analysis/misc-ps-basic-store.m @@ -19,3 +19,17 @@ void checkaccess_union() { ).__i))) & 0xff00) >> 8) == 1) ret = 1; } + +// BasicStore handles this case incorrectly because it doesn't reason about +// the value pointed to by 'x' and thus creates different symbolic values +// at the declarations of 'a' and 'b' respectively. See the companion test +// in 'misc-ps-region-store.m'. +void test_trivial_symbolic_comparison_pointer_parameter(int *x) { + int a = *x; + int b = *x; + if (a != b) { + int *p = 0; + *p = 0xDEADBEEF; // expected-warning{{null}} + } +} + diff --git a/test/Analysis/misc-ps-region-store-i386.m b/test/Analysis/misc-ps-region-store-i386.m new file mode 100644 index 000000000000..c2c4d5b9413c --- /dev/null +++ b/test/Analysis/misc-ps-region-store-i386.m @@ -0,0 +1,14 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s + +// Here is a case where a pointer is treated as integer, invalidated as an +// integer, and then used again as a pointer. This test just makes sure +// we don't crash. +typedef unsigned uintptr_t; +void test_pointer_invalidated_as_int_aux(uintptr_t* ptr); +void test_pointer_invalidated_as_int() { + void *x; + test_pointer_invalidated_as_int_aux((uintptr_t*) &x); + // Here we have a pointer to integer cast. + uintptr_t y = (uintptr_t) x; +} + diff --git a/test/Analysis/misc-ps-region-store-x86_64.m b/test/Analysis/misc-ps-region-store-x86_64.m new file mode 100644 index 000000000000..154ffaf3a003 --- /dev/null +++ b/test/Analysis/misc-ps-region-store-x86_64.m @@ -0,0 +1,14 @@ +// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s + +// Here is a case where a pointer is treated as integer, invalidated as an +// integer, and then used again as a pointer. This test just makes sure +// we don't crash. +typedef unsigned long uintptr_t; +void test_pointer_invalidated_as_int_aux(uintptr_t* ptr); +void test_pointer_invalidated_as_int() { + void *x; + test_pointer_invalidated_as_int_aux((uintptr_t*) &x); + // Here we have a pointer to integer cast. + uintptr_t y = (uintptr_t) x; +} + diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index 8c8815ea63eb..e849042b3d3d 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -1,4 +1,5 @@ -// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s +// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s && +// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s typedef struct objc_selector *SEL; typedef signed char BOOL; @@ -31,10 +32,12 @@ extern NSString * const NSConnectionReplyMode; // PR 2948 (testcase; crash on VisitLValue for union types) // http://llvm.org/bugs/show_bug.cgi?id=2948 - void checkaccess_union() { int ret = 0, status; - if (((((__extension__ (((union { // expected-warning {{ Branch condition evaluates to an uninitialized value.}} + // Since RegionStore doesn't handle unions yet, + // this branch condition won't be triggered + // as involving an uninitialized value. + if (((((__extension__ (((union { // no-warning __typeof (status) __in; int __i;} ) { @@ -43,7 +46,6 @@ void checkaccess_union() { ret = 1; } - // Check our handling of fields being invalidated by function calls. struct test2_struct { int x; int y; char* s; }; void test2_helper(struct test2_struct* p); @@ -68,3 +70,236 @@ char test2() { return 'a'; } +// BasicStore handles this case incorrectly because it doesn't reason about +// the value pointed to by 'x' and thus creates different symbolic values +// at the declarations of 'a' and 'b' respectively. RegionStore handles +// it correctly. See the companion test in 'misc-ps-basic-store.m'. +void test_trivial_symbolic_comparison_pointer_parameter(int *x) { + int a = *x; + int b = *x; + if (a != b) { + int *p = 0; + *p = 0xDEADBEEF; // no-warning + } +} + +// This is a modified test from 'misc-ps.m'. Here we have the extra +// NULL dereferences which are pruned out by RegionStore's symbolic reasoning +// of fields. +typedef struct _BStruct { void *grue; } BStruct; +void testB_aux(void *ptr); + +void testB(BStruct *b) { + { + int *__gruep__ = ((int *)&((b)->grue)); + int __gruev__ = *__gruep__; + int __gruev2__ = *__gruep__; + if (__gruev__ != __gruev2__) { + int *p = 0; + *p = 0xDEADBEEF; // no-warning + } + + testB_aux(__gruep__); + } + { + int *__gruep__ = ((int *)&((b)->grue)); + int __gruev__ = *__gruep__; + int __gruev2__ = *__gruep__; + if (__gruev__ != __gruev2__) { + int *p = 0; + *p = 0xDEADBEEF; // no-warning + } + + if (~0 != __gruev__) {} + } +} + +void testB_2(BStruct *b) { + { + int **__gruep__ = ((int **)&((b)->grue)); + int *__gruev__ = *__gruep__; + testB_aux(__gruep__); + } + { + int **__gruep__ = ((int **)&((b)->grue)); + int *__gruev__ = *__gruep__; + if ((int*)~0 != __gruev__) {} + } +} + +// This test case is a reduced case of a caching bug discovered by an +// assertion failure in RegionStoreManager::BindArray. Essentially the +// DeclStmt is evaluated twice, but on the second loop iteration the +// engine caches out. Previously a false transition would cause UnknownVal +// to bind to the variable, firing an assertion failure. This bug was fixed +// in r76262. +void test_declstmt_caching() { +again: + { + const char a[] = "I like to crash"; + goto again; + } +} + +// Reduced test case from <rdar://problem/7114618>. +// Basically a null check is performed on the field value, which is then +// assigned to a variable and then checked again. +struct s_7114618 { int *p; }; +void test_rdar_7114618(struct s_7114618 *s) { + if (s->p) { + int *p = s->p; + if (!p) { + // Infeasible + int *dead = 0; + *dead = 0xDEADBEEF; // no-warning + } + } +} + +// Test pointers increment correctly. +void f() { + int a[2]; + a[1] = 3; + int *p = a; + p++; + if (*p != 3) { + int *q = 0; + *q = 3; // no-warning + } +} + +// <rdar://problem/7185607> +// Bit-fields of a struct should be invalidated when blasting the entire +// struct with an integer constant. +struct test_7185607 { + int x : 10; + int y : 22; +}; +int rdar_test_7185607() { + struct test_7185607 s; // Uninitialized. + *((unsigned *) &s) = 0U; + return s.x; // no-warning +} + +// <rdar://problem/7242006> [RegionStore] compound literal assignment with +// floats not honored +// This test case is mirrored in misc-ps.m, but this case is a negative. +typedef float CGFloat; +typedef struct _NSSize { + CGFloat width; + CGFloat height; +} NSSize; + +CGFloat rdar7242006_negative(CGFloat x) { + NSSize y; + return y.width; // expected-warning{{garbage}} +} + +// <rdar://problem/7249340> - Allow binding of values to symbolic regions. +// This test case shows how RegionStore tracks the value bound to 'x' +// after the assignment. +typedef int* ptr_rdar_7249340; +void rdar_7249340(ptr_rdar_7249340 x) { + *x = 1; + if (*x) + return; + int *p = 0; // This is unreachable. + *p = 0xDEADBEEF; // no-warning +} + +// <rdar://problem/7249327> - This test case tests both value tracking of +// array values and that we handle symbolic values that are casted +// between different integer types. Note the assignment 'n = *a++'; here +// 'n' is and 'int' and '*a' is 'unsigned'. Previously we got a false positive +// at 'x += *b++' (undefined value) because we got a false path. +int rdar_7249327_aux(void); + +void rdar_7249327(unsigned int A[2*32]) { + int B[2*32]; + int *b; + unsigned int *a; + int x = 0; + + int n; + + a = A; + b = B; + + n = *a++; + if (n) + *b++ = rdar_7249327_aux(); + + a = A; + b = B; + + n = *a++; + if (n) + x += *b++; // no-warning +} + +// <rdar://problem/6914474> - Check that 'x' is invalidated because its +// address is passed in as a value to a struct. +struct doodad_6914474 { int *v; }; +extern void prod_6914474(struct doodad_6914474 *d); +int rdar_6914474(void) { + int x; + struct doodad_6914474 d; + d.v = &x; + prod_6914474(&d); + return x; // no-warning +} + +// Test invalidation of a single field. +struct s_test_field_invalidate { + int x; +}; +extern void test_invalidate_field(int *x); +int test_invalidate_field_test() { + struct s_test_field_invalidate y; + test_invalidate_field(&y.x); + return y.x; // no-warning +} +int test_invalidate_field_test_positive() { + struct s_test_field_invalidate y; + return y.x; // expected-warning{{garbage}} +} + +// This test case illustrates how a typeless array of bytes casted to a +// struct should be treated as initialized. RemoveDeadBindings previously +// had a bug that caused 'x' to lose its default symbolic value after the +// assignment to 'p', thus causing 'p->z' to evaluate to "undefined". +struct ArrayWrapper { unsigned char y[16]; }; +struct WrappedStruct { unsigned z; }; + +int test_handle_array_wrapper() { + struct ArrayWrapper x; + test_handle_array_wrapper(&x); + struct WrappedStruct *p = (struct WrappedStruct*) x.y; + return p->z; // no-warning +} + +// <rdar://problem/7261075> [RegionStore] crash when +// handling load: '*((unsigned int *)"????")' +int rdar_7261075(void) { + unsigned int var = 0; + if (var == *((unsigned int *)"????")) + return 1; + return 0; +} + +// <rdar://problem/7275774> false path due to limited pointer +// arithmetic constraints +void rdar_7275774(void *data, unsigned n) { + if (!(data || n == 0)) + return; + + unsigned short *p = (unsigned short*) data; + unsigned short *q = p + (n / 2); + + if (p < q) { + // If we reach here, 'p' cannot be null. If 'p' is null, then 'n' must + // be '0', meaning that this branch is not feasible. + *p = *q; // no-warning + } +} + diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index ea41b5bb2f35..10e5823c206c 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -1,24 +1,43 @@ -// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=basic --verify -fblocks %s && +// NOTE: Use '-fobjc-gc' to test the analysis being run twice, and multiple reports are not issued. +// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -fobjc-gc -analyzer-constraints=basic --verify -fblocks %s && // RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=range --verify -fblocks %s && // RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=basic --verify -fblocks %s && // RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s +typedef struct objc_ivar *Ivar; typedef struct objc_selector *SEL; typedef signed char BOOL; typedef int NSInteger; typedef unsigned int NSUInteger; typedef struct _NSZone NSZone; -@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; -@protocol NSObject - (BOOL)isEqual:(id)object; @end -@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end +@class NSInvocation, NSArray, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)autorelease; +@end +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end -@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end -@interface NSObject <NSObject> {} - (id)init; @end +@protocol NSCoding +- (void)encodeWithCoder:(NSCoder *)aCoder; +@end +@interface NSObject <NSObject> {} +- (id)init; ++ (id)allocWithZone:(NSZone *)zone; +@end extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); @interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; + (id)stringWithUTF8String:(const char *)nullTerminatedCString; @end extern NSString * const NSBundleDidLoadNotification; +@interface NSValue : NSObject <NSCopying, NSCoding> +- (void)getValue:(void *)value; +@end +@interface NSNumber : NSValue +- (char)charValue; +- (id)initWithBool:(BOOL)value; +@end @interface NSAssertionHandler : NSObject {} + (NSAssertionHandler *)currentHandler; - (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...; @@ -144,7 +163,7 @@ void pr3422() { } // PR 3543 (handle empty statement expressions) -int pr_3543(void) { +void pr_3543(void) { ({}); } @@ -295,4 +314,381 @@ void rdar_7027684(int x, int y) { (rdar_7027684_aux() ? rdar_7027684_aux_2() : (void) 0); } +// Test that we handle casts of string literals to arbitrary types. +unsigned const char *string_literal_test1() { + return (const unsigned char*) "hello"; +} + +const float *string_literal_test2() { + return (const float*) "hello"; +} + +// Test that we handle casts *from* incomplete struct types. +extern const struct _FooAssertStruct _cmd; +void test_cast_from_incomplete_struct_aux(volatile const void *x); +void test_cast_from_incomplete_struct() { + test_cast_from_incomplete_struct_aux(&_cmd); +} + +// Test for <rdar://problem/7034511> +// "ValueManager::makeIntVal(uint64_t X, QualType T) should return a 'Loc' +// when 'T' is a pointer" +// +// Previously this case would crash. +void test_rdar_7034511(NSArray *y) { + NSObject *x; + for (x in y) {} + if (x == ((void*) 0)) {} +} + +// Handle casts of function pointers (CodeTextRegions) to arbitrary pointer +// types. This was previously causing a crash in CastRegion. +void handle_funcptr_voidptr_casts() { + void **ptr; + typedef void *PVOID; + typedef void *PCHAR; + typedef long INT_PTR, *PINT_PTR; + typedef INT_PTR (*FARPROC)(); + FARPROC handle_funcptr_voidptr_casts_aux(); + PVOID handle_funcptr_voidptr_casts_aux_2(PVOID volatile *x); + PVOID handle_funcptr_voidptr_casts_aux_3(PCHAR volatile *x); + + ptr = (void**) handle_funcptr_voidptr_casts_aux(); + handle_funcptr_voidptr_casts_aux_2(ptr); + handle_funcptr_voidptr_casts_aux_3(ptr); +} + +// RegionStore::Retrieve previously crashed on this example. This example +// was previously in the test file 'xfail_regionstore_wine_crash.c'. +void testA() { + long x = 0; + char *y = (char *) &x; + if (!*y) + return; +} + +// RegionStoreManager previously crashed on this example. The problem is that +// the value bound to the field of b->grue after the call to testB_aux is +// a symbolic region. The second '*__gruep__' involves performing a load +// from a 'int*' that really is a 'void**'. The loaded location must be +// implicitly converted to an integer that wraps a location. Previosly we would +// get a crash here due to an assertion failure. +typedef struct _BStruct { void *grue; } BStruct; +void testB_aux(void *ptr); +void testB(BStruct *b) { + { + int *__gruep__ = ((int *)&((b)->grue)); + int __gruev__ = *__gruep__; + testB_aux(__gruep__); + } + { + int *__gruep__ = ((int *)&((b)->grue)); + int __gruev__ = *__gruep__; + if (~0 != __gruev__) {} + } +} + +void test_trivial_symbolic_comparison(int *x) { + int test_trivial_symbolic_comparison_aux(); + int a = test_trivial_symbolic_comparison_aux(); + int b = a; + if (a != b) { + int *p = 0; + *p = 0xDEADBEEF; // no-warning + } + + a = a == 1; + b = b == 1; + if (a != b) { + int *p = 0; + *p = 0xDEADBEEF; // no-warning + } +} + +// Test for: +// <rdar://problem/7062158> false positive null dereference due to +// BasicStoreManager not tracking *static* globals +// +// This just tests the proper tracking of symbolic values for globals (both +// static and non-static). +// +static int* x_rdar_7062158; +void rdar_7062158() { + int *current = x_rdar_7062158; + if (current == x_rdar_7062158) + return; + + int *p = 0; + *p = 0xDEADBEEF; // no-warning +} + +int* x_rdar_7062158_2; +void rdar_7062158_2() { + int *current = x_rdar_7062158_2; + if (current == x_rdar_7062158_2) + return; + + int *p = 0; + *p = 0xDEADBEEF; // no-warning +} + +// This test reproduces a case for a crash when analyzing ClamAV using +// RegionStoreManager (the crash doesn't exhibit in BasicStoreManager because +// it isn't doing anything smart about arrays). The problem is that on the +// second line, 'p = &p[i]', p is assigned an ElementRegion whose index +// is a 16-bit integer. On the third line, a new ElementRegion is created +// based on the previous region, but there the region uses a 32-bit integer, +// resulting in a clash of values (an assertion failure at best). We resolve +// this problem by implicitly converting index values to 'int' when the +// ElementRegion is created. +unsigned char test_array_index_bitwidth(const unsigned char *p) { + unsigned short i = 0; + for (i = 0; i < 2; i++) p = &p[i]; + return p[i+1]; +} + +// This case tests that CastRegion handles casts involving BlockPointerTypes. +// It should not crash. +void test_block_cast() { + id test_block_cast_aux(); + (void (^)(void *))test_block_cast_aux(); // expected-warning{{expression result unused}} +} + +// Test comparison of 'id' instance variable to a null void* constant after +// performing an OSAtomicCompareAndSwap32Barrier. +// This previously was a crash in RegionStoreManager. +@interface TestIdNull { + id x; +} +-(int)foo; +@end +@implementation TestIdNull +-(int)foo { + OSAtomicCompareAndSwap32Barrier(0, (signed)2, (signed*)&x); + if (x == (void*) 0) { return 0; } + return 1; +} +@end + +// PR 4594 - This was a crash when handling casts in SimpleSValuator. +void PR4594() { + char *buf[1]; + char **foo = buf; + *foo = "test"; +} + +// Test invalidation logic where an integer is casted to an array with a +// different sign and then invalidated. +void test_invalidate_cast_int() { + void test_invalidate_cast_int_aux(unsigned *i); + signed i; + test_invalidate_cast_int_aux((unsigned*) &i); + if (i < 0) + return; +} + +// Reduced from a crash involving the cast of an Objective-C symbolic region to +// 'char *' +static NSNumber *test_ivar_offset(id self, SEL _cmd, Ivar inIvar) { + return [[[NSNumber allocWithZone:((void*)0)] initWithBool:*(_Bool *)((char *)self + ivar_getOffset(inIvar))] autorelease]; +} + +// Reduced from a crash in StoreManager::CastRegion involving a divide-by-zero. +// This resulted from not properly handling region casts to 'const void*'. +void test_cast_const_voidptr() { + char x[10]; + char *p = &x[1]; + const void* q = p; +} + +// Reduced from a crash when analyzing Wine. This test handles loads from +// function addresses. +typedef long (*FARPROC)(); +FARPROC test_load_func(FARPROC origfun) { + if (!*(unsigned char*) origfun) + return origfun; + return 0; +} + +// Test passing-by-value an initialized struct variable. +struct test_pass_val { + int x; + int y; +}; +void test_pass_val_aux(struct test_pass_val s); +void test_pass_val() { + struct test_pass_val s; + s.x = 1; + s.y = 2; + test_pass_val_aux(s); +} + +// This is a reduced test case of a false positive that previously appeared +// in RegionStoreManager. Previously the array access resulted in dereferencing +// an undefined value. +int test_array_compound(int *q, int *r, int *z) { + int *array[] = { q, r, z }; + int j = 0; + for (unsigned i = 0; i < 3 ; ++i) + if (*array[i]) ++j; // no-warning + return j; +} + +// This test case previously crashed with -analyzer-store=basic because the +// symbolic value stored in 'x' wouldn't be implicitly casted to a signed value +// during the comparison. +int rdar_7124210(unsigned int x) { + enum { SOME_CONSTANT = 123 }; + int compare = ((signed) SOME_CONSTANT) == *((signed *) &x); + return compare ? 0 : 1; // Forces the evaluation of the symbolic constraint. +} + +void pr4781(unsigned long *raw1) { + unsigned long *cook, *raw0; + unsigned long dough[32]; + int i; + cook = dough; + for( i = 0; i < 16; i++, raw1++ ) { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + } +} + +// <rdar://problem/7185647> - 'self' should be treated as being non-null +// upon entry to an objective-c method. +@interface RDar7185647 +- (id)foo; +@end +@implementation RDar7185647 +- (id) foo { + if (self) + return self; + *((int *) 0x0) = 0xDEADBEEF; // no-warning + return self; +} +@end + +// Test reasoning of __builtin_offsetof; +struct test_offsetof_A { + int x; + int y; +}; +struct test_offsetof_B { + int w; + int z; +}; +void test_offsetof_1() { + if (__builtin_offsetof(struct test_offsetof_A, x) == + __builtin_offsetof(struct test_offsetof_B, w)) + return; + int *p = 0; + *p = 0xDEADBEEF; // no-warning +} +void test_offsetof_2() { + if (__builtin_offsetof(struct test_offsetof_A, y) == + __builtin_offsetof(struct test_offsetof_B, z)) + return; + int *p = 0; + *p = 0xDEADBEEF; // no-warning +} +void test_offsetof_3() { + if (__builtin_offsetof(struct test_offsetof_A, y) - + __builtin_offsetof(struct test_offsetof_A, x) + == + __builtin_offsetof(struct test_offsetof_B, z) - + __builtin_offsetof(struct test_offsetof_B, w)) + return; + int *p = 0; + *p = 0xDEADBEEF; // no-warning +} +void test_offsetof_4() { + if (__builtin_offsetof(struct test_offsetof_A, y) == + __builtin_offsetof(struct test_offsetof_B, w)) + return; + int *p = 0; + *p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}} +} + +// <rdar://problem/6829164> "nil receiver" false positive: make tracking +// of the MemRegion for 'self' path-sensitive +@interface RDar6829164 : NSObject { + double x; int y; +} +- (id) init; +@end + +id rdar_6829164_1(); +double rdar_6829164_2(); + +@implementation RDar6829164 +- (id) init { + if((self = [super init]) != 0) { + id z = rdar_6829164_1(); + y = (z != 0); + if (y) + x = rdar_6829164_2(); + } + return self; +} +@end + +// <rdar://problem/7242015> - Invalidate values passed-by-reference +// to functions when the pointer to the value is passed as an integer. +void test_7242015_aux(unsigned long); +int rdar_7242015() { + int x; + test_7242015_aux((unsigned long) &x); // no-warning + return x; // Previously we return and uninitialized value when + // using RegionStore. +} + +// <rdar://problem/7242006> [RegionStore] compound literal assignment with +// floats not honored +CGFloat rdar7242006(CGFloat x) { + NSSize y = (NSSize){x, 10}; + return y.width; // no-warning +} + +// PR 4988 - This test exhibits a case where a function can be referenced +// when not explicitly used in an "lvalue" context (as far as the analyzer is +// concerned). This previously triggered a crash due to an invalid assertion. +void pr_4988(void) { + pr_4988; // expected-warning{{expression result unused}} +} + +// <rdar://problem/7152418> - A 'signed char' is used as a flag, which is +// implicitly converted to an int. +void *rdar7152418_bar(); +@interface RDar7152418 { + signed char x; +} +-(char)foo; +@end; +@implementation RDar7152418 +-(char)foo { + char *p = 0; + void *result = 0; + if (x) { + result = rdar7152418_bar(); + p = "hello"; + } + if (!result) { + result = rdar7152418_bar(); + if (result && x) + return *p; // no-warning + } + return 1; +} + +// Test constant-folding of symbolic values, automatically handling type +// conversions of the symbol as necessary. Previously this would crash +// once we started eagerly evaluating symbols whose values were constrained +// to a single value. +void test_constant_symbol(signed char x) { + while (1) { + if (x == ((signed char) 0)) {} + } +} + diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m index 9a64b3001e16..87faab6bfbac 100644 --- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m +++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m @@ -1,4 +1,5 @@ -// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic %s -verify +// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic %s -verify && +// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=region %s -verify @interface MyClass {} - (void *)voidPtrM; diff --git a/test/Analysis/no-outofbounds.c b/test/Analysis/no-outofbounds.c new file mode 100644 index 000000000000..94052806f0aa --- /dev/null +++ b/test/Analysis/no-outofbounds.c @@ -0,0 +1,12 @@ +// RUN: clang-cc -checker-cfref -analyze -analyzer-store=basic -verify %s && +// RUN: clang-cc -checker-cfref -analyze -analyzer-store=region -verify %s + +//===----------------------------------------------------------------------===// +// This file tests cases where we should not flag out-of-bounds warnings. +//===----------------------------------------------------------------------===// + +void f() { + long x = 0; + char *y = (char*) &x; + char c = y[0] + y[1] + y[2]; // no-warning +} diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c index 6e2074146c30..f37b4416f2a1 100644 --- a/test/Analysis/null-deref-ps.c +++ b/test/Analysis/null-deref-ps.c @@ -1,10 +1,16 @@ -// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=basic -analyzer-store=basic && -// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=range -analyzer-store=basic && -// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -analyzer-purge-dead=false -verify %s && -// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s +// RUN: clang-cc -triple i386-apple-darwin10 -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=basic -analyzer-store=basic && +// RUN: clang-cc -triple i386-apple-darwin10 -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=range -analyzer-store=basic && +// RUN: clang-cc -triple i386-apple-darwin10 -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -analyzer-purge-dead=false -verify %s && +// RUN: clang-cc -triple i386-apple-darwin10 -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s -#include<stdint.h> -#include <assert.h> +typedef unsigned uintptr_t; + +extern void __assert_fail (__const char *__assertion, __const char *__file, + unsigned int __line, __const char *__function) + __attribute__ ((__noreturn__)); + +#define assert(expr) \ + ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) void f1(int *p) { if (p) *p = 1; @@ -72,6 +78,7 @@ int f4_b() { else return; // expected-warning {{non-void function 'f4_b' should return a value}} *p += 10; // expected-warning{{Dereference of null pointer}} + return 0; } @@ -102,6 +109,15 @@ int f6c(int *p, int *q) { : bar3(p, 2, q); // no-warning } +void f6d(int *p) { + bar(p, 0); + // At this point, 'p' cannot be null. + if (!p) { + int *q = 0; + *q = 0xDEADBEEF; // no-warning + } +} + int* qux(); int f7(int x) { @@ -160,7 +176,7 @@ int* f7c2(int *x) { } -int f8(int *p, int *q) { +void f8(int *p, int *q) { if (!p) if (p) *p = 1; // no-warning @@ -262,4 +278,13 @@ void f13() { if (((((int) x) << 2) + 1) >> 1) *x = 1; // no-warning } +// PR 4759 - Attribute non-null checking by the analyzer was not correctly +// handling pointer values that were undefined. +void pr4759_aux(int *p) __attribute__((nonnull)); + +void pr4759() { + int *p; + pr4759_aux(p); // expected-warning{{undefined}} +} + diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c index 527a311d2b7d..568f14329e9b 100644 --- a/test/Analysis/outofbound.c +++ b/test/Analysis/outofbound.c @@ -1,4 +1,5 @@ // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s +// XFAIL char f1() { char* s = "abcd"; diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m index 7d7d8fc5a157..991d0d68f704 100644 --- a/test/Analysis/pr4209.m +++ b/test/Analysis/pr4209.m @@ -1,4 +1,4 @@ -// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -verify %s && +// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -analyzer-store=basic -verify %s && // RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -analyzer-store=region -verify %s // This test case was crashing due to how CFRefCount.cpp resolved the @@ -56,6 +56,7 @@ CMProfileLocation; - (GSEbayCategory *) parent; - (GSEbayCategory*) subcategoryWithID:(int) inID; @end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent { + return 0; } - (void) addCategory:(EBayCategoryType*)inCategory toRootTreeCategory:(NSMutableArray*)inRootTreeCategories { GSEbayCategory *category = [rootCategory subcategoryWithID:[[inCategory categoryID] intValue]]; diff --git a/test/Analysis/rdar-6442306-1.m b/test/Analysis/rdar-6442306-1.m index 15d349884093..bfda115360e4 100644 --- a/test/Analysis/rdar-6442306-1.m +++ b/test/Analysis/rdar-6442306-1.m @@ -28,4 +28,5 @@ __Beeble_check__Request__SetPortalSize_t(__attribute__((__unused__)) __Request__ } while (0); } + return 0; } diff --git a/test/Analysis/rdar-6540084.m b/test/Analysis/rdar-6540084.m index 18ab038f6e2e..cfe522074ed3 100644 --- a/test/Analysis/rdar-6540084.m +++ b/test/Analysis/rdar-6540084.m @@ -32,5 +32,6 @@ typedef struct {} TazVersion; } } } + while (1) {} } @end diff --git a/test/Analysis/rdar-6541136-region.c b/test/Analysis/rdar-6541136-region.c index 1e7a2d974bc4..e2779e8d914f 100644 --- a/test/Analysis/rdar-6541136-region.c +++ b/test/Analysis/rdar-6541136-region.c @@ -13,7 +13,10 @@ void foo( void ) struct load_wine *cmd = (void*) &wonky[1]; cmd = cmd; char *p = (void*) &wonky[1]; - *p = 1; + *p = 1; // no-warning kernel_tea_cheese_t *q = &wonky[1]; - kernel_tea_cheese_t r = *q; // expected-warning{{out-of-bound memory position}} + // This test case tests both the RegionStore logic (doesn't crash) and + // the out-of-bounds checking. We don't expect the warning for now since + // out-of-bound checking is temporarily disabled. + kernel_tea_cheese_t r = *q; // eventually-warning{{out-of-bound memory position}} } diff --git a/test/Analysis/rdar-6562655.m b/test/Analysis/rdar-6562655.m index 581d6eacf085..3c1c281a830d 100644 --- a/test/Analysis/rdar-6562655.m +++ b/test/Analysis/rdar-6562655.m @@ -1,4 +1,5 @@ -// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic -verify %s +// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=region -verify %s // // This test case mainly checks that the retain/release checker doesn't crash // on this file. @@ -51,7 +52,7 @@ typedef struct _NSRunArrayItem { @end @implementation Bar static Baz Qux = 0; -- (id)copyWithZone:(NSZone *)zone {} +- (id)copyWithZone:(NSZone *)zone { return 0; } - (void)encodeWithCoder:(NSCoder *)coder {} @end @implementation Bar (BarBotnet) @@ -59,5 +60,6 @@ static Baz Qux = 0; if (!(*(BarAuxiliary **)&self->_support)->auxCFlags.botnetIsSet) { _cFlags.botnet = [self _initialBotnetZorg]; } + while (1) {} } @end diff --git a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m index 5d1fa37c46a8..49ef7c381545 100644 --- a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m +++ b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m @@ -1,4 +1,5 @@ -// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic %s -verify +// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic %s -verify && +// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=region %s -verify typedef struct Foo { int x; } Bar; diff --git a/test/Analysis/rdar-7168531.m b/test/Analysis/rdar-7168531.m new file mode 100644 index 000000000000..bdbd22d24e2c --- /dev/null +++ b/test/Analysis/rdar-7168531.m @@ -0,0 +1,19 @@ +// RUN: clang-cc -analyze -checker-cfref -triple i386-apple-darwin10 -analyzer-store=region && +// RUN: clang-cc -analyze -checker-cfref -triple i386-apple-darwin10 -analyzer-store=basic + +// Note that the target triple is important for this test case. It specifies that we use the +// fragile Objective-C ABI. + +@interface Foo { + int x; +} +@end + +@implementation Foo +static Foo* bar(Foo *p) { + if (p->x) + return ++p; // This is only valid for the fragile ABI. + + return p; +} +@end diff --git a/test/Analysis/region-1.m b/test/Analysis/region-1.m index ed172e431e99..68a375b7126c 100644 --- a/test/Analysis/region-1.m +++ b/test/Analysis/region-1.m @@ -79,6 +79,7 @@ typedef NSUInteger JabaSourceLanguage; Dos_CharacterRangeType = 0, Dos_LineRangeType = 1 } DosTextRangeType; @implementation JabaSCSharedDiagramViewController + (NSImage *)findImageNamed:(NSString *)name { + return 0; } - (void)revealSourceInEditor:(JabasectItem *)sectItem duperGesture:(BOOL)duperGesture { id <EcoNamedElement> selectedElement = [sectItem representedObject]; diff --git a/test/Analysis/region-only-test.c b/test/Analysis/region-only-test.c index 64d3fcd57b2a..8908adb1057c 100644 --- a/test/Analysis/region-only-test.c +++ b/test/Analysis/region-only-test.c @@ -9,5 +9,5 @@ void foo(int* p) { if (p[0] == 1) x = &a; if (p[0] == 1) - *x; // no-warning + (void)*x; // no-warning } diff --git a/test/Analysis/retain-release-gc-only.m b/test/Analysis/retain-release-gc-only.m index ec33a57d3303..2833b02f0771 100644 --- a/test/Analysis/retain-release-gc-only.m +++ b/test/Analysis/retain-release-gc-only.m @@ -1,16 +1,26 @@ -// RUN: clang-cc -analyze -checker-cfref -verify -fobjc-gc-only %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify -fobjc-gc-only %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -fobjc-gc-only -verify %s //===----------------------------------------------------------------------===// // Header stuff. //===----------------------------------------------------------------------===// -typedef struct objc_class *Class; - typedef unsigned int __darwin_natural_t; -typedef struct {} div_t; -typedef unsigned long UInt32; +typedef unsigned long uintptr_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +typedef unsigned int UInt32; typedef signed long CFIndex; +typedef struct { + CFIndex location; + CFIndex length; +} CFRange; +static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) { + CFRange range; + range.location = loc; + range.length = len; + return range; +} typedef const void * CFTypeRef; typedef const struct __CFString * CFStringRef; typedef const struct __CFAllocator * CFAllocatorRef; @@ -26,7 +36,17 @@ typedef struct __CFArray * CFMutableArrayRef; extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); +typedef struct { +} +CFDictionaryKeyCallBacks; +extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; +typedef struct { +} +CFDictionaryValueCallBacks; +extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; typedef const struct __CFDictionary * CFDictionaryRef; +typedef struct __CFDictionary * CFMutableDictionaryRef; +extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks); typedef UInt32 CFStringEncoding; enum { kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 }; @@ -40,44 +60,96 @@ extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); typedef __darwin_natural_t natural_t; typedef natural_t mach_port_name_t; typedef mach_port_name_t mach_port_t; -typedef struct { -} -CFRunLoopObserverContext; +typedef int kern_return_t; +typedef kern_return_t mach_error_t; +enum { +kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2, kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4, kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6, kCFNumberCharType = 7, kCFNumberShortType = 8, kCFNumberIntType = 9, kCFNumberLongType = 10, kCFNumberLongLongType = 11, kCFNumberFloatType = 12, kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14, kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16, kCFNumberMaxType = 16 }; +typedef CFIndex CFNumberType; +typedef const struct __CFNumber * CFNumberRef; +extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr); +typedef const struct __CFAttributedString *CFAttributedStringRef; +typedef struct __CFAttributedString *CFMutableAttributedStringRef; +extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ; +extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ; +extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ; typedef signed char BOOL; -typedef unsigned int NSUInteger; +typedef unsigned long NSUInteger; @class NSString, Protocol; extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); typedef struct _NSZone NSZone; @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; -@protocol NSObject - (BOOL)isEqual:(id)object; +@protocol NSObject +- (BOOL)isEqual:(id)object; - (id)retain; - (oneway void)release; - (id)autorelease; +- (Class)class; @end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end @interface NSObject <NSObject> {} -- (Class)class; -+ (id)alloc; + (id)allocWithZone:(NSZone *)zone; -@end typedef float CGFloat; ++ (id)alloc; +- (void)dealloc; +@end +@interface NSObject (NSCoderMethods) +- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; +@end +extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); +typedef struct { +} +NSFastEnumerationState; +@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; +@end @class NSString, NSDictionary; +@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; +@end @interface NSNumber : NSValue - (char)charValue; +- (id)initWithInt:(int)value; +@end @class NSString; +@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count; +@end @interface NSArray (NSArrayCreation) + (id)array; +@end @interface NSAutoreleasePool : NSObject { +} +- (void)drain; +@end extern NSString * const NSBundleDidLoadNotification; +typedef double NSTimeInterval; +@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; +@end typedef unsigned short unichar; @interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; -- (const char *)UTF8String; +- ( const char *)UTF8String; - (id)initWithUTF8String:(const char *)nullTerminatedCString; + (id)stringWithUTF8String:(const char *)nullTerminatedCString; -- (id)init; -- (void)dealloc; -@end extern NSString * const NSCurrentLocaleDidChangeNotification ; -@protocol NSLocking - (void)lock; -@end extern NSString * const NSUndoManagerCheckpointNotification; -typedef enum { -ACL_READ_DATA = (1<<1), ACL_LIST_DIRECTORY = (1<<1), ACL_WRITE_DATA = (1<<2), ACL_ADD_FILE = (1<<2), ACL_EXECUTE = (1<<3), ACL_SEARCH = (1<<3), ACL_DELETE = (1<<4), ACL_APPEND_DATA = (1<<5), ACL_ADD_SUBDIRECTORY = (1<<5), ACL_DELETE_CHILD = (1<<6), ACL_READ_ATTRIBUTES = (1<<7), ACL_WRITE_ATTRIBUTES = (1<<8), ACL_READ_EXTATTRIBUTES = (1<<9), ACL_WRITE_EXTATTRIBUTES = (1<<10), ACL_READ_SECURITY = (1<<11), ACL_WRITE_SECURITY = (1<<12), ACL_CHANGE_OWNER = (1<<13) } -acl_entry_id_t; -typedef int kern_return_t; -typedef kern_return_t mach_error_t; +@end @class NSString, NSURL, NSError; +@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; ++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; ++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; +@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; +@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count; +@end @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; +- (void)setObject:(id)anObject forKey:(id)aKey; +@end @interface NSMutableDictionary (NSMutableDictionaryCreation) + (id)dictionaryWithCapacity:(NSUInteger)numItems; +@end typedef double CGFloat; +struct CGSize { +}; +typedef struct CGSize CGSize; +struct CGRect { +}; +typedef struct CGRect CGRect; typedef mach_port_t io_object_t; +typedef char io_name_t[128]; +typedef io_object_t io_iterator_t; typedef io_object_t io_service_t; +typedef struct IONotificationPort * IONotificationPortRef; +typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator ); +io_service_t IOServiceGetMatchingService( mach_port_t masterPort, CFDictionaryRef matching ); +kern_return_t IOServiceGetMatchingServices( mach_port_t masterPort, CFDictionaryRef matching, io_iterator_t * existing ); +kern_return_t IOServiceAddNotification( mach_port_t masterPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); +kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification ); +CFMutableDictionaryRef IOServiceMatching( const char * name ); +CFMutableDictionaryRef IOServiceNameMatching( const char * name ); +CFMutableDictionaryRef IOBSDNameMatching( mach_port_t masterPort, uint32_t options, const char * bsdName ); +CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t masterPort, uint32_t options, const char * path ); +CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID ); typedef struct __DASession * DASessionRef; extern DASessionRef DASessionCreate( CFAllocatorRef allocator ); typedef struct __DADisk * DADiskRef; @@ -85,23 +157,62 @@ extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ); extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ); extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ); +@interface NSTask : NSObject - (id)init; +@end typedef struct CGColorSpace *CGColorSpaceRef; +typedef struct CGImage *CGImageRef; +typedef struct CGLayer *CGLayerRef; @interface NSResponder : NSObject <NSCoding> { } -@end @class NSColor, NSFont, NSNotification; -typedef struct __CFlags { +@end @protocol NSAnimatablePropertyContainer - (id)animator; +@end extern NSString *NSAnimationTriggerOrderIn ; +@interface NSView : NSResponder <NSAnimatablePropertyContainer> { } -_CFlags; +@end @protocol NSValidatedUserInterfaceItem - (SEL)action; +@end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem; +@end @class NSDate, NSDictionary, NSError, NSException, NSNotification; +@interface NSApplication : NSResponder <NSUserInterfaceValidations> { +} +@end enum { +NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 }; +typedef NSUInteger NSApplicationTerminateReply; +@protocol NSApplicationDelegate <NSObject> @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; +@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; @interface NSCell : NSObject <NSCopying, NSCoding> { } -@end @class NSDate, NSDictionary, NSError, NSException, NSNotification; -@interface NSManagedObjectContext : NSObject <NSCoding, NSLocking> { +@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; +typedef struct { +} +CVTimeStamp; +@interface CIImage : NSObject <NSCoding, NSCopying> { } -@end enum { +typedef int CIFormat; +@end enum { kDAReturnSuccess = 0, kDAReturnError = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01, kDAReturnBusy = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02, kDAReturnBadArgument = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03, kDAReturnExclusiveAccess = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04, kDAReturnNoResources = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05, kDAReturnNotFound = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06, kDAReturnNotMounted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07, kDAReturnNotPermitted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08, kDAReturnNotPrivileged = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09, kDAReturnNotReady = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A, kDAReturnNotWritable = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B, kDAReturnUnsupported = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C }; typedef mach_error_t DAReturn; typedef const struct __DADissenter * DADissenterRef; extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ); - +@interface CIContext: NSObject { +} +- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r; +- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs; +- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d; +@end extern NSString* const QCRendererEventKey; +@protocol QCCompositionRenderer - (NSDictionary*) attributes; +@end @interface QCRenderer : NSObject <QCCompositionRenderer> { +} +- (id) createSnapshotImageOfType:(NSString*)type; +@end extern NSString* const QCViewDidStartRenderingNotification; +@interface QCView : NSView <QCCompositionRenderer> { +} +- (id) createSnapshotImageOfType:(NSString*)type; +@end enum { +ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, }; +@class ICDevice; +@protocol ICDeviceDelegate <NSObject> @required - (void)didRemoveDevice:(ICDevice*)device; +@end extern NSString *const ICScannerStatusWarmingUp; +@class ICScannerDevice; +@protocol ICScannerDeviceDelegate <ICDeviceDelegate> @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner; +@end CFTypeRef CFMakeCollectable(CFTypeRef cf) ; static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef @@ -198,6 +309,19 @@ void f5b() { @end //===----------------------------------------------------------------------===// +// <rdar://problem/7174400> 'ciContext createCGImage:outputImage fromRect:' returns a retained CF object (not GC'ed)//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// + +void rdar_7174400(QCView *view, QCRenderer *renderer, CIContext *context, + NSString *str, CIImage *img, CGRect rect, + CIFormat form, CGColorSpaceRef cs) { + [view createSnapshotImageOfType:str]; // no-warning + [renderer createSnapshotImageOfType:str]; // no-warning + [context createCGImage:img fromRect:rect]; // expected-warning{{leak}} + [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}} +} + +//===----------------------------------------------------------------------===// // Tests of ownership attributes. //===----------------------------------------------------------------------===// diff --git a/test/Analysis/retain-release-region-store.m b/test/Analysis/retain-release-region-store.m index 66950e2190ed..7a696833f92d 100644 --- a/test/Analysis/retain-release-region-store.m +++ b/test/Analysis/retain-release-region-store.m @@ -1,4 +1,5 @@ // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s +// XFAIL //===----------------------------------------------------------------------===// // The following code is reduced using delta-debugging from @@ -115,4 +116,27 @@ CFAbsoluteTime f4() { } @end +//===----------------------------------------------------------------------===// +// <rdar://problem/7257223> - False positive due to not invalidating the +// reference count of a tracked region that was itself invalidated. +//===----------------------------------------------------------------------===// + +typedef struct __rdar_7257223 { CFDateRef x; } RDar7257223; +void rdar_7257223_aux(RDar7257223 *p); + +// THIS CASE CURRENTLY FAILS. +CFDateRef rdar7257223_Create(void) { + RDar7257223 s; + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + s.x = CFDateCreate(0, t); // no-warning + rdar_7257223_aux(&s); + return s.x; +} + +CFDateRef rdar7257223_Create_2(void) { + RDar7257223 s; + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + s.x = CFDateCreate(0, t); // no-warning + return s.x; +} diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index da0ae801dac6..7076bb294254 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -1,6 +1,12 @@ -//>>SLICER -// RUN: clang-cc -analyze -checker-cfref -verify %s && -// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s +// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=basic -verify %s && +// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=region -verify %s + +#if __has_feature(attribute_ns_returns_retained) +#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) +#endif +#if __has_feature(attribute_cf_returns_retained) +#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) +#endif //===----------------------------------------------------------------------===// // The following code is reduced using delta-debugging from Mac OS X headers: @@ -21,6 +27,16 @@ typedef unsigned int uint32_t; typedef unsigned long long uint64_t; typedef unsigned int UInt32; typedef signed long CFIndex; +typedef struct { + CFIndex location; + CFIndex length; +} CFRange; +static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) { + CFRange range; + range.location = loc; + range.length = len; + return range; +} typedef const void * CFTypeRef; typedef const struct __CFString * CFStringRef; typedef const struct __CFAllocator * CFAllocatorRef; @@ -36,8 +52,17 @@ typedef struct __CFArray * CFMutableArrayRef; extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); +typedef struct { +} +CFDictionaryKeyCallBacks; +extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; +typedef struct { +} +CFDictionaryValueCallBacks; +extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; typedef const struct __CFDictionary * CFDictionaryRef; typedef struct __CFDictionary * CFMutableDictionaryRef; +extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks); typedef UInt32 CFStringEncoding; enum { kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 }; @@ -53,29 +78,48 @@ typedef natural_t mach_port_name_t; typedef mach_port_name_t mach_port_t; typedef int kern_return_t; typedef kern_return_t mach_error_t; +enum { +kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2, kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4, kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6, kCFNumberCharType = 7, kCFNumberShortType = 8, kCFNumberIntType = 9, kCFNumberLongType = 10, kCFNumberLongLongType = 11, kCFNumberFloatType = 12, kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14, kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16, kCFNumberMaxType = 16 }; +typedef CFIndex CFNumberType; +typedef const struct __CFNumber * CFNumberRef; +extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr); +typedef const struct __CFAttributedString *CFAttributedStringRef; +typedef struct __CFAttributedString *CFMutableAttributedStringRef; +extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ; +extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ; +extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ; typedef signed char BOOL; typedef unsigned long NSUInteger; @class NSString, Protocol; extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); typedef struct _NSZone NSZone; @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; -@protocol NSObject - (BOOL)isEqual:(id)object; +@protocol NSObject +- (BOOL)isEqual:(id)object; - (id)retain; - (oneway void)release; - (id)autorelease; @end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; -@end @interface NSObject <NSObject> { -} +@end +@interface NSObject <NSObject> {} + (id)allocWithZone:(NSZone *)zone; + (id)alloc; - (void)dealloc; -@end extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); +@end +@interface NSObject (NSCoderMethods) +- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; +@end +extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); typedef struct { } NSFastEnumerationState; @protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; +@end @class NSString, NSDictionary; +@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; +@end @interface NSNumber : NSValue - (char)charValue; +- (id)initWithInt:(int)value; @end @class NSString; @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count; @end @interface NSArray (NSArrayCreation) + (id)array; @@ -90,11 +134,11 @@ typedef double NSTimeInterval; - ( const char *)UTF8String; - (id)initWithUTF8String:(const char *)nullTerminatedCString; + (id)stringWithUTF8String:(const char *)nullTerminatedCString; -@end @class NSString, NSData; +@end @class NSString, NSURL, NSError; @interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; + (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; + (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; -@end @class NSString; +@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; @interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count; @end @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; - (void)setObject:(id)anObject forKey:(id)aKey; @@ -106,9 +150,6 @@ typedef struct CGSize CGSize; struct CGRect { }; typedef struct CGRect CGRect; -@protocol NSLocking - (void)lock; -- (id)init; -@end @class NSURLAuthenticationChallenge; typedef mach_port_t io_object_t; typedef char io_name_t[128]; typedef io_object_t io_iterator_t; @@ -131,37 +172,32 @@ extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ); extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ); extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ); -typedef struct CGColorSpace *CGColorSpaceRef; +@interface NSTask : NSObject - (id)init; +@end typedef struct CGColorSpace *CGColorSpaceRef; typedef struct CGImage *CGImageRef; - typedef struct CGLayer *CGLayerRef; - @class NSArray, NSError, NSEvent, NSMenu, NSUndoManager, NSWindow; +typedef struct CGLayer *CGLayerRef; @interface NSResponder : NSObject <NSCoding> { } @end @protocol NSAnimatablePropertyContainer - (id)animator; @end extern NSString *NSAnimationTriggerOrderIn ; @interface NSView : NSResponder <NSAnimatablePropertyContainer> { -struct __VFlags2 { -} -_vFlags2; -} -@end extern NSString * const NSFullScreenModeAllScreens; -@protocol NSChangeSpelling - (void)changeSpelling:(id)sender; -@end @protocol NSIgnoreMisspelledWords - (void)ignoreSpelling:(id)sender; -@end @class NSColor, NSFont, NSNotification; -@interface NSText : NSView <NSChangeSpelling, NSIgnoreMisspelledWords> { } @end @protocol NSValidatedUserInterfaceItem - (SEL)action; @end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem; -@end @class NSArray, NSError, NSImage, NSView, NSNotificationCenter, NSURL, NSScreen, NSRunningApplication; +@end @class NSDate, NSDictionary, NSError, NSException, NSNotification; @interface NSApplication : NSResponder <NSUserInterfaceValidations> { } @end enum { NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 }; typedef NSUInteger NSApplicationTerminateReply; @protocol NSApplicationDelegate <NSObject> @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; -@end enum { +@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; +@interface NSCell : NSObject <NSCopying, NSCoding> { } -_CFlags; +@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; +typedef struct { +} +CVTimeStamp; @interface CIImage : NSObject <NSCoding, NSCopying> { } typedef int CIFormat; @@ -175,7 +211,7 @@ extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn stat - (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r; - (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs; - (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d; -@end @class NSURL; +@end extern NSString* const QCRendererEventKey; @protocol QCCompositionRenderer - (NSDictionary*) attributes; @end @interface QCRenderer : NSObject <QCCompositionRenderer> { } @@ -188,11 +224,34 @@ extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn stat ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, }; @class ICDevice; @protocol ICDeviceDelegate <NSObject> @required - (void)didRemoveDevice:(ICDevice*)device; -@end @class ICCameraDevice; +@end extern NSString *const ICScannerStatusWarmingUp; @class ICScannerDevice; @protocol ICScannerDeviceDelegate <ICDeviceDelegate> @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner; @end - + +typedef long unsigned int __darwin_size_t; +typedef __darwin_size_t size_t; +typedef unsigned long CFTypeID; +struct CGPoint { + CGFloat x; + CGFloat y; +}; +typedef struct CGPoint CGPoint; +typedef struct CGGradient *CGGradientRef; +typedef uint32_t CGGradientDrawingOptions; +extern CFTypeID CGGradientGetTypeID(void); +extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef + space, const CGFloat components[], const CGFloat locations[], size_t count); +extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space, + CFArrayRef colors, const CGFloat locations[]); +extern CGGradientRef CGGradientRetain(CGGradientRef gradient); +extern void CGGradientRelease(CGGradientRef gradient); +typedef struct CGContext *CGContextRef; +extern void CGContextDrawLinearGradient(CGContextRef context, + CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, + CGGradientDrawingOptions options); +extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); + //===----------------------------------------------------------------------===// // Test cases. //===----------------------------------------------------------------------===// @@ -371,6 +430,7 @@ CFMutableArrayRef f13_autorelease_d() { [(id) A autorelease]; CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object sent -autorelease too many times}} CFRelease(B); // no-warning + while (1) {} } @@ -389,6 +449,18 @@ void f15() { CFRelease(*B); // no-warning } +// Test when we pass NULL to CFRetain/CFRelease. +void f16(int x, CFTypeRef p) { + if (p) + return; + + if (x) { + CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}} + } + else { + CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}} + } +} // Test basic tracking of ivars associated with 'self'. For the retain/release // checker we currently do not want to flag leaks associated with stores @@ -559,7 +631,7 @@ void rdar6704930(unsigned char *s, unsigned int length) { int rdar_6257780_Case1() { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSArray *array = [NSArray array]; - [array release]; // expected-warning{{Incorrect decrement of the reference count of an object is not owned at this point by the caller}} + [array release]; // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} [pool drain]; return 0; } @@ -603,7 +675,8 @@ typedef CFTypeRef OtherRef; @end //===----------------------------------------------------------------------===// -//<rdar://problem/6320065> false positive - init method returns an object owned by caller +//<rdar://problem/6320065> false positive - init method returns an object +// owned by caller //===----------------------------------------------------------------------===// @interface RDar6320065 : NSObject { @@ -646,7 +719,21 @@ int RDar6320065_test() { } //===----------------------------------------------------------------------===// -// <rdar://problem/6859457> [NSData dataWithBytesNoCopy] does not return a retained object +// <rdar://problem/7129086> -awakeAfterUsingCoder: returns an owned object +// and claims the receiver +//===----------------------------------------------------------------------===// + +@interface RDar7129086 : NSObject {} @end +@implementation RDar7129086 +- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder { + [self release]; // no-warning + return [NSString alloc]; // no-warning +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/6859457> [NSData dataWithBytesNoCopy] does not return a +// retained object //===----------------------------------------------------------------------===// @interface RDar6859457 : NSObject {} @@ -750,7 +837,7 @@ void IOServiceNameMatching_wrapper(const char * name) { IOServiceNameMatching(name); // expected-warning{{leak}} } -__attribute__((cf_returns_retained)) CFDictionaryRef CreateDict(); +CF_RETURNS_RETAINED CFDictionaryRef CreateDict(); void IOServiceAddNotification_wrapper(mach_port_t masterPort, const io_name_t notificationType, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) { @@ -791,19 +878,241 @@ void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, } //===----------------------------------------------------------------------===// +// Test of handling objects whose references "escape" to containers. +//===----------------------------------------------------------------------===// + +// <rdar://problem/6539791> +void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) { + CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(y, key, x); + CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); + if (value) { + CFDictionaryAddValue(x, val_key, value); // no-warning + CFRelease(value); + CFDictionaryAddValue(y, val_key, value); // no-warning + } +} + +// <rdar://problem/6560661> +// Same issue, except with "AppendValue" functions. +void rdar_6560661(CFMutableArrayRef x) { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); + // CFArrayAppendValue keeps a reference to value. + CFArrayAppendValue(x, value); + CFRelease(value); + CFRetain(value); + CFRelease(value); // no-warning +} + +// <rdar://problem/7152619> +// Same issue, excwept with "CFAttributeStringSetAttribute". +void rdar_7152619(CFStringRef str) { + CFAttributedStringRef string = CFAttributedStringCreate(kCFAllocatorDefault, str, 0); + CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 100, string); + CFRelease(string); + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} + CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 1), str, number); + [number release]; + [number retain]; + CFRelease(attrString); +} + +//===----------------------------------------------------------------------===// +// Test of handling CGGradientXXX functions. +//===----------------------------------------------------------------------===// + +void rdar_7184450(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, + CGPoint myEndPoint) { + size_t num_locations = 6; + CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; + CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, + x, // Start color + 207.0/255.0, 39.0/255.0, 39.0/255.0, x, + 147.0/255.0, 21.0/255.0, 22.0/255.0, x, + 175.0/255.0, 175.0/255.0, 175.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x + }; // End color + + CGGradientRef myGradient = + CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), // expected-warning{{leak}} + components, locations, num_locations); + + CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, + 0); + CGGradientRelease(myGradient); +} + +void rdar_7184450_pos(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, + CGPoint myEndPoint) { + size_t num_locations = 6; + CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; + CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, + x, // Start color + 207.0/255.0, 39.0/255.0, 39.0/255.0, x, + 147.0/255.0, 21.0/255.0, 22.0/255.0, x, + 175.0/255.0, 175.0/255.0, 175.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x + }; // End color + + CGGradientRef myGradient = + CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), components, locations, num_locations); // expected-warning 2 {{leak}} + + CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, + 0); +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7299394> clang false positive: retained instance passed to +// thread in pthread_create marked as leak +// +// Until we have full IPA, the analyzer should stop tracking the reference +// count of objects passed to pthread_create. +// +//===----------------------------------------------------------------------===// + +struct _opaque_pthread_t {}; +struct _opaque_pthread_attr_t {}; +typedef struct _opaque_pthread_t *__darwin_pthread_t; +typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t; +typedef __darwin_pthread_t pthread_t; +typedef __darwin_pthread_attr_t pthread_attr_t; + +int pthread_create(pthread_t * restrict, const pthread_attr_t * restrict, + void *(*)(void *), void * restrict); + +void *rdar_7299394_start_routine(void *p) { + [((id) p) release]; + return 0; +} +void rdar_7299394(pthread_attr_t *attr, pthread_t *thread, void *args) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + pthread_create(thread, attr, rdar_7299394_start_routine, number); +} +void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7283567> False leak associated with call to +// CVPixelBufferCreateWithBytes () +// +// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and +// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the +// pixel buffer object. These test cases show how the analyzer stops tracking +// the reference count for the objects passed for this argument. This +// could be made smarter. +//===----------------------------------------------------------------------===// + +typedef int int32_t; +typedef UInt32 FourCharCode; +typedef FourCharCode OSType; +typedef uint64_t CVOptionFlags; +typedef int32_t CVReturn; +typedef struct __CVBuffer *CVBufferRef; +typedef CVBufferRef CVImageBufferRef; +typedef CVImageBufferRef CVPixelBufferRef; +typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress ); + +extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, + size_t width, + size_t height, + OSType pixelFormatType, + void *baseAddress, + size_t bytesPerRow, + CVPixelBufferReleaseBytesCallback releaseCallback, + void *releaseRefCon, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) ; + +typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] ); + +extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator, + size_t width, + size_t height, + OSType pixelFormatType, + void *dataPtr, + size_t dataSize, + size_t numberOfPlanes, + void *planeBaseAddress[], + size_t planeWidth[], + size_t planeHeight[], + size_t planeBytesPerRow[], + CVPixelBufferReleasePlanarBytesCallback releaseCallback, + void *releaseRefCon, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) ; + +extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, + size_t width, + size_t height, + OSType pixelFormatType, + void *baseAddress, + size_t bytesPerRow, + CVPixelBufferReleaseBytesCallback releaseCallback, + void *releaseRefCon, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) ; + +CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height, + OSType pixelFormatType, void *baseAddress, + size_t bytesPerRow, + CVPixelBufferReleaseBytesCallback releaseCallback, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) { + + // For the allocated object, it doesn't really matter what type it is + // for the purpose of this test. All we want to show is that + // this is freed later by the callback. + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + + return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType, + baseAddress, bytesPerRow, releaseCallback, + number, // potentially released by callback + pixelBufferAttributes, pixelBufferOut) ; +} + +CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height, + OSType pixelFormatType, void *dataPtr, size_t dataSize, + size_t numberOfPlanes, void *planeBaseAddress[], + size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[], + CVPixelBufferReleasePlanarBytesCallback releaseCallback, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) { + + // For the allocated object, it doesn't really matter what type it is + // for the purpose of this test. All we want to show is that + // this is freed later by the callback. + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + + return CVPixelBufferCreateWithPlanarBytes(allocator, + width, height, pixelFormatType, dataPtr, dataSize, + numberOfPlanes, planeBaseAddress, planeWidth, + planeHeight, planeBytesPerRow, releaseCallback, + number, // potentially released by callback + pixelBufferAttributes, pixelBufferOut) ; +} + +//===----------------------------------------------------------------------===// // Tests of ownership attributes. //===----------------------------------------------------------------------===// typedef NSString* MyStringTy; +@protocol FooP; + @interface TestOwnershipAttr : NSObject -- (NSString*) returnsAnOwnedString __attribute__((ns_returns_retained)); // no-warning -- (NSString*) returnsAnOwnedCFString __attribute__((cf_returns_retained)); // no-warning -- (MyStringTy) returnsAnOwnedTypedString __attribute__((ns_returns_retained)); // no-warning -- (int) returnsAnOwnedInt __attribute__((ns_returns_retained)); // expected-warning{{'ns_returns_retained' attribute only applies to functions or methods that return a pointer or Objective-C object}} +- (NSString*) returnsAnOwnedString NS_RETURNS_RETAINED; // no-warning +- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning +- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning +- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions or methods that return a pointer or Objective-C object}} @end -static int ownership_attribute_doesnt_go_here __attribute__((ns_returns_retained)); // expected-warning{{'ns_returns_retained' attribute only applies to function or method types}} +static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to function or method types}} void test_attr_1(TestOwnershipAttr *X) { NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}} @@ -814,12 +1123,14 @@ void test_attr_1b(TestOwnershipAttr *X) { } @interface MyClassTestCFAttr : NSObject {} -- (NSDate*) returnsCFRetained __attribute__((cf_returns_retained)); +- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED; +- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED; - (NSDate*) alsoReturnsRetained; -- (NSDate*) returnsNSRetained __attribute__((ns_returns_retained)); +- (CFDateRef) alsoReturnsRetainedAsCF; +- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED; @end -__attribute__((cf_returns_retained)) +CF_RETURNS_RETAINED CFDateRef returnsRetainedCFDate() { return CFDateCreate(0, CFAbsoluteTimeGetCurrent()); } @@ -829,14 +1140,58 @@ CFDateRef returnsRetainedCFDate() { return (NSDate*) returnsRetainedCFDate(); // No leak. } +- (CFDateRef) returnsCFRetainedAsCF { + return returnsRetainedCFDate(); // No leak. +} + + - (NSDate*) alsoReturnsRetained { return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}} } +- (CFDateRef) alsoReturnsRetainedAsCF { + return returnsRetainedCFDate(); // expected-warning{{leak}} +} + + - (NSDate*) returnsNSRetained { return (NSDate*) returnsRetainedCFDate(); // no-warning } @end +//===----------------------------------------------------------------------===// +// Test that leaks post-dominated by "panic" functions are not reported. +// +// <rdar://problem/5905851> do not report a leak when post-dominated by a call +// to a noreturn or panic function +//===----------------------------------------------------------------------===// + +void panic() __attribute__((noreturn)); + +void test_panic_negative() { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} +} + +void test_panic_positive() { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning + panic(); +} +void test_panic_neg_2(int x) { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} + if (x) + panic(); +} + +void test_panic_pos_2(int x) { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning + if (x) + panic(); + if (!x) + panic(); +} diff --git a/test/Analysis/security-syntax-checks.m b/test/Analysis/security-syntax-checks.m new file mode 100644 index 000000000000..ebd7d172b5b4 --- /dev/null +++ b/test/Analysis/security-syntax-checks.m @@ -0,0 +1,91 @@ +// RUN: clang-cc -triple i386-apple-darwin10 -analyze -warn-security-syntactic %s -verify + +// <rdar://problem/6336718> rule request: floating point used as loop +// condition (FLP30-C, FLP-30-CPP) +// +// For reference: https://www.securecoding.cert.org/confluence/display/seccode/FLP30-C.+Do+not+use+floating+point+variables+as+loop+counters +// +void test_float_condition() { + for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // expected-warning{{Variable 'x' with floating point type 'float'}} + for (float x = 100000001.0f; x <= 100000010.0f; x += 1.0f) {} // expected-warning{{Variable 'x' with floating point type 'float'}} + for (float x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'float'}} + for (double x = 100000001.0; x <= 100000010.0; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}} + for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}} + + for (double x = 100000001.0; 100000010.0 >= x; x = x + 1.0 ) {} // expected-warning{{Variable 'x' with floating point type 'double'}} + + int i = 0; + for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++, ++i ) {} // expected-warning{{Variable 'x' with floating point type 'double'}} + + typedef float FooType; + for (FooType x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'FooType'}} +} + +// <rdar://problem/6335715> rule request: gets() buffer overflow +// Part of recommendation: 300-BSI (buildsecurityin.us-cert.gov) +char* gets(char *buf); + +void test_gets() { + char buff[1024]; + gets(buff); // expected-warning{{Call to function 'gets' is extremely insecure as it can always result in a buffer overflow}} +} + +// <rdar://problem/6337132> CWE-273: Failure to Check Whether Privileges Were +// Dropped Successfully +typedef unsigned int __uint32_t; +typedef __uint32_t __darwin_uid_t; +typedef __uint32_t __darwin_gid_t; +typedef __darwin_uid_t uid_t; +typedef __darwin_gid_t gid_t; +int setuid(uid_t); +int setregid(gid_t, gid_t); +int setreuid(uid_t, uid_t); +extern void check(int); + +void test_setuid() +{ + setuid(2); // expected-warning{{The return value from the call to 'setuid' is not checked. If an error occurs in 'setuid', the following code may execute with unexpected privileges}} + setuid(0); // expected-warning{{The return value from the call to 'setuid' is not checked. If an error occurs in 'setuid', the following code may execute with unexpected privileges}} + if (setuid (2) != 0) + abort(); + + // Currently the 'setuid' check is not flow-sensitive, and only looks + // at whether the function was called in a compound statement. This + // will lead to false negatives, but there should be no false positives. + int t = setuid(2); // no-warning + (void)setuid (2); // no-warning + + check(setuid (2)); // no-warning + + setreuid(2,2); // expected-warning{{The return value from the call to 'setreuid' is not checked. If an error occurs in 'setreuid', the following code may execute with unexpected privileges}} + setregid(2,2); // expected-warning{{The return value from the call to 'setregid' is not checked. If an error occurs in 'setregid', the following code may execute with unexpected privileges}} +} + +// <rdar://problem/6337100> CWE-338: Use of cryptographically weak prng +int rand(void); +double drand48(void); +double erand48(unsigned short[3]); +long jrand48(unsigned short[3]); +void lcong48(unsigned short[7]); +long lrand48(void); +long mrand48(void); +long nrand48(unsigned short[3]); +long random(void); +int rand_r(unsigned *); + +void test_rand() +{ + unsigned short a[7]; + unsigned b; + + rand(); // expected-warning{{Function 'rand' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}} + drand48(); // expected-warning{{Function 'drand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}} + erand48(a); // expected-warning{{Function 'erand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}} + jrand48(a); // expected-warning{{Function 'jrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}} + lcong48(a); // expected-warning{{Function 'lcong48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}} + lrand48(); // expected-warning{{Function 'lrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}} + mrand48(); // expected-warning{{Function 'mrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}} + nrand48(a); // expected-warning{{Function 'nrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}} + rand_r(&b); // expected-warning{{Function 'rand_r' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}} + random(); // expected-warning{{The 'random' function produces a sequence of values that an adversary may be able to predict. Use 'arc4random' instead}} +} diff --git a/test/Analysis/uninit-vals-ps-region.c b/test/Analysis/uninit-vals-ps-region.c index 32f787db4aeb..1561f11c9937 100644 --- a/test/Analysis/uninit-vals-ps-region.c +++ b/test/Analysis/uninit-vals-ps-region.c @@ -15,3 +15,21 @@ void f4() { if (global.data == 0) // When the true branch is feasible 'a = 3'. g(a); // no-warning } + + +// Test uninitialized value due to part of the structure being uninitialized. +struct TestUninit { int x; int y; }; +struct TestUninit test_uninit_aux(); +void test_uninit_pos() { + struct TestUninit v1 = { 0, 0 }; + struct TestUninit v2 = test_uninit_aux(); + int z; + v1.y = z; + test_unit_aux2(v2.x + v1.y); // expected-warning{{The right operand of '+' is a garbage value}} +} +void test_uninit_neg() { + struct TestUninit v1 = { 0, 0 }; + struct TestUninit v2 = test_uninit_aux(); + test_unit_aux2(v2.x + v1.y); // no-warning +} + diff --git a/test/Analysis/uninit-vals-ps.c b/test/Analysis/uninit-vals-ps.c index 41771265367a..759c7edbcc57 100644 --- a/test/Analysis/uninit-vals-ps.c +++ b/test/Analysis/uninit-vals-ps.c @@ -1,4 +1,4 @@ -// RUN: clang-cc -analyze -checker-cfref -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s struct FPRec { @@ -22,7 +22,7 @@ int f2() { int x; - if (x+1) // expected-warning{{Branch}} + if (x+1) // expected-warning{{The left operand of '+' is a garbage value}} return 1; return 2; @@ -31,13 +31,13 @@ int f2() { int f2_b() { int x; - return ((x+1)+2+((x))) + 1 ? 1 : 2; // expected-warning{{Branch}} + return ((1+x)+2+((x))) + 1 ? 1 : 2; // expected-warning{{The right operand of '+' is a garbage value}} } int f3(void) { int i; int *p = &i; - if (*p > 0) // expected-warning{{Branch condition evaluates to an uninitialized value}} + if (*p > 0) // expected-warning{{The left operand of '>' is a garbage value}} return 0; else return 1; @@ -61,7 +61,7 @@ int f5(void) { int ret_uninit() { int i; int *p = &i; - return *p; // expected-warning{{Uninitialized or undefined value returned to caller.}} + return *p; // expected-warning{{Undefined or garbage value returned to caller}} } // <rdar://problem/6451816> @@ -83,3 +83,43 @@ CFStringRef rdar_6451816(CFNumberRef nr) { return CFStringConvertEncodingToIANACharSetName(encoding); // no-warning } +// PR 4630 - false warning with nonnull attribute +// This false positive (due to a regression) caused the analyzer to falsely +// flag a "return of uninitialized value" warning in the first branch due to +// the nonnull attribute. +void pr_4630_aux(char *x, int *y) __attribute__ ((nonnull (1))); +void pr_4630_aux_2(char *x, int *y); +int pr_4630(char *a, int y) { + int x; + if (y) { + pr_4630_aux(a, &x); + return x; // no-warning + } + else { + pr_4630_aux_2(a, &x); + return x; // no-warning + } +} + +// PR 4631 - False positive with union initializer +// Previously the analyzer didn't examine the compound initializers of unions, +// resulting in some false positives for initializers with side-effects. +union u_4631 { int a; }; +struct s_4631 { int a; }; +int pr4631_f2(int *p); +int pr4631_f3(void *q); +int pr4631_f1(void) +{ + int x; + union u_4631 m = { pr4631_f2(&x) }; + pr4631_f3(&m); // tell analyzer that we use m + return x; // no-warning +} +int pr4631_f1_b(void) +{ + int x; + struct s_4631 m = { pr4631_f2(&x) }; + pr4631_f3(&m); // tell analyzer that we use m + return x; // no-warning +} + diff --git a/test/Analysis/uninit-vals.c b/test/Analysis/uninit-vals.c index d69250b65c0b..8428ca4f81cd 100644 --- a/test/Analysis/uninit-vals.c +++ b/test/Analysis/uninit-vals.c @@ -23,7 +23,7 @@ int f4(int x) { return y; // expected-warning {{use of uninitialized variable}} } -int f5() { +void f5() { int a; a = 30; // no-warning } diff --git a/test/Analysis/unions-region.m b/test/Analysis/unions-region.m new file mode 100644 index 000000000000..be4f1852bf02 --- /dev/null +++ b/test/Analysis/unions-region.m @@ -0,0 +1,41 @@ +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range %s -verify + +//===-- unions-region.m ---------------------------------------------------===// +// +// This file tests the analyzer's reasoning about unions. +// +//===----------------------------------------------------------------------===// + +// [testA] When using RegionStore, this test case previously had a +// false positive of a 'pass-by-value argument is uninitialized' +// warning at the call to 'testA_aux' and 'testA_aux_2'. +union u_testA { + unsigned i; + float f; +}; + +float testA(float f) { + int testA_aux(unsigned x); + int testA_aux_2(union u_testA z); + + union u_testA swap; + swap.f = f; + + if (testA_aux(swap.i)) // no-warning + swap.i = ((swap.i & 0xffff0000) >> 16) | ((swap.i & 0x0000fffff) << 16); + + testA_aux_2(swap); // no-warning + + return swap.f; +} + +// [testB] When using RegionStore, this test case previously had a +// false positive of a 'pass-by-value argument is uninitialized' +// warning at the call to 'testB_aux'. +void testB(int i) { + void testB_aux(short z); + union { short x[2]; unsigned y; } val; + val.y = 10; + testB_aux(val.x[1]); // no-warning +} + diff --git a/test/Analysis/unused-ivars.m b/test/Analysis/unused-ivars.m index 632b395c3e08..aacd44e7e677 100644 --- a/test/Analysis/unused-ivars.m +++ b/test/Analysis/unused-ivars.m @@ -1,10 +1,45 @@ -// RUN: clang-cc -analyze -warn-objc-unused-ivars %s -verify +// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -warn-objc-unused-ivars %s -verify -@interface A -{ - @private int x; // expected-warning {{Instance variable 'x' in class 'A' is never used}} +//===--- BEGIN: Delta-debugging reduced headers. --------------------------===// + +@protocol NSObject +- (id)retain; +- (oneway void)release; +@end +@interface NSObject <NSObject> {} +- (id)init; ++ (id)alloc; +@end + +//===--- END: Delta-debugging reduced headers. ----------------------------===// + +// This test case tests the basic functionality of the unused ivar test. +@interface TestA { +@private + int x; // expected-warning {{Instance variable 'x' in class 'TestA' is never used}} } @end +@implementation TestA @end -@implementation A @end +// This test case tests whether the unused ivar check handles blocks that +// reference an instance variable. (<rdar://problem/7075531>) +@interface TestB : NSObject { +@private + id _ivar; // no-warning +} +@property (readwrite,retain) id ivar; +@end + +@implementation TestB +- (id)ivar { + __attribute__((__blocks__(byref))) id value = ((void*)0); + void (^b)() = ^{ value = _ivar; }; + b(); + return value; +} +- (void)setIvar:(id)newValue { + void (^b)() = ^{ [_ivar release]; _ivar = [newValue retain]; }; + b(); +} +@end diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d5e23278729b..2a7f132fb5df 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,6 @@ set(CLANG_TEST_DIRECTORIES "Analysis" + "CodeCompletion" "CodeGen" "CodeGenCXX" "CodeGenObjC" @@ -24,37 +25,59 @@ set(CLANG_TEST_DIRECTORIES include(FindPythonInterp) if(PYTHONINTERP_FOUND) get_target_property(LLVM_TOOLS_PATH clang RUNTIME_OUTPUT_DIRECTORY) - set(TESTING_EXTRA_PATHS - "${LLVM_TOOLS_PATH}/${CMAKE_CFG_INTDIR}:${LLVM_SOURCE_DIR}/test/Scripts") + get_target_property(LLVM_LIBS_PATH clang LIBRARY_OUTPUT_DIRECTORY) set(CLANG_TEST_EXTRA_ARGS) if (MSVC OR XCODE) set(CLANG_TEST_EXTRA_ARGS "--no-progress-bar") endif() - set(all_testdirs) - foreach(testdir ${CLANG_TEST_DIRECTORIES}) - add_custom_target(clang-test-${testdir} - ${PYTHON_EXECUTABLE} - ${LLVM_SOURCE_DIR}/tools/clang/utils/test/MultiTestRunner.py - "--path=${TESTING_EXTRA_PATHS}" - -s ${CLANG_TEST_EXTRA_ARGS} - --clang=${LLVM_TOOLS_PATH}/${CMAKE_CFG_INTDIR}/clang - --clang-cc=${LLVM_TOOLS_PATH}/${CMAKE_CFG_INTDIR}/clang-cc - ${CMAKE_CURRENT_SOURCE_DIR}/${testdir}/ - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMENT "Running Clang regression tests in ${testdir}") - list(APPEND all_testdirs ${CMAKE_CURRENT_SOURCE_DIR}/${testdir}/) + foreach(testdir ${CLANG_TEST_DIRECTORIES}) + add_custom_target(clang-test-${testdir} + COMMAND sed -e "s#\@LLVM_SOURCE_DIR\@#${LLVM_MAIN_SRC_DIR}#" + -e "s#\@LLVM_BINARY_DIR\@#${LLVM_BINARY_DIR}#" + -e "s#\@LLVM_TOOLS_DIR\@#${LLVM_TOOLS_PATH}/${CMAKE_CFG_INTDIR}#" + -e "s#\@LLVM_LIBS_DIR\@#${LLVM_LIBS_PATH}/${CMAKE_CFG_INTDIR}#" + -e "s#\@CLANG_SOURCE_DIR\@#${CMAKE_CURRENT_SOURCE_DIR}/..#" + -e "s#\@CLANG_BINARY_DIR\@#${CMAKE_CURRENT_BINARY_DIR}/..#" + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in > + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + COMMAND ${PYTHON_EXECUTABLE} + ${LLVM_SOURCE_DIR}/utils/lit/lit.py + -sv ${CLANG_TEST_EXTRA_ARGS} + ${CMAKE_CURRENT_BINARY_DIR}/${testdir} + DEPENDS clang clang-cc index-test + COMMENT "Running Clang regression tests in ${testdir}") endforeach() add_custom_target(clang-test - ${PYTHON_EXECUTABLE} - ${LLVM_SOURCE_DIR}/tools/clang/utils/test/MultiTestRunner.py - "--path=${TESTING_EXTRA_PATHS}" - -s ${CLANG_TEST_EXTRA_ARGS} - --clang=${LLVM_TOOLS_PATH}/${CMAKE_CFG_INTDIR}/clang - --clang-cc=${LLVM_TOOLS_PATH}/${CMAKE_CFG_INTDIR}/clang-cc - ${all_testdirs} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS clang clang-cc index-test - COMMENT "Running Clang regression tests") + COMMAND sed -e "s#\@LLVM_SOURCE_DIR\@#${LLVM_MAIN_SRC_DIR}#" + -e "s#\@LLVM_BINARY_DIR\@#${LLVM_BINARY_DIR}#" + -e "s#\@LLVM_TOOLS_DIR\@#${LLVM_TOOLS_PATH}/${CMAKE_CFG_INTDIR}#" + -e "s#\@LLVM_LIBS_DIR\@#${LLVM_LIBS_PATH}/${CMAKE_CFG_INTDIR}#" + -e "s#\@CLANG_SOURCE_DIR\@#${CMAKE_CURRENT_SOURCE_DIR}/..#" + -e "s#\@CLANG_BINARY_DIR\@#${CMAKE_CURRENT_BINARY_DIR}/..#" + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in > + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + COMMAND ${PYTHON_EXECUTABLE} + ${LLVM_SOURCE_DIR}/utils/lit/lit.py + -sv ${CLANG_TEST_EXTRA_ARGS} + ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS clang clang-cc index-test + COMMENT "Running Clang regression tests") + + add_custom_target(clang-c++tests + COMMAND sed -e "s#\@LLVM_SOURCE_DIR\@#${LLVM_MAIN_SRC_DIR}#" + -e "s#\@LLVM_BINARY_DIR\@#${LLVM_BINARY_DIR}#" + -e "s#\@LLVM_TOOLS_DIR\@#${LLVM_TOOLS_PATH}/${CMAKE_CFG_INTDIR}#" + -e "s#\@LLVM_LIBS_DIR\@#${LLVM_LIBS_PATH}/${CMAKE_CFG_INTDIR}#" + -e "s#\@CLANG_SOURCE_DIR\@#${CMAKE_CURRENT_SOURCE_DIR}/..#" + -e "s#\@CLANG_BINARY_DIR\@#${CMAKE_CURRENT_BINARY_DIR}/..#" + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in > + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + COMMAND ${PYTHON_EXECUTABLE} + ${LLVM_SOURCE_DIR}/utils/lit/lit.py + -sv ${CLANG_TEST_EXTRA_ARGS} + ${CMAKE_CURRENT_SOURCE_DIR}/../utils/C++Tests + DEPENDS clang clang-cc index-test + COMMENT "Running Clang regression tests") endif() diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp new file mode 100644 index 000000000000..e2c76f918336 --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp @@ -0,0 +1,27 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +namespace N1 { + struct X { }; + int& f(void*); +} + +namespace N2 { + template<typename T> struct Y { }; +} + +namespace N3 { + void test() { + int &ir = f((N2::Y<N1::X>*)0); + } +} + +int g(void *); +long g(N1::X); + +namespace N1 { + void h(int (*)(void *)); +} + +void test() { + h((&g)); +} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp new file mode 100644 index 000000000000..677df8284a72 --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp @@ -0,0 +1,73 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +namespace N { + struct X { }; + + X operator+(X, X); + + void f(X); + void g(X); // expected-note{{candidate function}} + + void test_multiadd(X x) { + (void)(x + x); + } +} + +namespace M { + struct Y : N::X { }; +} + +void f(); + +void test_operator_adl(N::X x, M::Y y) { + (void)(x + x); + (void)(y + y); +} + +void test_func_adl(N::X x, M::Y y) { + f(x); + f(y); + (f)(x); // expected-error{{too many arguments to function call}} + ::f(x); // expected-error{{too many arguments to function call}} +} + +namespace N { + void test_multiadd2(X x) { + (void)(x + x); + } +} + + +void test_func_adl_only(N::X x) { + g(x); +} + +namespace M { + int g(N::X); // expected-note{{candidate function}} + + void test(N::X x) { + g(x); // expected-error{{call to 'g' is ambiguous; candidates are:}} + int i = (g)(x); + + int g(N::X); + g(x); // okay; calls locally-declared function, no ADL + } +} + + +void test_operator_name_adl(N::X x) { + (void)operator+(x, x); +} + +struct Z { }; +int& f(Z); + +namespace O { + char &f(); + void test_global_scope_adl(Z z) { + { + int& ir = f(z); + } + } +} + diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp new file mode 100644 index 000000000000..8f0bed8789fe --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp @@ -0,0 +1,42 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +namespace A { + class A { + friend void func(A); + friend A operator+(A,A); + }; +} + +namespace B { + class B { + static void func(B); + }; + B operator+(B,B); +} + +namespace D { + class D {}; +} + +namespace C { + class C {}; + void func(C); + C operator+(C,C); + D::D operator+(D::D,D::D); +} + +namespace D { + using namespace C; +} + +namespace Test { + void test() { + func(A::A()); + func(B::B()); // expected-error {{ no matching function for call to 'func' }} + func(C::C()); + A::A() + A::A(); + B::B() + B::B(); + C::C() + C::C(); + D::D() + D::D(); // expected-error {{ invalid operands to binary expression ('D::D' and 'D::D') }} + } +} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp b/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp new file mode 100644 index 000000000000..cb9d942ba6f6 --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// elaborated-type-specifier: +// class-key '::'? nested-name-specifier? 'template'? simple-template-id +// Tests that this form is accepted by the compiler but does not follow +// the elaborated lookup rules of [basic.lookup.elab]. + +template <typename> class Ident {}; // expected-note {{previous use is here}} + +namespace A { + template <typename> void Ident(); + + class Ident<int> AIdent; // expected-error {{refers to a function template}} + class ::Ident<int> AnotherIdent; +} + +class Ident<int> GlobalIdent; +union Ident<int> GlobalIdent; // expected-error {{ tag type that does not match }} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp new file mode 100644 index 000000000000..b32948b4a608 --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp @@ -0,0 +1,65 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +namespace Ints { + int zero = 0; // expected-note {{candidate found by name lookup is 'Ints::zero'}} + void f(int); // expected-note 3 {{candidate function}} + void g(int); +} + +namespace Floats { + float zero = 0.0f; // expected-note {{candidate found by name lookup is 'Floats::zero'}} + void f(float); // expected-note 3 {{candidate function}} + void g(float); +} + +namespace Numbers { + using namespace Ints; + using namespace Floats; +} + +void test() { + int i = Ints::zero; + Ints::f(i); + + float f = Floats::zero; + Floats::f(f); + + double n = Numbers::zero; // expected-error {{reference to 'zero' is ambiguous}} + Numbers::f(n); // expected-error{{call to 'f' is ambiguous}} + Numbers::f(i); + Numbers::f(f); +} + +namespace Numbers { + struct Number { + explicit Number(double d) : d(d) {} + double d; + }; + Number zero(0.0f); + void g(Number); +} + +void test2() { + Numbers::Number n = Numbers::zero; + Numbers::f(n); // expected-error {{no matching function for call to 'f'}} + Numbers::g(n); +} + +namespace Numbers2 { + using Numbers::f; + using Numbers::g; +} + +void test3() { + Numbers::Number n = Numbers::zero; + Numbers2::f(n); // expected-error {{no matching function for call to 'f'}} + Numbers2::g(n); + + int i = Ints::zero; + Numbers2::f(i); + Numbers2::g(i); // expected-error {{incompatible type passing 'int'}} + + float f = Floats::zero; + Numbers2::f(f); + Numbers2::g(f); // expected-error {{incompatible type passing 'float'}} +} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p3.cpp new file mode 100644 index 000000000000..7a51a7bb1df0 --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p3.cpp @@ -0,0 +1,41 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// This is basically paraphrased from the standard. + +namespace Root { + int i = 0; + void f(); +} + +namespace A { + using namespace Root; +} + +namespace B { + using namespace Root; +} + +namespace AB { + using namespace A; + using namespace B; +} + +void test() { + if (AB::i) + AB::f(); +} + +namespace C { + using Root::i; + using Root::f; +} + +namespace AC { + using namespace A; + using namespace C; +} + +void test2() { + if (AC::i) + AC::f(); +} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p4.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p4.cpp new file mode 100644 index 000000000000..2c0ce80d8ce6 --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p4.cpp @@ -0,0 +1,25 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +namespace A { + int a; +} + +namespace C { + int c; +} + +namespace B { + using namespace C; + int b; +} + +namespace C { + using namespace B; + using namespace A; +} + +void test() { + C::a++; + C::b++; + C::c++; +} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p5.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p5.cpp new file mode 100644 index 000000000000..78af521c9103 --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p5.cpp @@ -0,0 +1,35 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +namespace A { + struct x {}; // expected-note {{candidate found by name lookup is 'A::x'}} + int x; // expected-note {{candidate found by name lookup is 'A::x'}} + + struct y {}; // expected-note {{type declaration hidden}} + + struct z; + void z(float); +} + +namespace B { + struct x {}; // expected-note {{candidate found by name lookup is 'B::x'}} + float x; // expected-note {{candidate found by name lookup is 'B::x'}} + + float y; // expected-note {{declaration hides type}} + + void z(int); +} + +namespace AB { + using namespace A; + using namespace B; +} + +void test() { + struct AB::x foo; // expected-error {{reference to 'x' is ambiguous}} + int i = AB::x; // expected-error {{reference to 'x' is ambiguous}} + + struct AB::y bar; + float f = AB::y; // expected-error {{a type named 'y' is hidden by a declaration in a different namespace}} + AB::z(i); + AB::z(f); +} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp index 1daf0ddec6c0..7fd1b53c2cb0 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp @@ -1,9 +1,7 @@ // RUN: clang-cc -fsyntax-only -verify %s -// XFAIL -// FIXME: This part is here to demonstrate the failure in looking up 'f', it can -// be removed once the whole test passes. typedef int f; + namespace N0 { struct A { friend void f(); diff --git a/test/CXX/basic/basic.start/basic.start.main/p2a.cpp b/test/CXX/basic/basic.start/basic.start.main/p2a.cpp new file mode 100644 index 000000000000..a6a758798949 --- /dev/null +++ b/test/CXX/basic/basic.start/basic.start.main/p2a.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +typedef int Int; +typedef char Char; +typedef Char* Carp; + +Int main(Int argc, Carp argv[]) { +} diff --git a/test/CXX/basic/basic.start/basic.start.main/p2b.cpp b/test/CXX/basic/basic.start/basic.start.main/p2b.cpp new file mode 100644 index 000000000000..caecf6060881 --- /dev/null +++ b/test/CXX/basic/basic.start/basic.start.main/p2b.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +typedef int Int; +typedef char Char; +typedef Char* Carp; + +Int main(Int argc, Carp argv[], Char *env[]) { +} diff --git a/test/CXX/basic/basic.start/basic.start.main/p2c.cpp b/test/CXX/basic/basic.start/basic.start.main/p2c.cpp new file mode 100644 index 000000000000..8587d8cec791 --- /dev/null +++ b/test/CXX/basic/basic.start/basic.start.main/p2c.cpp @@ -0,0 +1,4 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +int main() { +} diff --git a/test/CXX/basic/basic.start/basic.start.main/p2d.cpp b/test/CXX/basic/basic.start/basic.start.main/p2d.cpp new file mode 100644 index 000000000000..777b5ceb743a --- /dev/null +++ b/test/CXX/basic/basic.start/basic.start.main/p2d.cpp @@ -0,0 +1,4 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +static int main() { // expected-error {{'main' is not allowed to be declared static}} +} diff --git a/test/CXX/basic/basic.start/basic.start.main/p2e.cpp b/test/CXX/basic/basic.start/basic.start.main/p2e.cpp new file mode 100644 index 000000000000..087cf77476ad --- /dev/null +++ b/test/CXX/basic/basic.start/basic.start.main/p2e.cpp @@ -0,0 +1,4 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +inline int main() { // expected-error {{'main' is not allowed to be declared inline}} +} diff --git a/test/CXX/basic/basic.start/basic.start.main/p2f.cpp b/test/CXX/basic/basic.start/basic.start.main/p2f.cpp new file mode 100644 index 000000000000..b7845b13e9a4 --- /dev/null +++ b/test/CXX/basic/basic.start/basic.start.main/p2f.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void // expected-error {{error: 'main' must return 'int'}} +main( // expected-error {{error: first argument of 'main' should be of type 'int'}} + float a +) { +} diff --git a/test/CXX/basic/basic.start/basic.start.main/p2g.cpp b/test/CXX/basic/basic.start/basic.start.main/p2g.cpp new file mode 100644 index 000000000000..4cedcdb91657 --- /dev/null +++ b/test/CXX/basic/basic.start/basic.start.main/p2g.cpp @@ -0,0 +1,4 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +int main(int argc, const char* const* argv) { +} diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-nodef.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-nodef.cpp new file mode 100644 index 000000000000..ff653d5fef08 --- /dev/null +++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-nodef.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +int *use_new(int N) { + return new int [N]; +} + +int std = 17; diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp new file mode 100644 index 000000000000..f3499e4286bc --- /dev/null +++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp @@ -0,0 +1,25 @@ +// RUN: clang-cc -fsyntax-only -verify %s +int *use_new(int N) { + if (N == 1) + return new int; + + return new int [N]; +} + +void use_delete(int* ip, int N) { + if (N == 1) + delete ip; + else + delete [] ip; +} + +namespace std { + class bad_alloc { }; + + typedef __SIZE_TYPE__ size_t; +} + +void* operator new(std::size_t) throw(std::bad_alloc); +void* operator new[](std::size_t) throw(std::bad_alloc); +void operator delete(void*) throw(); +void operator delete[](void*) throw(); diff --git a/test/CXX/class.derived/class.virtual/p12.cpp b/test/CXX/class.derived/class.virtual/p12.cpp new file mode 100644 index 000000000000..b5974a021180 --- /dev/null +++ b/test/CXX/class.derived/class.virtual/p12.cpp @@ -0,0 +1,19 @@ +// RUN: clang-cc -ast-print %s | FileCheck %s + +// CHECK: test12_A::foo() +struct test12_A { + virtual void foo(); + + void bar() { + test12_A::foo(); + } +}; + +// CHECK: xp->test24_B::wibble() +struct test24_B { + virtual void wibble(); +}; + +void foo(test24_B *xp) { + xp->test24_B::wibble(); +} diff --git a/test/CXX/class/class.friend/p1-ambiguous.cpp b/test/CXX/class/class.friend/p1-ambiguous.cpp new file mode 100644 index 000000000000..a02bc5337522 --- /dev/null +++ b/test/CXX/class/class.friend/p1-ambiguous.cpp @@ -0,0 +1,37 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// Make sure that friend declarations don't introduce ambiguous +// declarations. + +// Test case courtesy of Shantonu Sen. +// Bug 4784. + +class foo; + +extern "C" { + int c_func(foo *a); +}; +int cpp_func(foo *a); + +class foo { +public: + friend int c_func(foo *a); + friend int cpp_func(foo *a); + int caller(); +private: + int x; +}; + +int c_func(foo *a) { + return a->x; +} + +int cpp_func(foo *a) { + return a->x; +} + +int foo::caller() { + c_func(this); + cpp_func(this); + return 0; +} diff --git a/test/CXX/class/class.friend/p1.cpp b/test/CXX/class/class.friend/p1.cpp new file mode 100644 index 000000000000..7065a7e917fd --- /dev/null +++ b/test/CXX/class/class.friend/p1.cpp @@ -0,0 +1,76 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct Outer { + struct Inner { + int intfield; + }; +}; + +struct Base { + void base_member(); + + typedef int Int; + Int typedeffed_member(); +}; + +struct Derived : public Base { +}; + +int myglobal; + +void global_function(); +extern "C" { + void global_c_function(); +} + +class A { + class AInner { + }; + + friend class PreDeclared; + friend class Outer::Inner; + friend int Outer::Inner::intfield; // expected-error {{ friends can only be classes or functions }} + friend int Outer::Inner::missing_field; //expected-error {{ friends can only be classes or functions }} + friend int myoperation(float); // okay + friend int myglobal; // expected-error {{ friends can only be classes or functions }} + + friend void global_function(); + friend void global_c_function(); + + friend class UndeclaredSoFar; + UndeclaredSoFar x; // expected-error {{ unknown type name 'UndeclaredSoFar' }} + + void a_member(); + friend void A::a_member(); // expected-error {{ friends cannot be members of the declaring class }} + friend void a_member(); // okay (because we ignore class scopes when looking up friends) + friend class A::AInner; // this is okay as an extension + friend class AInner; // okay, refers to ::AInner + + friend void Derived::missing_member(); // expected-error {{ no function named 'missing_member' with type 'void ()' was found in the specified scope }} + + friend void Derived::base_member(); // expected-error {{ no function named 'base_member' with type 'void ()' was found in the specified scope }} + + friend int Base::typedeffed_member(); // okay: should look through typedef + + // These test that the friend is properly not being treated as a + // member function. + friend A operator|(const A& l, const A& r); // okay + friend A operator|(const A& r); // expected-error {{ overloaded 'operator|' must be a binary operator (has 1 parameter) }} + + friend operator bool() const; // expected-error {{ must use a qualified name when declaring a conversion operator as a friend }} + + typedef void ftypedef(); + friend ftypedef typedeffed_function; // okay (because it's not declared as a member) + + class facet; + friend class facet; // should not assert + class facet {}; +}; + +A::UndeclaredSoFar y; // expected-error {{no type named 'UndeclaredSoFar' in 'class A'}} + +class PreDeclared; + +int myoperation(float f) { + return (int) f; +} diff --git a/test/CXX/class/class.friend/p2.cpp b/test/CXX/class/class.friend/p2.cpp new file mode 100644 index 000000000000..98be2049e756 --- /dev/null +++ b/test/CXX/class/class.friend/p2.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct B0; + +class A { + friend class B {}; // expected-error {{cannot define a type in a friend declaration}} + friend int; // expected-error {{friends can only be classes or functions}} + friend B0; // expected-error {{must specify 'struct' to befriend}} + friend class C; // okay +}; diff --git a/test/CXX/class/class.friend/p6.cpp b/test/CXX/class/class.friend/p6.cpp new file mode 100644 index 000000000000..2e8153c6c047 --- /dev/null +++ b/test/CXX/class/class.friend/p6.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class A { + friend static class B; // expected-error {{'static' is invalid in friend declarations}} + friend extern class C; // expected-error {{'extern' is invalid in friend declarations}} + friend auto class D; // expected-error {{'auto' is invalid in friend declarations}} + friend register class E; // expected-error {{'register' is invalid in friend declarations}} + friend mutable class F; // expected-error {{'mutable' is invalid in friend declarations}} + friend typedef class G; // expected-error {{'typedef' is invalid in friend declarations}} +}; diff --git a/test/CXX/class/class.local/p3.cpp b/test/CXX/class/class.local/p3.cpp index d888a6d93633..9c625d18c95c 100644 --- a/test/CXX/class/class.local/p3.cpp +++ b/test/CXX/class/class.local/p3.cpp @@ -27,4 +27,4 @@ void f3(int a) { // expected-note{{'a' declared here}} int f() { return a; } // expected-error{{reference to local variable 'a' declared in enclosed function 'f3'}} }; }; -}
\ No newline at end of file +} diff --git a/test/CXX/class/class.local/p4.cpp b/test/CXX/class/class.local/p4.cpp index 40702ad96899..f2432ec97393 100644 --- a/test/CXX/class/class.local/p4.cpp +++ b/test/CXX/class/class.local/p4.cpp @@ -7,4 +7,4 @@ void f() { static void f() { } }; -}
\ No newline at end of file +} diff --git a/test/CXX/class/class.nest/p1.cpp b/test/CXX/class/class.nest/p1.cpp new file mode 100644 index 000000000000..bbc49f9e95e7 --- /dev/null +++ b/test/CXX/class/class.nest/p1.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class Outer { + int x; + static int sx; + + // C++0x will likely relax this rule in this specific case, but + // we'll still need to enforce it in C++03 mode. See N2253 (or + // successor). + class Inner { + static char a[sizeof(x)]; // expected-error {{ invalid use of nonstatic data member 'x' }} + static char b[sizeof(sx)]; // okay + }; +}; diff --git a/test/CXX/class/class.nested.type/p1.cpp b/test/CXX/class/class.nested.type/p1.cpp index 33bf4b4473e5..61ccd281ca93 100644 --- a/test/CXX/class/class.nested.type/p1.cpp +++ b/test/CXX/class/class.nested.type/p1.cpp @@ -1,3 +1,5 @@ +// RUN: clang-cc -fsyntax-only -verify %s + class X { public: typedef int I; @@ -8,4 +10,4 @@ public: I b; // expected-error{{unknown type name 'I'}} Y c; // expected-error{{unknown type name 'Y'}} X::Y d; -X::I e;
\ No newline at end of file +X::I e; diff --git a/test/CXX/class/class.union/p1.cpp b/test/CXX/class/class.union/p1.cpp new file mode 100644 index 000000000000..15c263467367 --- /dev/null +++ b/test/CXX/class/class.union/p1.cpp @@ -0,0 +1,105 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void abort() __attribute__((noreturn)); + +class Okay { + int a_; +}; + +class Virtual { + virtual void foo() { abort(); } // expected-note 3 {{because type 'class Virtual' has a virtual member function}} +}; + +class VirtualBase : virtual Okay { // expected-note 3 {{because type 'class VirtualBase' has a virtual base class}} +}; + +class Ctor { + Ctor() { abort(); } // expected-note 3 {{because type 'class Ctor' has a user-declared constructor}} +}; + +class CopyCtor { + CopyCtor(CopyCtor &cc) { abort(); } // expected-note 3 {{because type 'class CopyCtor' has a user-declared copy constructor}} +}; + +// FIXME: this should eventually trigger on the operator's declaration line +class CopyAssign { // expected-note 3 {{because type 'class CopyAssign' has a user-declared copy assignment operator}} + CopyAssign& operator=(CopyAssign& CA) { abort(); } +}; + +class Dtor { + ~Dtor() { abort(); } // expected-note 3 {{because type 'class Dtor' has a user-declared destructor}} +}; + +union U1 { + Virtual v; // expected-error {{union member 'v' has a non-trivial copy constructor}} + VirtualBase vbase; // expected-error {{union member 'vbase' has a non-trivial copy constructor}} + Ctor ctor; // expected-error {{union member 'ctor' has a non-trivial constructor}} + CopyCtor copyctor; // expected-error {{union member 'copyctor' has a non-trivial copy constructor}} + CopyAssign copyassign; // expected-error {{union member 'copyassign' has a non-trivial copy assignment operator}} + Dtor dtor; // expected-error {{union member 'dtor' has a non-trivial destructor}} + Okay okay; +}; + +union U2 { + struct { + Virtual v; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy constructor}} + } m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}} + struct { + VirtualBase vbase; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy constructor}} + } m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}} + struct { + Ctor ctor; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial constructor}} + } m3; // expected-error {{union member 'm3' has a non-trivial constructor}} + struct { + CopyCtor copyctor; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy constructor}} + } m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}} + struct { + CopyAssign copyassign; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy assignment operator}} + } m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}} + struct { + Dtor dtor; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial destructor}} + } m6; // expected-error {{union member 'm6' has a non-trivial destructor}} + struct { + Okay okay; + } m7; +}; + +union U3 { + struct s1 : Virtual { // expected-note {{because type 'struct U3::s1' has a base class with a non-trivial copy constructor}} + } m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}} + struct s2 : VirtualBase { // expected-note {{because type 'struct U3::s2' has a base class with a non-trivial copy constructor}} + } m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}} + struct s3 : Ctor { // expected-note {{because type 'struct U3::s3' has a base class with a non-trivial constructor}} + } m3; // expected-error {{union member 'm3' has a non-trivial constructor}} + struct s4 : CopyCtor { // expected-note {{because type 'struct U3::s4' has a base class with a non-trivial copy constructor}} + } m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}} + struct s5 : CopyAssign { // expected-note {{because type 'struct U3::s5' has a base class with a non-trivial copy assignment operator}} + } m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}} + struct s6 : Dtor { // expected-note {{because type 'struct U3::s6' has a base class with a non-trivial destructor}} + } m6; // expected-error {{union member 'm6' has a non-trivial destructor}} + struct s7 : Okay { + } m7; +}; + +template <class A, class B> struct Either { + bool tag; + union { + A a; + B b; + }; + + Either(A& a) : tag(true), a(a) {} + Either(B& b) : tag(false), b(b) {} +}; + +/* FIXME: this should work, but crashes in template code. +void fred() { + Either<int,Virtual> virt(0); + Either<int,VirtualBase> vbase(0); + Either<int,Ctor> ctor(0); + Either<int,CopyCtor> copyctor(0); + Either<int,CopyAssign> copyassign(0); + Either<int,Dtor> dtor(0); + Either<int,Okay> okay(0); +} + */ diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp new file mode 100644 index 000000000000..2ca7165aad48 --- /dev/null +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp @@ -0,0 +1,15 @@ +// RUN: clang-cc -fsyntax-only %s + +template<typename T> struct X0 { }; +struct X1 { }; + +struct Y { + template<typename T> union X0; + template<typename T> friend union X0; + + union X1; + friend union X1; +}; + + +// FIXME: Woefully inadequate for testing diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp new file mode 100644 index 000000000000..d701f885fba1 --- /dev/null +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp @@ -0,0 +1,20 @@ +// RUN: clang-cc -fsyntax-only -verify %s +// C++0x N2914. + +struct B { + void f(char); + void g(char); + enum E { e }; + union { int x; }; +}; + +class C { + int g(); +}; + +class D2 : public B { + using B::f; + using B::e; + using B::x; + using C::g; // expected-error{{using declaration refers into 'C::', which is not a base class of 'D2'}} +}; diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp new file mode 100644 index 000000000000..63e5c3cd27b0 --- /dev/null +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc -fsyntax-only -verify %s +// C++0x N2914. + +struct A { + template<class T> void f(T); + template<class T> struct X { }; +}; + +struct B : A { + using A::f<double>; // expected-error{{using declaration can not refer to template specialization}} + using A::X<int>; // expected-error{{using declaration can not refer to template specialization}} +};
\ No newline at end of file diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp new file mode 100644 index 000000000000..f86f8fb57907 --- /dev/null +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -verify %s +// C++0x N2914. + +namespace A { + namespace B { } +} + +using A::B; // expected-error{{using declaration can not refer to namespace}} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp new file mode 100644 index 000000000000..59137eb8c9d8 --- /dev/null +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp @@ -0,0 +1,15 @@ +// RUN: clang-cc -fsyntax-only -verify %s +// C++0x N2914. + +struct X { + int i; + static int a; +}; + +using X::i; // expected-error{{using declaration can not refer to class member}} +using X::s; // expected-error{{using declaration can not refer to class member}} + +void f() { + using X::i; // expected-error{{using declaration can not refer to class member}} + using X::s; // expected-error{{using declaration can not refer to class member}} +} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp index 5d9f9e7a51c5..907a91a86ec4 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp @@ -2,11 +2,11 @@ struct S; // expected-note {{forward declaration of 'struct S'}} extern S a; -extern S f(); +extern S f(); // expected-note {{'f' declared here}} extern void g(S a); // expected-note {{candidate function}} void h() { // FIXME: This diagnostic could be better. g(a); // expected-error {{no matching function for call to 'g'}} - f(); // expected-error {{return type of called function ('struct S') is incomplete}} + f(); // expected-error {{calling 'f' with incomplete return type 'struct S'}} } diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp new file mode 100644 index 000000000000..6bdea20df6bd --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x +void f() { + auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}} +} + +void g() { + auto a; // expected-error{{declaration of variable 'a' with type 'auto' requires an initializer}} + + auto *b; // expected-error{{declaration of variable 'b' with type 'auto *' requires an initializer}} +} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp new file mode 100644 index 000000000000..fa3101c6736c --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x +void f() { + auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}} +} + +struct S { auto a; }; // expected-error{{'auto' not allowed in struct member}} + +void f(auto a) // expected-error{{'auto' not allowed in function prototype}} +{ + try { } catch (auto a) { } // expected-error{{'auto' not allowed in exception declaration}} +} + +template <auto a = 10> class C { }; // expected-error{{'auto' not allowed in template parameter}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp new file mode 100644 index 000000000000..b9cdb52f11a1 --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp @@ -0,0 +1,60 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class A {}; // expected-note 3 {{previous use is here}} + +void a1(struct A); +void a2(class A); +void a3(union A); // expected-error {{use of 'A' with tag type that does not match previous declaration}} +void a4(enum A); // expected-error {{use of 'A' with tag type that does not match previous declaration}} + +class A1 { + friend struct A; + friend class A; + friend union A; // expected-error {{use of 'A' with tag type that does not match previous declaration}} + + friend enum A; // expected-error {{ISO C++ forbids forward references to 'enum' types}} \ + // expected-error {{enum types cannot be friends}} +}; + +template <class T> struct B { // expected-note {{previous use is here}} + class Member {}; // expected-note 2 {{previous use is here}} +}; + +template <> class B<int> { + // no type Member +}; + +template <> struct B<A> { + // FIXME: the error here should be associated with the use at "void foo..." + union Member { // expected-note 4 {{previous use is here}} expected-error {{tag type that does not match previous declaration}} + void* a; + }; +}; + +void b1(struct B<float>); +void b2(class B<float>); +void b3(union B<float>); // expected-error {{use of 'B<float>' with tag type that does not match previous declaration}} +//void b4(enum B<float>); // this just doesn't parse; you can't template an enum directly + +void c1(struct B<float>::Member); +void c2(class B<float>::Member); +void c3(union B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} +void c4(enum B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} + +void d1(struct B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} +void d2(class B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} +void d3(union B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} +void d4(enum B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} + +void e1(struct B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} +void e2(class B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} +void e3(union B<A>::Member); +void e4(enum B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} + +template <class T> struct C { + void foo(class B<T>::Member); // expected-error{{no type named 'Member' in 'B<int>'}} +}; + +C<float> f1; +C<int> f2; // expected-note {{in instantiation of template class}} +C<A> f3; // expected-note {{in instantiation of template class}} diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p10.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p10.cpp new file mode 100644 index 000000000000..82f526745dc6 --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p10.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct A { + virtual void f(int a = 7); +}; + +struct B : public A { + void f(int a); +}; + +void m() { + B* pb = new B; + A* pa = pb; + pa->f(); // OK, calls pa->B::f(7) + pb->f(); // expected-error{{too few arguments}} +} diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p2.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p2.cpp new file mode 100644 index 000000000000..143a0caf82b2 --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p2.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void point(int = 3, int = 4); + +void test_point() { + point(1,2); + point(1); + point(); +} 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 new file mode 100644 index 000000000000..ea16f641dba0 --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void nondecl(int (*f)(int x = 5)) // {expected-error {{default arguments can only be specified}}} +{ + void (*f2)(int = 17) // {expected-error {{default arguments can only be specified}}} + = (void (*)(int = 42))f; // {expected-error {{default arguments can only be specified}}} +} + +struct X0 { + int (*f)(int = 17); // expected-error{{default arguments can only be specified for parameters in a function declaration}} + + void mem8(int (*fp)(int) = (int (*)(int = 17))0); // expected-error{{default arguments can only be specified for parameters in a function declaration}} +}; diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp new file mode 100644 index 000000000000..bbfaf909392a --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp @@ -0,0 +1,55 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void f0(int i, int j, int k = 3); +void f0(int i, int j, int k); +void f0(int i, int j = 2, int k); +void f0(int i, int j, int k); +void f0(int i = 1, // expected-note{{previous definition}} + int j, int k); +void f0(int i, int j, int k); + +namespace N0 { + void f0(int, int, int); // expected-note{{candidate}} + + void test_f0_inner_scope() { + f0(); // expected-error{{no matching}} + } +} + +void test_f0_outer_scope() { + f0(); // okay +} + +void f0(int i = 1, // expected-error{{redefinition of default argument}} + int, int); + +template<typename T> void f1(T); // expected-note{{previous}} + +template<typename T> +void f1(T = T()); // expected-error{{cannot be added}} + + +namespace N1 { + // example from C++03 standard + // FIXME: make these "f2"s into "f"s, then fix our scoping issues + void f2(int, int); + void f2(int, int = 7); + void h() { + f2(3); // OK, calls f(3, 7) + void f(int = 1, int); // expected-error{{missing default argument}} + } + + void m() + { + void f(int, int); // expected-note{{candidate}} + f(4); // expected-error{{no matching}} + void f(int, int = 5); // expected-note{{previous definition}} + f(4); // okay + void f(int, int = 5); // expected-error{{redefinition of default argument}} + } + + void n() + { + f2(6); // okay + } +}
\ No newline at end of file diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p5.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p5.cpp new file mode 100644 index 000000000000..894c9b5a877a --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p5.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +float global_f; + +void f0(int *ip = &global_f); // expected-error{{incompatible}} + +// Example from C++03 standard +int a = 1; +int f(int); +int g(int x = f(a)); + +void h() { + a = 2; + { + int *a = 0; + g(); // FIXME: check that a is called with a value of 2 + } +} diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp new file mode 100644 index 000000000000..ef00e7b70534 --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp @@ -0,0 +1,32 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class C { + void f(int i = 3); // expected-note{{here}} + void g(int i, int j = 99); +}; + +void C::f(int i = 3) { } // expected-error{{redefinition of default argument}} + +void C::g(int i = 88, int j) { } + +void test_C(C c) { + c.f(); + c.g(); +} + +template<typename T> +struct X0 { + void f(int); + + struct Inner { + void g(int); + }; +}; + +// DR217 +template<typename T> +void X0<T>::f(int = 17) { } // expected-error{{cannot be added}} + +// DR217 + DR205 (reading tea leaves) +template<typename T> +void X0<T>::Inner::g(int = 17) { } // expected-error{{cannot be added}} diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp new file mode 100644 index 000000000000..9c1d3a91c9bd --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void h() +{ + int i; + extern void h2(int x = sizeof(i)); // expected-error {{default argument references local variable 'i' of enclosing function}} +} diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp new file mode 100644 index 000000000000..574237ee557d --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp @@ -0,0 +1,4 @@ +// RUN: clang-cc -fsyntax-only -verify %s +class A { + void f(A* p = this) { } // expected-error{{invalid use of 'this'}} +}; diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp new file mode 100644 index 000000000000..6f71978c4e46 --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp @@ -0,0 +1,3 @@ +// RUN: clang-cc -fsyntax-only -verify %s +void f(int) { } // expected-note {{previous definition is here}} +void f(const int) { } // expected-error {{redefinition of 'f'}}
\ No newline at end of file diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp new file mode 100644 index 000000000000..101d75fc0f48 --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp @@ -0,0 +1,26 @@ +// RUN: clang-cc -fsyntax-only -verify %t +class A { +public: + int& i; + + A(int& i) : i(i) { } + + static int s; +}; + +template<typename T> void ft(T& t) { + t.*&T::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}} +} + +void f() { + int b; + A a(b); + + int A::*ip = &A::s; // expected-error {{incompatible type initializing 'int *', expected 'int class A::*'}} + a.*&A::s = 10; // expected-error{{right hand operand to .* has non pointer-to-member type 'int *'}} + + a.*&A::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}} + ft(a); // expected-note{{in instantiation of function template specialization 'ft' requested here}} + + void A::*p = 0; // expected-error{{'p' declared as a member pointer to void}} +} diff --git a/test/CXX/expr/p3.cpp b/test/CXX/expr/p3.cpp new file mode 100644 index 000000000000..40fe052f6342 --- /dev/null +++ b/test/CXX/expr/p3.cpp @@ -0,0 +1,15 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +double operator +(double, double); // expected-error{{overloaded 'operator+' must have at least one parameter of class or enumeration type}} + +struct A +{ + operator int(); +}; + +int main() +{ + A a, b; + int i0 = a + 1; + int i1 = a + b; +} diff --git a/test/CXX/expr/p8.cpp b/test/CXX/expr/p8.cpp new file mode 100644 index 000000000000..4f02497486c8 --- /dev/null +++ b/test/CXX/expr/p8.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +int a0; +const volatile int a1; +int a2[16]; +int a3(); + +void f0(int); +void f1(int *); +void f2(int (*)()); + +int main() +{ + f0(a0); + f0(a1); + f1(a2); + f2(a3); +} diff --git a/test/CXX/expr/p9.cpp b/test/CXX/expr/p9.cpp new file mode 100644 index 000000000000..1eec3cf0b9f9 --- /dev/null +++ b/test/CXX/expr/p9.cpp @@ -0,0 +1,50 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// floating-point overloads + +__typeof__(0 + 0.0L) ld0; +long double &ldr = ld0; + +__typeof__(0 + 0.0) d0; +double &dr = d0; + +__typeof__(0 + 0.0f) f0; +float &fr = f0; + +// integral promotions + +signed char c0; +__typeof__(c0 + c0) c1; +int &cr = c1; + +unsigned char uc0; +__typeof__(uc0 + uc0) uc1; +int &ucr = uc1; + +short s0; +__typeof__(s0 + s0) s1; +int &sr = s1; + +unsigned short us0; +__typeof__(us0 + us0) us1; +int &usr = us1; + +// integral overloads + +__typeof__(0 + 0UL) ul0; +unsigned long &ulr = ul0; + +template<bool T> struct selector; +template<> struct selector<true> { typedef long type; }; +template<> struct selector<false> {typedef unsigned long type; }; +__typeof__(0U + 0L) ui_l0; +selector<(sizeof(long) > sizeof(unsigned int))>::type &ui_lr = ui_l0; + +__typeof__(0 + 0L) l0; +long &lr = l0; + +__typeof__(0 + 0U) u0; +unsigned &ur = u0; + +__typeof__(0 + 0) i0; +int &ir = i0; diff --git a/test/CXX/lex/lex.trigraph/p1.cpp b/test/CXX/lex/lex.trigraph/p1.cpp new file mode 100644 index 000000000000..2a9a34b87eed --- /dev/null +++ b/test/CXX/lex/lex.trigraph/p1.cpp @@ -0,0 +1,19 @@ +// RUN: clang-cc -fsyntax-only -trigraphs -Wtrigraphs -verify %s + +??=pragma // expected-warning {{trigraph converted to '#' character}} + +int a = '??/0'; // expected-warning {{trigraph converted to '\' character}} + +int b = 1 ??' 0; // expected-warning {{trigraph converted to '^' character}} + +int c ??(1]; // expected-warning {{trigraph converted to '[' character}} + +int d [1??); // expected-warning {{trigraph converted to ']' character}} + +int e = 1 ??! 0; // expected-warning {{trigraph converted to '|' character}} + +void f() ??<} // expected-warning {{trigraph converted to '{' character}} + +void g() {??> // expected-warning {{trigraph converted to '}' character}} + +int h = ??- 0; // expected-warning {{trigraph converted to '~' character}} diff --git a/test/CXX/lex/lex.trigraph/p2.cpp b/test/CXX/lex/lex.trigraph/p2.cpp new file mode 100644 index 000000000000..5be2d46b9189 --- /dev/null +++ b/test/CXX/lex/lex.trigraph/p2.cpp @@ -0,0 +1,3 @@ +// RUN: clang-cc -fsyntax-only -trigraphs -Wtrigraphs -verify %s + +??=define arraycheck(a,b) a??(b??) ??!??! b??(a??) // expected-warning {{trigraph converted to '#' character}} expected-warning {{trigraph converted to '[' character}} expected-warning {{trigraph converted to ']' character}} expected-warning {{trigraph converted to '|' character}} expected-warning {{trigraph converted to '|' character}} expected-warning {{trigraph converted to '[' character}} expected-warning {{trigraph converted to ']' character}} diff --git a/test/CXX/lex/lex.trigraph/p3.cpp b/test/CXX/lex/lex.trigraph/p3.cpp new file mode 100644 index 000000000000..f32af49994af --- /dev/null +++ b/test/CXX/lex/lex.trigraph/p3.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -trigraphs -Wtrigraphs -verify %s + +char a[] = +"?? ??\"??#??$??%??&??*??+??,??.??0??1??2??3??4??5??6" +"??7??8??9??:??;?????@??A??B??C??D??E??F??G??H??I??J" +"??K??L??M??N??O??P??Q??R??S??T??U??V??W??X??Y??Z??[" +"??\\??]??^??_??`??a??b??c??d??e??f??g??h??i??j??k??l" +"??m??n??o??p??q??r??s??t??u??v??w??x??y??z??{??|??}??~"; diff --git a/test/CXX/over/over.match/over.match.best/p1.cpp b/test/CXX/over/over.match/over.match.best/p1.cpp new file mode 100644 index 000000000000..df5198357d7b --- /dev/null +++ b/test/CXX/over/over.match/over.match.best/p1.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> int &f0(T*, int); +float &f0(void*, int); + +void test_f0(int* ip, void *vp) { + // One argument is better... + int &ir = f0(ip, 0); + + // Prefer non-templates to templates + float &fr = f0(vp, 0); +} + +// Partial ordering of function template specializations will be tested +// elsewhere +// FIXME: Initialization by user-defined conversion is tested elsewhere diff --git a/test/CXX/over/over.over/p1.cpp b/test/CXX/over/over.over/p1.cpp new file mode 100644 index 000000000000..e7f7d18c69e3 --- /dev/null +++ b/test/CXX/over/over.over/p1.cpp @@ -0,0 +1,94 @@ +// RUN: clang-cc -fsyntax-only %s + +template<typename T> T f0(T); +int f0(int); + +// -- an object or reference being initialized +struct S { + int (*f0)(int); + float (*f1)(float); +}; + +void test_init_f0() { + int (*f0a)(int) = f0; + int (*f0b)(int) = &f0; + int (*f0c)(int) = (f0); + float (*f0d)(float) = f0; + float (*f0e)(float) = &f0; + float (*f0f)(float) = (f0); + int (&f0g)(int) = f0; + int (&f0h)(int) = (f0); + float (&f0i)(float) = f0; + float (&f0j)(float) = (f0); + S s = { f0, f0 }; +} + +// -- the left side of an assignment (5.17), +void test_assign_f0() { + int (*f0a)(int) = 0; + float (*f0b)(float) = 0; + + f0a = f0; + f0a = &f0; + f0a = (f0); + f0b = f0; + f0b = &f0; + f0b = (f0); +} + +// -- a parameter of a function (5.2.2), +void eat_f0(int a(int), float (*b)(float), int (&c)(int), float (&d)(float)); + +void test_pass_f0() { + eat_f0(f0, f0, f0, f0); + eat_f0(&f0, &f0, (f0), (f0)); +} + +// -- a parameter of a user-defined operator (13.5), +struct X { }; +void operator+(X, int(int)); +void operator-(X, float(*)(float)); +void operator*(X, int (&)(int)); +void operator/(X, float (&)(float)); + +void test_operator_pass_f0(X x) { + x + f0; + x + &f0; + x - f0; + x - &f0; + x * f0; + x * (f0); + x / f0; + x / (f0); +} + +// -- the return value of a function, operator function, or conversion (6.6.3), +int (*test_return_f0_a())(int) { return f0; } +int (*test_return_f0_b())(int) { return &f0; } +int (*test_return_f0_c())(int) { return (f0); } +float (*test_return_f0_d())(float) { return f0; } +float (*test_return_f0_e())(float) { return &f0; } +float (*test_return_f0_f())(float) { return (f0); } + +// -- an explicit type conversion (5.2.3, 5.2.9, 5.4), or +void test_convert_f0() { + (void)((int (*)(int))f0); + (void)((int (*)(int))&f0); + (void)((int (*)(int))(f0)); + (void)((float (*)(float))f0); + (void)((float (*)(float))&f0); + (void)((float (*)(float))(f0)); +} + +// -- a non-type template-parameter(14.3.2). +template<int(int)> struct Y0 { }; +template<float(float)> struct Y1 { }; +template<int (&)(int)> struct Y2 { }; +template<float (&)(float)> struct Y3 { }; + +Y0<f0> y0; +Y0<&f0> y0a; +Y1<f0> y1; +Y1<&f0> y1a; +Y2<f0> y2; +Y3<f0> y3; diff --git a/test/CXX/over/over.over/p2.cpp b/test/CXX/over/over.over/p2.cpp new file mode 100644 index 000000000000..9ab026061893 --- /dev/null +++ b/test/CXX/over/over.over/p2.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> T f0(T, T); + +void test_f0() { + int (*f0a)(int, int) = f0; + int (*f0b)(int, int) = &f0; + int (*f0c)(int, float) = f0; // expected-error{{incompatible type}} + // FIXME: poor error message above! +} diff --git a/test/CXX/over/over.over/p4.cpp b/test/CXX/over/over.over/p4.cpp new file mode 100644 index 000000000000..a05dbaebb71d --- /dev/null +++ b/test/CXX/over/over.over/p4.cpp @@ -0,0 +1,23 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> T f0(T); +int f0(int); // expected-note{{candidate function}} + +void test_f0() { + int (*fp0)(int) = f0; + int (*fp1)(int) = &f0; + float (*fp2)(float) = &f0; +} + +namespace N { + int f0(int); // expected-note{{candidate function}} +} + +int f0(int); + +void test_f0_2() { + using namespace N; + int (*fp0)(int) = f0; // expected-error{{ambiguous}} \ + // expected-error{{initializing}} + float (*fp1)(float) = f0; +} diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp new file mode 100644 index 000000000000..afe6ab2b968e --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp @@ -0,0 +1,20 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct X0 { + template<typename U> struct Inner0 { + static const unsigned value = 0; + }; + + template<typename U> struct Inner0<U*> { + static const unsigned value = 1; + }; +}; + +template<typename T> template<typename U> +struct X0<T>::Inner0<const U*> { + static const unsigned value = 2; +}; + +// FIXME: Test instantiation of these partial specializations (once they are +// implemented). diff --git a/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp new file mode 100644 index 000000000000..b3b7635106c5 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<int I, int J, class T> class X { + static const int value = 0; +}; + +template<int I, int J> class X<I, J, int> { + static const int value = 1; +}; + +template<int I> class X<I, I, int> { + static const int value = 2; +}; + +int array0[X<0, 0, float>::value == 0? 1 : -1]; +int array1[X<0, 1, int>::value == 1? 1 : -1]; +int array2[X<0, 0, int>::value == 2? 1 : -1]; diff --git a/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1-neg.cpp b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1-neg.cpp new file mode 100644 index 000000000000..47cf8379c319 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1-neg.cpp @@ -0,0 +1,25 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T, int N> +struct A; + +template<typename T> // expected-note{{previous template declaration}} +struct A<T*, 2> { + void f0(); + void f1(); + void f2(); +}; + +template<> +struct A<int, 1> { + void g0(); +}; + +// FIXME: We should probably give more precise diagnostics here, but the +// diagnostics we give aren't terrible. +// FIXME: why not point to the first parameter that's "too many"? +template<typename T, int N> // expected-error{{too many template parameters}} +void A<T*, 2>::f0() { } + +template<typename T, int N> +void A<T, N>::f1() { } // expected-error{{out-of-line definition}} diff --git a/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp new file mode 100644 index 000000000000..b63c56c40fe8 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp @@ -0,0 +1,26 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T, int N> +struct A; + +template<typename T> +struct A<T*, 2> { + A(T); + ~A(); + + void f(T*); + + operator T*(); + + static T value; +}; + +template<class X> void A<X*, 2>::f(X*) { } + +template<class X> X A<X*, 2>::value; + +template<class X> A<X*, 2>::A(X) { value = 0; } + +template<class X> A<X*, 2>::~A() { } + +template<class X> A<X*, 2>::operator X*() { return 0; } diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp new file mode 100644 index 000000000000..bc4bb5da4011 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp @@ -0,0 +1,27 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T, typename U> +struct X0 { + struct Inner; +}; + +template<typename T, typename U> +struct X0<T, U>::Inner { + T x; + U y; + + void f() { x = y; } // expected-error{{incompatible}} +}; + + +void test(int i, float f) { + X0<int, float>::Inner inner; + inner.x = 5; + inner.y = 3.4; + inner.f(); + + X0<int*, float *>::Inner inner2; + inner2.x = &i; + inner2.y = &f; + inner2.f(); // expected-note{{instantiation}} +} diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp new file mode 100644 index 000000000000..fd3fb0bc7a7d --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp @@ -0,0 +1,28 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> struct X1 { }; + +template<typename T> +struct X0 { + typedef int size_type; + typedef T value_type; + + size_type f0() const; + value_type *f1(); + X1<value_type*> f2(); +}; + +template<typename T> +typename X0<T>::size_type X0<T>::f0() const { + return 0; +} + +template<typename U> +typename X0<U>::value_type *X0<U>::f1() { + return 0; +}; + +template<typename U> +X1<typename X0<U>::value_type*> X0<U>::f2() { + return 0; +}; diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp new file mode 100644 index 000000000000..725b61c27162 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp @@ -0,0 +1,68 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T, typename U> // expected-note{{previous template}} +class X0 { +public: + typedef int size_type; + + X0(int); + ~X0(); + + void f0(const T&, const U&); + + T& operator[](int i) const; + + void f1(size_type) const; + void f2(size_type) const; + void f3(size_type) const; + void f4() ; + + operator T*() const; + + T value; +}; + +template<typename T, typename U> +void X0<T, U>::f0(const T&, const U&) { // expected-note{{previous definition}} +} + +template<class X, class Y> +X& X0<X, Y>::operator[](int i) const { + (void)i; + return value; +} + +template<class X, class Y> +void X0<X, Y>::f1(int) const { } + +template<class X, class Y> +void X0<X, Y>::f2(size_type) const { } + +template<class X, class Y, class Z> // expected-error{{too many template parameters}} +void X0<X, Y>::f3(size_type) const { +} + +template<class X, class Y> +void X0<Y, X>::f4() { } // expected-error{{does not refer}} + +// FIXME: error message should probably say, "redefinition of 'X0<T, U>::f0'" +// rather than just "redefinition of 'f0'" +template<typename T, typename U> +void X0<T, U>::f0(const T&, const U&) { // expected-error{{redefinition}} +} + +// Test out-of-line constructors, destructors +template<typename T, typename U> +X0<T, U>::X0(int x) : value(x) { } + +template<typename T, typename U> +X0<T, U>::~X0() { } + +// Test out-of-line conversion functions. +template<typename T, typename U> +X0<T, U>::operator T*() const { + return &value; +} + +namespace N { template <class X> class A {void a();}; } +namespace N { template <class X> void A<X>::a() {} } diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp new file mode 100644 index 000000000000..a09d0efa297f --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp @@ -0,0 +1,17 @@ +// RUN: clang-cc -fsyntax-only -verify %s +// Test instantiation of member functions of class templates defined out-of-line +template<typename T, typename U> +struct X0 { + void f(T *t, const U &u); + void f(T *); +}; + +template<typename T, typename U> +void X0<T, U>::f(T *t, const U &u) { + *t = u; // expected-error{{not assignable}} +} + +void test_f(X0<float, int> xfi, X0<void, int> xvi, float *fp, void *vp, int i) { + xfi.f(fp, i); + xvi.f(vp, i); // expected-note{{instantiation}} +} diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp new file mode 100644 index 000000000000..602fd374c2ab --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp @@ -0,0 +1,17 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +extern "C" void * malloc(int); + +template <typename T> struct A { + void *malloc(int); +}; + +template <typename T> +inline void *A<T>::malloc(int) +{ + return 0; +} + +void f() { + malloc(10); +} diff --git a/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp b/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp new file mode 100644 index 000000000000..2ddb8eac6c0a --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp @@ -0,0 +1,28 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// Test instantiation of static data members declared out-of-line. + +template<typename T> +struct X { + static T value; +}; + +template<typename T> + T X<T>::value = 17; // expected-error{{initialize}} + +struct InitOkay { + InitOkay(int) { } +}; + +struct CannotInit { }; + +int &returnInt() { return X<int>::value; } +float &returnFloat() { return X<float>::value; } + +InitOkay &returnInitOkay() { return X<InitOkay>::value; } + +unsigned long sizeOkay() { return sizeof(X<CannotInit>::value); } + +CannotInit &returnError() { + return X<CannotInit>::value; // expected-note{{instantiation}} +} diff --git a/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp b/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp new file mode 100644 index 000000000000..949a8b0a72c7 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp @@ -0,0 +1,26 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct X0 { + static T value; +}; + +template<typename T> +T X0<T>::value = 0; // expected-error{{initialize}} + +struct X1 { + X1(int); +}; + +struct X2 { }; + +int& get_int() { return X0<int>::value; } +X1& get_X1() { return X0<X1>::value; } + +double*& get_double_ptr() { return X0<int*>::value; } // expected-error{{initialized}} + +X2& get_X2() { + return X0<X2>::value; // expected-note{{instantiation}} +} + +template<typename T> T x; // expected-error{{variable 'x' declared as a template}} diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p4.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p4.cpp new file mode 100644 index 000000000000..fe42ba41d81e --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p4.cpp @@ -0,0 +1,23 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<class T> struct A { A(); }; +template<class T> int &f(T); +template<class T> float &f(T*); +template<class T> double &f(const T*); + +template<class T> void g(T); // expected-note{{candidate}} +template<class T> void g(T&); // expected-note{{candidate}} + +template<class T> int &h(const T&); +template<class T> float &h(A<T>&); + +void m() { + const int *p; + double &dr1 = f(p); + float x; + g(x); // expected-error{{ambiguous}} + A<int> z; + float &fr1 = h(z); + const A<int> z2; + int &ir1 = h(z2); +} diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p5.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p5.cpp new file mode 100644 index 000000000000..27e4426b9082 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p5.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<class T> int &f(T); +template<class T> float &f(T*, int=1); + +template<class T> int &g(T); +template<class T> float &g(T*, ...); + +int main() { + int* ip; + float &fr1 = f(ip); + float &fr2 = g(ip); +} diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp index b482955818cb..399dcc4bed76 100644 --- a/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp +++ b/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp @@ -17,11 +17,11 @@ template<typename T> struct MetaFun; template<typename T> - typename MetaFun<T*>::type f0(const T&) { } // expected-note{{previous}} + typename MetaFun<T*>::type f0(const T&) { while (1) {} } // expected-note{{previous}} template<class U> - typename MetaFun<U*>::type f0(const U&) { } // expected-error{{redefinition}} + typename MetaFun<U*>::type f0(const U&) { while (1) {} } // expected-error{{redefinition}} // FIXME: We need canonicalization of expressions for this to work // template<int> struct A { }; // template<int I> void f0(A<I>) { } // Xpected-note{{previous}} -// template<int J> void f0(A<J>) { } // Xpected-error{{redefinition}}
\ No newline at end of file +// template<int J> void f0(A<J>) { } // Xpected-error{{redefinition}} diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp new file mode 100644 index 000000000000..2571e45c5cde --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<int N, int M> +struct A0 { + void g0(); +}; + +template<int X, int Y> void f0(A0<X, Y>) { } // expected-note{{previous}} +template<int N, int M> void f0(A0<M, N>) { } +template<int V1, int V2> void f0(A0<V1, V2>) { } // expected-error{{redefinition}} + +template<int X, int Y> void f1(A0<0, (X + Y)>) { } // expected-note{{previous}} +template<int X, int Y> void f1(A0<0, (X - Y)>) { } +template<int A, int B> void f1(A0<0, (A + B)>) { } // expected-error{{redefinition}} + +template<int X, int Y> void A0<X, Y>::g0() { } diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp new file mode 100644 index 000000000000..fc392da00acf --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp @@ -0,0 +1,56 @@ +// RUN: clang-cc -emit-llvm-only %s + +template <typename T> struct Num { + T value_; + +public: + Num(T value) : value_(value) {} + T get() const { return value_; } + + template <typename U> struct Rep { + U count_; + Rep(U count) : count_(count) {} + + friend Num operator*(const Num &a, const Rep &n) { + Num x = 0; + for (U count = n.count_; count; --count) + x += a; + return x; + } + }; + + friend Num operator+(const Num &a, const Num &b) { + return a.value_ + b.value_; + } + + Num& operator+=(const Num& b) { + value_ += b.value_; + return *this; + } + + class Representation {}; + friend class Representation; +}; + +class A { + template <typename T> friend bool iszero(const A &a) throw(); +}; + +template <class T> class B_iterator; +template <class T> class B { + friend class B_iterator<T>; +}; + +int calc1() { + Num<int> left = -1; + Num<int> right = 1; + Num<int> result = left + right; + return result.get(); +} + +int calc2() { + Num<int> x = 3; + Num<int>::Rep<char> n = (char) 10; + Num<int> result = x * n; + return result.get(); +} diff --git a/test/CXX/temp/temp.decls/temp.friend/p3.cpp b/test/CXX/temp/temp.decls/temp.friend/p3.cpp new file mode 100644 index 000000000000..4615bebe711f --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.friend/p3.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template <class T> class A { + typedef int Member; +}; + +class B { + template <class T> friend class A; + template <class T> friend class Undeclared; + + // FIXME: Diagnostic below could be (and was) better. + template <class T> friend typename A<T>::Member; // expected-error {{classes or functions}} +}; diff --git a/test/CXX/temp/temp.decls/temp.friend/p5.cpp b/test/CXX/temp/temp.decls/temp.friend/p5.cpp new file mode 100644 index 000000000000..f1142a4129b2 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.friend/p5.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template <class T> class A { + class Member { + }; +}; + +class B { + template <class T> friend class A<T>::Member; +}; + diff --git a/test/CXX/temp/temp.decls/temp.mem/p1.cpp b/test/CXX/temp/temp.decls/temp.mem/p1.cpp new file mode 100644 index 000000000000..80b18467a364 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.mem/p1.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template <class T> struct A { + static T cond; + + template <class U> struct B { + static T twice(U value) { + return (cond ? value + value : value); + } + }; +}; + +int foo() { + A<bool>::cond = true; + return A<bool>::B<int>::twice(4); +} diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp index f4970b89f693..01030b2a8a20 100644 --- a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp +++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp @@ -8,4 +8,4 @@ void g() { f<int>("aa",3.0); // Y is deduced to be char*, and // Z is deduced to be double f("aa",3.0); // expected-error{{no matching}} -}
\ No newline at end of file +} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp index c014c663598c..dbe2ff3e18fb 100644 --- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp @@ -1,4 +1,4 @@ -// RUN: clang-cc -fsyntax-only %s +// RUN: clang-cc -fsyntax-only -verify %s template<typename T> struct A { }; @@ -57,4 +57,32 @@ void test_f3(int ***ip, volatile int ***vip) { A<volatile int> a1 = f3(vip); } -// FIXME: the next bullet requires a lot of effort. +// - If P is a class, and P has the form template-id, then A can be a +// derived class of the deduced A. Likewise, if P is a pointer to a class +// of the form template-id, A can be a pointer to a derived class pointed +// to by the deduced A. +template<typename T, int I> struct C { }; + +struct D : public C<int, 1> { }; +struct E : public D { }; +struct F : A<float> { }; +struct G : A<float>, C<int, 1> { }; + +template<typename T, int I> + C<T, I> *f4a(const C<T, I>&); +template<typename T, int I> + C<T, I> *f4b(C<T, I>); +template<typename T, int I> + C<T, I> *f4c(C<T, I>*); +int *f4c(...); + +void test_f4(D d, E e, F f, G g) { + C<int, 1> *ci1a = f4a(d); + C<int, 1> *ci2a = f4a(e); + C<int, 1> *ci1b = f4b(d); + C<int, 1> *ci2b = f4b(e); + C<int, 1> *ci1c = f4c(&d); + C<int, 1> *ci2c = f4c(&e); + C<int, 1> *ci3c = f4c(&g); + int *ip1 = f4c(&f); +} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp new file mode 100644 index 000000000000..7d175781c2d9 --- /dev/null +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp @@ -0,0 +1,36 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// FIXME: [temp.deduct.conv]p2 bullets 1 and 2 can't actually happen without +// references? +// struct ConvertibleToArray { +// // template<typename T, unsigned N> +// // operator T(()[]) const; + +// private: +// typedef int array[17]; + +// operator array() const; +// }; + +// void test_array(ConvertibleToArray cta) { +// int *ip = cta; +// ip = cta; +// const float *cfp = cta; +// } + +// bullet 2 +// struct ConvertibleToFunction { +// template<typename T, typename A1, typename A2> +// operator T(A1, A2) const () { }; +// }; + +// bullet 3 +struct ConvertibleToCVQuals { + template<typename T> + operator T* const() const; +}; + +void test_cvqual_conv(ConvertibleToCVQuals ctcv) { + int *ip = ctcv; + const int *icp = ctcv; +} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp new file mode 100644 index 000000000000..95bd7fe12159 --- /dev/null +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp @@ -0,0 +1,30 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct AnyPtr { + template<typename T> + operator T*() const; +}; + +// If A is a cv-qualified type, the top level cv-qualifiers of A's type +// are ignored for type deduction. +void test_cvquals(AnyPtr ap) { + int* const ip = ap; + const float * const volatile fp = ap; +} + +// If A is a reference type, the type referred to by A is used for +// type deduction. +void test_ref_arg(AnyPtr ap) { + const int* const &ip = ap; + double * const &dp = ap; +} + +struct AnyRef { + template<typename T> + operator T&() const; +}; + +void test_ref_param(AnyRef ar) { + int &ir = ar; + const float &fr = ar; + int i = ar; +} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp new file mode 100644 index 000000000000..50d31fb2f851 --- /dev/null +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp @@ -0,0 +1,44 @@ +// RUN: clang-cc -fsyntax-only %s + +struct AnyT { + template<typename T> + operator T(); +}; + +void test_cvqual_ref(AnyT any) { + const int &cir = any; +} + +struct AnyThreeLevelPtr { + template<typename T> + operator T***() const + { + T x = 0; + // FIXME: looks like we get this wrong, too! + // x = 0; // will fail if T is deduced to a const type + // (EDG and GCC get this wrong) + return 0; + } +}; + +struct X { }; + +void test_deduce_with_qual(AnyThreeLevelPtr a3) { + int * const * const * const ip = a3; +} + +struct AnyPtrMem { + template<typename Class, typename T> + operator T Class::*() const + { + T x = 0; + // FIXME: looks like we get this wrong, too! + // x = 0; // will fail if T is deduced to a const type. + // (EDG and GCC get this wrong) + return 0; + } +}; + +void test_deduce_ptrmem_with_qual(AnyPtrMem apm) { + const float X::* pm = apm; +} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp new file mode 100644 index 000000000000..86a34500ad41 --- /dev/null +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only %s + +template<typename T> + T f0(T, int); + +void test_f0() { + int (*f0a)(int, int) = f0; + int (*f0b)(int, int) = &f0; + float (*f0c)(float, int) = &f0; +} + +template<typename T> T f1(T, int); +template<typename T> T f1(T); + +void test_f1() { + float (*f1a)(float, int) = f1; + float (*f1b)(float, int) = &f1; + float (*f1c)(float) = f1; + float (*f1d)(float) = (f1); + float (*f1e)(float) = &f1; + float (*f1f)(float) = (&f1); +} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp new file mode 100644 index 000000000000..072789c7d579 --- /dev/null +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template <class T> T* f(int); // #1 +template <class T, class U> T& f(U); // #2 + +void g() { + int *ip = f<int>(1); // calls #1 +} + +template<typename T> +struct identity { + typedef T type; +}; + +template <class T> + T* f2(int, typename identity<T>::type = 0); // expected-note{{candidate}} +template <class T, class U> + T& f2(U, typename identity<T>::type = 0); // expected-note{{candidate}} + +void g2() { + f2<int>(1); // expected-error{{ambiguous}} +} diff --git a/test/CXX/temp/temp.param/p1.cpp b/test/CXX/temp/temp.param/p1.cpp index 488c3a07429a..a6638b4f60f2 100644 --- a/test/CXX/temp/temp.param/p1.cpp +++ b/test/CXX/temp/temp.param/p1.cpp @@ -1 +1,4 @@ +// Suppress 'no run line' failure. +// RUN: true + // Paragraph 1 is descriptive, and therefore requires no tests. diff --git a/test/CXX/temp/temp.res/temp.dep/p3.cpp b/test/CXX/temp/temp.res/temp.dep/p3.cpp new file mode 100644 index 000000000000..d47f0d683514 --- /dev/null +++ b/test/CXX/temp/temp.res/temp.dep/p3.cpp @@ -0,0 +1,43 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct A0 { + struct K { }; +}; + +template <typename T> struct B0: A0 { + static void f() { + K k; + } +}; + +namespace E1 { + typedef double A; + + template<class T> class B { + typedef int A; + }; + + template<class T> + struct X : B<T> { + A* blarg(double *dp) { + return dp; + } + }; +} + +namespace E2 { + struct A { + struct B; + int *a; + int Y; + }; + + int a; + template<class T> struct Y : T { + struct B { /* ... */ }; + B b; + void f(int i) { a = i; } + Y* p; + }; + + Y<A> ya; +} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp new file mode 100644 index 000000000000..239b8aeb04e4 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp @@ -0,0 +1,99 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// This test creates cases where implicit instantiations of various entities +// would cause a diagnostic, but provides expliict specializations for those +// entities that avoid the diagnostic. The intent is to verify that +// implicit instantiations do not occur (because the explicit specialization +// is used instead). +struct NonDefaultConstructible { + NonDefaultConstructible(int); +}; + + +// C++ [temp.expl.spec]p1: +// An explicit specialization of any of the following: + +// -- function template +template<typename T> void f0(T) { + T t; +} + +template<> void f0(NonDefaultConstructible) { } + +void test_f0(NonDefaultConstructible NDC) { + f0(NDC); +} + +// -- class template +template<typename T> +struct X0 { + static T member; + + void f1(T t) { + t = 17; + } + + struct Inner : public T { }; + + template<typename U> + struct InnerTemplate : public T { }; + + template<typename U> + void ft1(T t, U u); +}; + +template<typename T> +template<typename U> +void X0<T>::ft1(T t, U u) { + t = u; +} + +template<typename T> T X0<T>::member; + +template<> struct X0<void> { }; +X0<void> test_X0; + + +// -- member function of a class template +template<> void X0<void*>::f1(void *) { } + +void test_spec(X0<void*> xvp, void *vp) { + xvp.f1(vp); +} + +// -- static data member of a class template +template<> +NonDefaultConstructible X0<NonDefaultConstructible>::member = 17; + +NonDefaultConstructible &get_static_member() { + return X0<NonDefaultConstructible>::member; +} + +// -- member class of a class template +template<> +struct X0<void*>::Inner { }; + +X0<void*>::Inner inner0; + +// -- member class template of a class template +template<> +template<> +struct X0<void*>::InnerTemplate<int> { }; + +X0<void*>::InnerTemplate<int> inner_template0; + +// -- member function template of a class template +template<> +template<> +void X0<void*>::ft1(void*, const void*) { } + +void test_func_template(X0<void *> xvp, void *vp, const void *cvp) { + xvp.ft1(vp, cvp); +} + +// example from the standard: +template<class T> class stream; +template<> class stream<char> { /* ... */ }; +template<class T> class Array { /* ... */ }; +template<class T> void sort(Array<T>& v) { /* ... */ } +template<> void sort<char*>(Array<char*>&) ; diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp new file mode 100644 index 000000000000..61f1710a6b9e --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<class T> class X; +template<> class X<int>; // expected-note{{forward}} +X<int>* p; + +X<int> x; // expected-error{{incomplete type}} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp new file mode 100644 index 000000000000..e794e67a5ef3 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<class T> class Array { /* ... */ }; +template<class T> void sort(Array<T>& v); + +// explicit specialization for sort(Array<int>&) +// with deduced template-argument of type int +template<> void sort(Array<int>&); diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp new file mode 100644 index 000000000000..63cf9f5e50d1 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp @@ -0,0 +1,6 @@ +// RUN: clang-cc -fsyntax-only %s + +template<typename T> void f(T); + +template<> void f(int) { } +void f(int) { } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp new file mode 100644 index 000000000000..a5d5b9e3c41e --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp @@ -0,0 +1,42 @@ +// RUN: clang-cc -emit-llvm -o - %s | FileCheck %s + +template<class T> void f(T) { /* ... */ } +template<class T> inline void g(T) { /* ... */ } + +// CHECK: define void @_Z1gIiEvT_ +template<> void g<>(int) { /* ... */ } + +template<class T> +struct X { + void f() { } + void g(); + void h(); +}; + +template<class T> +void X<T>::g() { +} + +template<class T> +inline void X<T>::h() { +} + +// CHECK: define void @_ZN1XIiE1fEv +template<> void X<int>::f() { } + +// CHECK: define void @_ZN1XIiE1hEv +template<> void X<int>::h() { } + +// CHECK: define linkonce_odr void @_Z1fIiEvT_ +template<> inline void f<>(int) { /* ... */ } + +// CHECK: define linkonce_odr void @_ZN1XIiE1gEv +template<> inline void X<int>::g() { } + +void test(X<int> xi) { + f(17); + g(17); + xi.f(); + xi.g(); + xi.h(); +} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp new file mode 100644 index 000000000000..840f566362ed --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct NonDefaultConstructible { + NonDefaultConstructible(const NonDefaultConstructible&); +}; + +template<typename T, typename U> +struct X { + static T member; +}; + +template<typename T, typename U> +T X<T, U>::member; // expected-error{{no matching constructor}} + +// Okay; this is a declaration, not a definition. +template<> +NonDefaultConstructible X<NonDefaultConstructible, long>::member; + +NonDefaultConstructible &test(bool b) { + return b? X<NonDefaultConstructible, int>::member // expected-note{{instantiation}} + : X<NonDefaultConstructible, long>::member; +} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp new file mode 100644 index 000000000000..ce40afd40225 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp @@ -0,0 +1,26 @@ +// RUN: clang-cc -fsyntax-only %s +template<class T> struct A { + void f(T); + template<class X1> void g1(T, X1); + template<class X2> void g2(T, X2); + void h(T) { } +}; + +// specialization +template<> void A<int>::f(int); + +// out of class member template definition +template<class T> template<class X1> void A<T>::g1(T, X1) { } + +// member template specialization +template<> template<class X1> void A<int>::g1(int, X1); + +// member template specialization +template<> template<> + void A<int>::g1(int, char); // X1 deduced as char + +template<> template<> + void A<int>::g2<char>(int, char); // X2 specified as char + // member specialization even if defined in class definition + +template<> void A<int>::h(int) { } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp new file mode 100644 index 000000000000..883cb71d5686 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<class T1> +class A { + template<class T2> class B { + void mf(); + }; +}; + +template<> template<> class A<int>::B<double>; +template<> template<> void A<char>::B<char>::mf(); + +template<> void A<char>::B<int>::mf(); // expected-error{{requires 'template<>'}} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp new file mode 100644 index 000000000000..a5877d281d74 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp @@ -0,0 +1,20 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<class T1> class A { + template<class T2> class B { + template<class T3> void mf1(T3); + void mf2(); + }; +}; + +template<> template<class X> +class A<long>::B { }; + +template<> template<> template<class T> + void A<int>::B<double>::mf1(T t) { } + +template<> template<> template<class T> +void A<long>::B<double>::mf1(T t) { } // expected-error{{does not match}} + +// FIXME: This diagnostic could probably be better. +template<class Y> template<> + void A<Y>::B<double>::mf2() { } // expected-error{{does not refer}} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp new file mode 100644 index 000000000000..1f38e5a2c17d --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp @@ -0,0 +1,30 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct X { + template<typename U> struct Inner { }; + + template<typename U> void f(T, U) { } +}; + +template<> template<typename U> +struct X<int>::Inner { + U member; +}; + +template<> template<typename U> +void X<int>::f(int x, U y) { + x = y; // expected-error{{incompatible type}} +} + +void test(X<int> xi, X<long> xl, float *fp) { + X<int>::Inner<float*> xii; + xii.member = fp; + xi.f(17, 25); + xi.f(17, 3.14159); + xi.f(17, fp); // expected-note{{instantiation}} + X<long>::Inner<float*> xli; + + xli.member = fp; // expected-error{{no member}} + xl.f(17, fp); // okay +} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp new file mode 100644 index 000000000000..64856605a0a7 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp @@ -0,0 +1,239 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// This test creates cases where implicit instantiations of various entities +// would cause a diagnostic, but provides expliict specializations for those +// entities that avoid the diagnostic. The specializations are alternately +// declarations and definitions, and the intent of this test is to verify +// that we allow specializations only in the appropriate namespaces (and +// nowhere else). +struct NonDefaultConstructible { + NonDefaultConstructible(int); +}; + + +// C++ [temp.expl.spec]p1: +// An explicit specialization of any of the following: + +// -- function template +namespace N0 { + template<typename T> void f0(T) { // expected-note{{here}} + T t; + } + + template<> void f0(NonDefaultConstructible) { } + + void test_f0(NonDefaultConstructible NDC) { + f0(NDC); + } + + template<> void f0(int); + template<> void f0(long); +} + +template<> void N0::f0(int) { } // okay + +namespace N1 { + template<> void N0::f0(long) { } // expected-error{{not in a namespace enclosing}} +} + +template<> void N0::f0(double) { } // expected-error{{originally be declared}} + +struct X1 { + template<typename T> void f(T); + + template<> void f(int); // expected-error{{in class scope}} +}; + +// -- class template +namespace N0 { + +template<typename T> +struct X0 { // expected-note 2{{here}} + static T member; // expected-note{{here}} + + void f1(T t) { // expected-note{{explicitly specialized declaration is here}} + t = 17; + } + + struct Inner : public T { }; // expected-note 3{{here}} + + template<typename U> + struct InnerTemplate : public T { }; // expected-note 2{{explicitly specialized}} \ + // expected-error{{base specifier}} + + template<typename U> + void ft1(T t, U u); // expected-note{{explicitly specialized}} +}; + +} + +template<typename T> +template<typename U> +void N0::X0<T>::ft1(T t, U u) { + t = u; +} + +template<typename T> T N0::X0<T>::member; + +template<> struct N0::X0<void> { }; // expected-error{{originally}} +N0::X0<void> test_X0; + +namespace N1 { + template<> struct N0::X0<const void> { }; // expected-error{{originally}} +} + +namespace N0 { + template<> struct X0<volatile void>; +} + +template<> struct N0::X0<volatile void> { + void f1(void *); +}; + +// -- member function of a class template +template<> void N0::X0<void*>::f1(void *) { } // expected-error{{member function specialization}} + +void test_spec(N0::X0<void*> xvp, void *vp) { + xvp.f1(vp); +} + +namespace N0 { + template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}} + + template<> void X0<const volatile void*>::f1(const volatile void*); +} + +void test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) { + x0.f1(cvp); // okay: we've explicitly specialized +} + +// -- static data member of a class template +namespace N0 { + // This actually tests p15; the following is a declaration, not a definition. + template<> + NonDefaultConstructible X0<NonDefaultConstructible>::member; + + template<> long X0<long>::member = 17; + + template<> float X0<float>::member; + + template<> double X0<double>::member; +} + +NonDefaultConstructible &get_static_member() { + return N0::X0<NonDefaultConstructible>::member; +} + +template<> int N0::X0<int>::member; // expected-error{{originally}} + +template<> float N0::X0<float>::member = 3.14f; + +namespace N1 { + template<> double N0::X0<double>::member = 3.14; // expected-error{{not in a namespace enclosing}} +} + +// -- member class of a class template +namespace N0 { + + template<> + struct X0<void*>::Inner { }; + + template<> + struct X0<int>::Inner { }; + + template<> + struct X0<unsigned>::Inner; + + template<> + struct X0<float>::Inner; + + template<> + struct X0<double>::Inner; // expected-note{{forward declaration}} +} + +template<> +struct N0::X0<long>::Inner { }; // expected-error{{originally}} + +template<> +struct N0::X0<float>::Inner { }; + +namespace N1 { + template<> + struct N0::X0<unsigned>::Inner { }; // expected-error{{member class specialization}} + + template<> + struct N0::X0<unsigned long>::Inner { }; // expected-error{{member class specialization}} +}; + +N0::X0<void*>::Inner inner0; +N0::X0<int>::Inner inner1; +N0::X0<long>::Inner inner2; +N0::X0<float>::Inner inner3; +N0::X0<double>::Inner inner4; // expected-error{{incomplete}} + +// -- member class template of a class template +namespace N0 { + template<> + template<> + struct X0<void*>::InnerTemplate<int> { }; + + template<> template<> + struct X0<int>::InnerTemplate<int>; // expected-note{{forward declaration}} + + template<> template<> + struct X0<int>::InnerTemplate<long>; + + template<> template<> + struct X0<int>::InnerTemplate<double>; +} + +template<> template<> +struct N0::X0<int>::InnerTemplate<long> { }; // okay + +template<> template<> +struct N0::X0<int>::InnerTemplate<float> { }; // expected-error{{class template specialization}} + +namespace N1 { + template<> template<> + struct N0::X0<int>::InnerTemplate<double> { }; // expected-error{{enclosing}} +} + +N0::X0<void*>::InnerTemplate<int> inner_template0; +N0::X0<int>::InnerTemplate<int> inner_template1; // expected-error{{incomplete}} +N0::X0<int>::InnerTemplate<long> inner_template2; +N0::X0<int>::InnerTemplate<unsigned long> inner_template3; // expected-note{{instantiation}} + +// -- member function template of a class template +namespace N0 { + template<> + template<> + void X0<void*>::ft1(void*, const void*) { } + + template<> template<> + void X0<void*>::ft1(void *, int); + + template<> template<> + void X0<void*>::ft1(void *, unsigned); + + template<> template<> + void X0<void*>::ft1(void *, long); +} + +template<> template<> +void N0::X0<void*>::ft1(void *, unsigned) { } // okay + +template<> template<> +void N0::X0<void*>::ft1(void *, float) { } // expected-error{{function template specialization}} + +namespace N1 { + template<> template<> + void N0::X0<void*>::ft1(void *, long) { } // expected-error{{enclosing}} +} + + +void test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp, + int i, unsigned u) { + xvp.ft1(vp, cvp); + xvp.ft1(vp, i); + xvp.ft1(vp, u); +} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp new file mode 100644 index 000000000000..d270b8167a16 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<typename T> +void f(T); + +template<typename T> +struct A { }; + +struct X { + template<> friend void f<int>(int); // expected-error{{in class scope}} + template<> friend class A<int>; // expected-error{{cannot be a friend}} + + friend void f<float>(float); // okay + friend class A<float>; // okay +}; diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp new file mode 100644 index 000000000000..9dae3eb5190b --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp @@ -0,0 +1,30 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct X { + void mf1(T); + template<typename U> void mf2(T, U); // expected-note{{previous}} +}; + +template<> +void X<int>::mf1(int i = 17) // expected-error{{default}} +{ +} + +template<> template<> +void X<int>::mf2(int, int = 17) // expected-error{{default}} +{ } + +template<> template<typename U> +void X<int>::mf2(int, U = U()) // expected-error{{default}} +{ +} + +template<> +struct X<float> { + void mf1(float); +}; + +void X<float>::mf1(float = 3.14f) // okay +{ +} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp new file mode 100644 index 000000000000..2bd1400faefb --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +namespace N { + template<class T> class X; +} + +// FIXME: this diagnostic is terrible (PR3844). +template<> class X<int> { /* ... */ }; // expected-error {{unqualified-id}} + +namespace N { + +template<> class X<char*> { /* ... */ }; // OK: X is a template + +}
\ No newline at end of file diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp new file mode 100644 index 000000000000..8d91068f9b99 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp @@ -0,0 +1,59 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct IntHolder { // expected-note{{here}} + IntHolder(int); +}; + +template<typename T, typename U> +struct X { // expected-note{{here}} + void f() { + T t; // expected-error{{no matching}} + } + + void g() { } + + struct Inner { + T value; // expected-note {{member is declared here}} + }; + + static T value; +}; + +template<typename T, typename U> +T X<T, U>::value; // expected-error{{no matching constructor}} + +IntHolder &test_X_IntHolderInt(X<IntHolder, int> xih) { + xih.g(); // okay + xih.f(); // expected-note{{instantiation}} + + // FIXME: diagnostic here has incorrect reason (PR5154) + X<IntHolder, int>::Inner inner; // expected-error{{implicit default}} + + return X<IntHolder, int>::value; // expected-note{{instantiation}} +} + +// Explicitly specialize the members of X<IntHolder, long> to not cause +// problems with instantiation. +template<> +void X<IntHolder, long>::f() { } + +template<> +struct X<IntHolder, long>::Inner { + Inner() : value(17) { } + IntHolder value; +}; + +template<> +IntHolder X<IntHolder, long>::value = 17; + +IntHolder &test_X_IntHolderInt(X<IntHolder, long> xih) { + xih.g(); // okay + xih.f(); // okay, uses specialization + + X<IntHolder, long>::Inner inner; // okay, uses specialization + + return X<IntHolder, long>::value; // okay, uses specialization +} + +template<> +X<IntHolder, long>::X() { } // expected-error{{instantiated member}} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp new file mode 100644 index 000000000000..58682c786f95 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp @@ -0,0 +1,61 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct IntHolder { + IntHolder(int); +}; + +template<typename T, typename U> +struct X { + void f() { + T t; + } + + void g() { } + + struct Inner { + T value; + }; + + static T value; +}; + +template<typename T, typename U> +T X<T, U>::value; + +// Explicitly specialize the members of X<IntHolder, long> to not cause +// problems with instantiation, but only provide declarations (not definitions). +template<> +void X<IntHolder, long>::f(); + +template<> +struct X<IntHolder, long>::Inner; // expected-note{{forward declaration}} + +template<> +IntHolder X<IntHolder, long>::value; + +IntHolder &test_X_IntHolderInt(X<IntHolder, long> xih) { + xih.g(); // okay + xih.f(); // okay, uses specialization + + X<IntHolder, long>::Inner inner; // expected-error {{incomplete}} + + return X<IntHolder, long>::value; // okay, uses specialization +} + + +template<class T> struct A { + void f(T) { /* ... */ } +}; + +template<> struct A<int> { + void f(int); +}; + +void h() { + A<int> a; + a.f(16); // A<int>::f must be defined somewhere +} + +// explicit specialization syntax not used for a member of +// explicitly specialized class template specialization +void A<int>::f(int) { /* ... */ } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp new file mode 100644 index 000000000000..e92d3f0a8883 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp @@ -0,0 +1,56 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct X0 { + void f(); + + template<typename U> + void g(U); + + struct Nested { + }; + + static T member; +}; + +int &use_X0_int(X0<int> x0i, // expected-note{{implicit instantiation first required here}} + int i) { + x0i.f(); // expected-note{{implicit instantiation first required here}} + x0i.g(i); // expected-note{{implicit instantiation first required here}} + X0<int>::Nested nested; // expected-note{{implicit instantiation first required here}} + return X0<int>::member; // expected-note{{implicit instantiation first required here}} +} + +template<> +void X0<int>::f() { // expected-error{{after instantiation}} +} + +template<> template<> +void X0<int>::g(int) { // expected-error{{after instantiation}} +} + +template<> +struct X0<int>::Nested { }; // expected-error{{after instantiation}} + +template<> +int X0<int>::member = 17; // expected-error{{after instantiation}} + +template<> +struct X0<int> { }; // expected-error{{after instantiation}} + +// Example from the standard +template<class T> class Array { /* ... */ }; + +template<class T> void sort(Array<T>& v) { /* ... */ } + +struct String {}; + +void f(Array<String>& v) { + + sort(v); // expected-note{{required}} + // use primary template + // sort(Array<T>&), T is String +} + +template<> void sort<String>(Array<String>& v); // // expected-error{{after instantiation}} +template<> void sort<>(Array<char*>& v); // OK: sort<char*> not yet used diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp new file mode 100644 index 000000000000..49481d2e6d7a --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +namespace N { + template<class T> class X { /* ... */ }; + template<class T> class Y { /* ... */ }; + template<> class X<int> { /* ... */ }; + template<> class Y<double>; + + const unsigned NumElements = 17; +} + +template<> class N::Y<double> { + int array[NumElements]; +}; diff --git a/test/CodeCompletion/call.cpp b/test/CodeCompletion/call.cpp new file mode 100644 index 000000000000..90bf82bff307 --- /dev/null +++ b/test/CodeCompletion/call.cpp @@ -0,0 +1,28 @@ +// Note: the run lines follow their respective tests, since line/column +// matter in this test. +void f(float x, float y); +void f(int i, int j, int k); +struct X { }; +void f(X); +namespace N { + struct Y { + Y(int = 0); + + operator int() const; + }; + void f(Y y, int ZZ); +} +typedef N::Y Y; +void f(); + +void test() { + f(Y(), 0, 0); + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:19:9 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: f(struct N::Y y, <#int ZZ#>) + // CHECK-CC1-NEXT: f(int i, <#int j#>, int k) + // CHECK-CC1-NEXT: f(float x, <#float y#>) + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:19:13 %s -o - | FileCheck -check-prefix=CC2 %s && + // CHECK-CC2-NOT: f(struct N::Y y, int ZZ) + // CHECK-CC2: f(int i, int j, <#int k#>) + // RUN: true +} diff --git a/test/CodeCompletion/enum-switch-case-qualified.cpp b/test/CodeCompletion/enum-switch-case-qualified.cpp new file mode 100644 index 000000000000..223aca8b9323 --- /dev/null +++ b/test/CodeCompletion/enum-switch-case-qualified.cpp @@ -0,0 +1,33 @@ +namespace M { + +namespace N { + struct C { + enum Color { + Red, + Orange, + Yellow, + Green, + Blue, + Indigo, + Violet + }; + }; +} + +} + +namespace M { + +void test(enum N::C::Color color) { + switch (color) { + case + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:23:8 %s -o - | FileCheck -check-prefix=CC1 %s && + // RUN: true + // CHECK-CC1: Blue : 0 : N::C::Blue + // CHECK-CC1-NEXT: Green : 0 : N::C::Green + // CHECK-CC1-NEXT: Indigo : 0 : N::C::Indigo + // CHECK-CC1-NEXT: Orange : 0 : N::C::Orange + // CHECK-CC1-NEXT: Red : 0 : N::C::Red + // CHECK-CC1-NEXT: Violet : 0 : N::C::Violet + // CHECK-CC1: Yellow : 0 : N::C::Yellow + diff --git a/test/CodeCompletion/enum-switch-case.c b/test/CodeCompletion/enum-switch-case.c new file mode 100644 index 000000000000..d8bb5e8ca474 --- /dev/null +++ b/test/CodeCompletion/enum-switch-case.c @@ -0,0 +1,29 @@ +enum Color { + Red, + Orange, + Yellow, + Green, + Blue, + Indigo, + Violet +}; + +void test(enum Color color) { + switch (color) { + case Red: + break; + + case Yellow: + break; + + case Green: + break; + + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:19:10 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: Blue : 0 + // CHECK-CC1-NEXT: Green : 0 + // CHECK-CC1-NEXT: Indigo : 0 + // CHECK-CC1-NEXT: Orange : 0 + // CHECK-CC1-NEXT: Violet : 0 + // RUN: true + diff --git a/test/CodeCompletion/enum-switch-case.cpp b/test/CodeCompletion/enum-switch-case.cpp new file mode 100644 index 000000000000..7a388fce0e39 --- /dev/null +++ b/test/CodeCompletion/enum-switch-case.cpp @@ -0,0 +1,29 @@ +namespace N { + enum Color { + Red, + Orange, + Yellow, + Green, + Blue, + Indigo, + Violet + }; +} + +void test(enum N::Color color) { + switch (color) { + case N::Red: + break; + + case N::Yellow: + break; + + case + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:21:8 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: Blue : 0 : N::Blue + // CHECK-CC1-NEXT: Green : 0 : N::Green + // CHECK-CC1-NEXT: Indigo : 0 : N::Indigo + // CHECK-CC1-NEXT: Orange : 0 : N::Orange + // CHECK-CC1-NEXT: Violet : 0 : N::Violet + + // RUN: true diff --git a/test/CodeCompletion/function-templates.cpp b/test/CodeCompletion/function-templates.cpp new file mode 100644 index 000000000000..52cba71bd2f9 --- /dev/null +++ b/test/CodeCompletion/function-templates.cpp @@ -0,0 +1,15 @@ +namespace std { + template<typename RandomAccessIterator> + void sort(RandomAccessIterator first, RandomAccessIterator last); + + template<class X, class Y> + X* dyn_cast(Y *Val); +} + +void f() { + std:: + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:10:8 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: dyn_cast<<#class X#>>(<#Y *Val#>) + // CHECK-CC1: sort(<#RandomAccessIterator first#>, <#RandomAccessIterator last#>) + // RUN: true + diff --git a/test/CodeCompletion/functions.cpp b/test/CodeCompletion/functions.cpp new file mode 100644 index 000000000000..2e1bc6edf8c4 --- /dev/null +++ b/test/CodeCompletion/functions.cpp @@ -0,0 +1,9 @@ +void f(int i, int j = 2, int k = 5); +void f(float x, float y...); + +void test() { + :: + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:5:5 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: f(<#int i#>{#, <#int j#>{#, <#int k#>#}#}) + // CHECK-CC1: f(<#float x#>, <#float y#><#, ...#>) + // RUN: true diff --git a/test/CodeCompletion/member-access.c b/test/CodeCompletion/member-access.c new file mode 100644 index 000000000000..1e8e5630981f --- /dev/null +++ b/test/CodeCompletion/member-access.c @@ -0,0 +1,13 @@ +struct Point { + float x; + float y; + float z; +}; + +void test(struct Point *p) { + p-> + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:8:6 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: x + // CHECK-CC1: y + // CHECK-CC1: z + // RUN: true diff --git a/test/CodeCompletion/member-access.cpp b/test/CodeCompletion/member-access.cpp new file mode 100644 index 000000000000..b810366209f5 --- /dev/null +++ b/test/CodeCompletion/member-access.cpp @@ -0,0 +1,43 @@ +struct Base1 { + int member1; + float member2; +}; + +struct Base2 { + int member1; + double member3; + void memfun1(int); +}; + +struct Base3 : Base1, Base2 { + void memfun1(float); + void memfun1(double); + void memfun2(int); +}; + +struct Derived : Base3 { + int member4; + int memfun3(int); +}; + +class Proxy { +public: + Derived *operator->() const; +}; + +void test(const Proxy &p) { + p-> + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:29:6 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s && + // CHECK-CC1: member1 : 0 : [#Base1::#]member1 + // CHECK-CC1: member1 : 0 : [#Base2::#]member1 + // CHECK-CC1: member2 : 0 : [#Base1::#]member2 + // CHECK-CC1: member3 : 0 + // CHECK-CC1: member4 : 0 + // CHECK-CC1: memfun1 : 0 : [#Base3::#]memfun1(<#float#>) + // CHECK-CC1: memfun1 : 0 : [#Base3::#]memfun1(<#double#>) + // CHECK-CC1: memfun2 : 0 : [#Base3::#]memfun2(<#int#>) + // CHECK-CC1: memfun3 : 0 : memfun3(<#int#>) + // CHECK-CC1: Base1 : 0 : Base1:: + // CHECK-CC1: memfun1 : 0 (Hidden) : Base2::memfun1(<#int#>) + // RUN: true + diff --git a/test/CodeCompletion/namespace-alias.cpp b/test/CodeCompletion/namespace-alias.cpp new file mode 100644 index 000000000000..0fa2ec20209c --- /dev/null +++ b/test/CodeCompletion/namespace-alias.cpp @@ -0,0 +1,21 @@ +namespace N4 { + namespace N3 { } +} + +class N3; + +namespace N2 { + namespace I1 { } + namespace I4 = I1; + namespace I5 { } + namespace I1 { } + + namespace New = + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:13:18 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: I1 : 1 + // CHECK-CC1: I4 : 1 + // CHECK-CC1: I5 : 1 + // CHECK-CC1: N2 : 3 + // CHECK-CC1-NEXT: N4 : 3 + // RUN: true + diff --git a/test/CodeCompletion/namespace.cpp b/test/CodeCompletion/namespace.cpp new file mode 100644 index 000000000000..d4ed639f8a05 --- /dev/null +++ b/test/CodeCompletion/namespace.cpp @@ -0,0 +1,15 @@ +namespace N3 { +} + +namespace N2 { + namespace I1 { } + namespace I4 = I1; + namespace I5 { } + namespace I1 { } + + namespace + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:10:12 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: I1 : 0 + // CHECK-CC1-NEXT: I5 : 0 + // RUN: true + diff --git a/test/CodeCompletion/nested-name-specifier.cpp b/test/CodeCompletion/nested-name-specifier.cpp new file mode 100644 index 000000000000..0cc5a19421c7 --- /dev/null +++ b/test/CodeCompletion/nested-name-specifier.cpp @@ -0,0 +1,18 @@ +namespace N { + struct A { }; + namespace M { + struct C { }; + }; +} + +namespace N { + struct B { }; +} + +N:: +// RUN: clang-cc -fsyntax-only -code-completion-at=%s:12:4 %s -o - | FileCheck -check-prefix=CC1 %s && +// CHECK-CC1: A : 0 +// CHECK-CC1: B : 0 +// CHECK-CC1: M : 0 +// RUN: true + diff --git a/test/CodeCompletion/operator.cpp b/test/CodeCompletion/operator.cpp new file mode 100644 index 000000000000..a3950f6b8913 --- /dev/null +++ b/test/CodeCompletion/operator.cpp @@ -0,0 +1,18 @@ +class T { }; + +typedef int Integer; + +namespace N { } + +void f() { + typedef float Float; + + operator + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:10:11 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: Float : 0 + // CHECK-CC1: + : 0 + // CHECK-CC1: short : 0 + // CHECK-CC1: Integer : 2 + // CHECK-CC1: T : 2 + // CHECK-CC1: N : 6 + // RUN: true diff --git a/test/CodeCompletion/ordinary-name.c b/test/CodeCompletion/ordinary-name.c new file mode 100644 index 000000000000..586e2b371bd7 --- /dev/null +++ b/test/CodeCompletion/ordinary-name.c @@ -0,0 +1,12 @@ +struct X { int x; }; + +typedef struct t TYPEDEF; + +void foo() { + int y; + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:6:9 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s && + // CHECK-CC1: y : 0 + // CHECK-CC1: foo : 2 + // CHECK-NOT-CC1: y : 2 + // CHECK-CC1-NEXT: TYPEDEF : 2 + // RUN: true diff --git a/test/CodeCompletion/property.m b/test/CodeCompletion/property.m new file mode 100644 index 000000000000..7f2321ee1395 --- /dev/null +++ b/test/CodeCompletion/property.m @@ -0,0 +1,29 @@ +// Note: the run lines follow their respective tests, since line/column +// matter in this test. + +@interface Foo { + void *isa; +} +@property(copy) Foo *myprop; +@property(retain, nonatomic) id xx; +// RUN: clang-cc -fsyntax-only -code-completion-at=%s:7:11 %s -o - | FileCheck -check-prefix=CC1 %s && +// CC1: assign +// CC1-NEXT: copy +// CC1-NEXT: getter +// CC1-NEXT: nonatomic +// CC1-NEXT: readonly +// CC1-NEXT: readwrite +// CC1-NEXT: retain +// CC1-NEXT: setter +// RUN: clang-cc -fsyntax-only -code-completion-at=%s:8:18 %s -o - | FileCheck -check-prefix=CC2 %s +// CC2: assign +// CC2-NEXT: copy +// CC2-NEXT: getter +// CC2-NEXT: nonatomic +// CC2-NEXT: readonly +// CC2-NEXT: readwrite +// CC2-NEXT: setter +@end + + + diff --git a/test/CodeCompletion/tag.c b/test/CodeCompletion/tag.c new file mode 100644 index 000000000000..e7250f540c4f --- /dev/null +++ b/test/CodeCompletion/tag.c @@ -0,0 +1,13 @@ +enum X { x }; +enum Y { y }; +struct Z { }; + +void X(); + +void test() { + enum X { x }; + enum + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:9:7 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: X : 0 + // CHECK-CC1: Y : 2 + // RUN: true diff --git a/test/CodeCompletion/tag.cpp b/test/CodeCompletion/tag.cpp new file mode 100644 index 000000000000..b00ff1fabdaa --- /dev/null +++ b/test/CodeCompletion/tag.cpp @@ -0,0 +1,26 @@ +class X { }; +struct Y { }; + +namespace N { + template<typename> class Z; +} + +namespace M { + class A; +} +using M::A; + +namespace N { + class Y; + + void test() { + class + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:17:10 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: Y : 2 + // CHECK-CC1: Z : 2 + // CHECK-CC1: A : 4 + // CHECK-CC1: X : 4 + // CHECK-CC1: Y : 4 + // CHECK-CC1: M : 9 : M:: + // CHECK-CC1: N : 9 : N:: + // RUN: true diff --git a/test/CodeCompletion/templates.cpp b/test/CodeCompletion/templates.cpp new file mode 100644 index 000000000000..22cca65bea98 --- /dev/null +++ b/test/CodeCompletion/templates.cpp @@ -0,0 +1,17 @@ +namespace std { + template<typename T> + class allocator; + + template<typename T, typename Alloc = std::allocator<T> > + class vector; +} + +void f() { + std:: + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:10:8 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: allocator<<#typename T#>> + // CHECK-CC1: vector<<#typename T#>{#, <#typename Alloc#>#}> + // RUN: true + + + diff --git a/test/CodeCompletion/truncation.c b/test/CodeCompletion/truncation.c new file mode 100644 index 000000000000..b72aa7facf79 --- /dev/null +++ b/test/CodeCompletion/truncation.c @@ -0,0 +1,12 @@ +#include "truncation.c.h" + +struct + +// RUN: clang-cc -fsyntax-only -code-completion-at=%s.h:4:8 -o - %s | FileCheck -check-prefix=CC1 %s && +// CHECK-CC1: X : 1 +// CHECK-CC1-NEXT: Y : 1 +// RUN: clang-cc -fsyntax-only -code-completion-at=%s:3:8 -o - %s | FileCheck -check-prefix=CC2 %s && +// CHECK-CC2: X : 1 +// CHECK-CC2: Xa : 1 +// CHECK-CC2: Y : 1 +// RUN: true diff --git a/test/CodeCompletion/truncation.c.h b/test/CodeCompletion/truncation.c.h new file mode 100644 index 000000000000..a5ebbacb3442 --- /dev/null +++ b/test/CodeCompletion/truncation.c.h @@ -0,0 +1,5 @@ +struct X { }; +struct Y { }; + +struct Xa { }; + diff --git a/test/CodeCompletion/using-namespace.cpp b/test/CodeCompletion/using-namespace.cpp new file mode 100644 index 000000000000..a332b880074e --- /dev/null +++ b/test/CodeCompletion/using-namespace.cpp @@ -0,0 +1,21 @@ +namespace N4 { + namespace N3 { } +} + +class N3; + +namespace N2 { + namespace I1 { } + namespace I4 = I1; + namespace I5 { } + namespace I1 { } + + void foo() { + using namespace + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:14:20 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: I1 : 2 + // CHECK-CC1: I4 : 2 + // CHECK-CC1: I5 : 2 + // CHECK-CC1: N2 : 4 + // CHECK-CC1-NEXT: N4 : 4 + // RUN: true diff --git a/test/CodeCompletion/using.cpp b/test/CodeCompletion/using.cpp new file mode 100644 index 000000000000..57b3aa7880a2 --- /dev/null +++ b/test/CodeCompletion/using.cpp @@ -0,0 +1,25 @@ +namespace N4 { + namespace N3 { } +} + +class N3; + +namespace N2 { + namespace I1 { } + namespace I4 = I1; + namespace I5 { } + namespace I1 { } + + void foo() { + int N3; + + using + // RUN: clang-cc -fsyntax-only -code-completion-at=%s:16:10 %s -o - | FileCheck -check-prefix=CC1 %s && + // CHECK-CC1: I1 : 2 + // CHECK-CC1: I4 : 2 + // CHECK-CC1: I5 : 2 + // CHECK-CC1: N2 : 4 + // CHECK-CC1: N3 : 4 + // CHECK-CC1-NEXT: N4 : 4 + // RUN: true + diff --git a/test/CodeGen/2008-07-17-no-emit-on-error.c b/test/CodeGen/2008-07-17-no-emit-on-error.c index 89aeb18d9d13..51ba2b45d063 100644 --- a/test/CodeGen/2008-07-17-no-emit-on-error.c +++ b/test/CodeGen/2008-07-17-no-emit-on-error.c @@ -1,5 +1,5 @@ -// RUN: rm -f %t1.bc -// RUN: not clang-cc %s -emit-llvm-bc -o %t1.bc +// RUN: rm -f %t1.bc && +// RUN: not clang-cc %s -emit-llvm-bc -o %t1.bc && // RUN: not test -f %t1.bc void f() { diff --git a/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c b/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c index 19bf9a2b078e..348ea75ea295 100644 --- a/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c +++ b/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c @@ -1,5 +1,4 @@ -// RUN: clang-cc --emit-llvm -o %t %s && -// RUN: grep "i8 52" %t | count 1 +// RUN: clang-cc -triple=i686-apple-darwin9 --emit-llvm -o - %s | FileCheck %s struct et7 { float lv7[0]; @@ -9,3 +8,5 @@ struct et7 { 52, }; +// CHECK: @yv7 = global +// CHECK: i8 52,
\ No newline at end of file diff --git a/test/CodeGen/2008-07-29-override-alias-decl.c b/test/CodeGen/2008-07-29-override-alias-decl.c index 43f4e3ecedae..4a36e0f13d5c 100644 --- a/test/CodeGen/2008-07-29-override-alias-decl.c +++ b/test/CodeGen/2008-07-29-override-alias-decl.c @@ -1,6 +1,6 @@ // RUN: clang-cc -emit-llvm -o - %s | grep -e "^@f" | count 1 -int x() {} +int x() { return 1; } int f() __attribute__((weak, alias("x"))); diff --git a/test/CodeGen/2009-01-21-invalid-debug-info.m b/test/CodeGen/2009-01-21-invalid-debug-info.m index 9a955a1c0d95..2662b922a03c 100644 --- a/test/CodeGen/2009-01-21-invalid-debug-info.m +++ b/test/CodeGen/2009-01-21-invalid-debug-info.m @@ -10,7 +10,7 @@ @interface I1 @end @implementation I1 --im0 {} +-im0 { return 0; } @end I1 *f1(void) { return 0; } diff --git a/test/CodeGen/2009-04-23-dbg.c b/test/CodeGen/2009-04-23-dbg.c index 4be6dab7ea2b..c6b179126e03 100644 --- a/test/CodeGen/2009-04-23-dbg.c +++ b/test/CodeGen/2009-04-23-dbg.c @@ -1,4 +1,4 @@ -// RUN: clang-cc -g -o %t %s -emit-llvm-bc && llc %t -f -o %t.s +// RUN: clang-cc -g -o %t %s -emit-llvm-bc && llc %t -o %t.s # 1 "a.c" # 1 "a.c" 1 # 1 "<built-in>" 1 diff --git a/test/CodeGen/2009-06-01-addrofknr.c b/test/CodeGen/2009-06-01-addrofknr.c index 16a5bbffc3af..d51a4a47b478 100644 --- a/test/CodeGen/2009-06-01-addrofknr.c +++ b/test/CodeGen/2009-06-01-addrofknr.c @@ -2,20 +2,20 @@ // PR4289 struct funcptr { - int (*func)(); + int (*func)(); }; static int func(f) - void *f; + void *f; { + return 0; } int main(int argc, char *argv[]) { - struct funcptr fp; + struct funcptr fp; - fp.func = &func; - fp.func = func; + fp.func = &func; + fp.func = func; } - diff --git a/test/CodeGen/2009-07-31-DbgDeclare.c b/test/CodeGen/2009-07-31-DbgDeclare.c new file mode 100644 index 000000000000..da49afedbc7a --- /dev/null +++ b/test/CodeGen/2009-07-31-DbgDeclare.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -S -g -o %t.s %s +void foo() { + int i = 0; + i = 42; +} diff --git a/test/CodeGen/2009-08-14-vararray-crash.c b/test/CodeGen/2009-08-14-vararray-crash.c new file mode 100644 index 000000000000..40e071bd19a0 --- /dev/null +++ b/test/CodeGen/2009-08-14-vararray-crash.c @@ -0,0 +1,11 @@ +// RUN: clang-cc -emit-llvm < %s + +void sum1(int rb) { + typedef unsigned char imgrow[rb]; + typedef imgrow img[rb]; + + const img *br; + int y; + + (*br)[y]; +} diff --git a/test/CodeGen/PR3613-static-decl.c b/test/CodeGen/PR3613-static-decl.c index 365b9b2be05e..208358130000 100644 --- a/test/CodeGen/PR3613-static-decl.c +++ b/test/CodeGen/PR3613-static-decl.c @@ -1,5 +1,5 @@ // RUN: clang-cc -triple i386-unknown-unknown -emit-llvm -o %t %s && -// RUN: grep '@g0 = internal global .struct.s0 <{ i32 3 }>' %t | count 1 +// RUN: grep '@g0 = internal global %.truct.s0 { i32 3 }' %t | count 1 struct s0 { int a; diff --git a/test/CodeGen/PR4611-bitfield-layout.c b/test/CodeGen/PR4611-bitfield-layout.c new file mode 100644 index 000000000000..83ce4ffdbd6d --- /dev/null +++ b/test/CodeGen/PR4611-bitfield-layout.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm -o %t && +// RUN: grep "struct.object_entry = type { i8, \[2 x i8\], i8 }" %t + +struct object_entry { + unsigned int type:3, pack_id:16, depth:13; +} entries; diff --git a/test/CodeGen/PR5060-align.c b/test/CodeGen/PR5060-align.c new file mode 100644 index 000000000000..5d864084b012 --- /dev/null +++ b/test/CodeGen/PR5060-align.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -emit-llvm %s -o - -verify | FileCheck %s + +// CHECK: @foo.p = internal global i8 0, align 32 +char *foo(void) { + static char p __attribute__((aligned(32))); + return &p; +} + +void bar(long n) { + // CHECK: align 32 + char p[n] __attribute__((aligned(32))); +} + diff --git a/test/CodeGen/address-space-compound-literal.c b/test/CodeGen/address-space-compound-literal.c new file mode 100644 index 000000000000..79d19ed6b6ba --- /dev/null +++ b/test/CodeGen/address-space-compound-literal.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -emit-llvm < %s | grep "internal addrspace(1) global i32 1" + +typedef int a __attribute__((address_space(1))); +a* x = &(a){1}; + diff --git a/test/CodeGen/address-space-field1.c b/test/CodeGen/address-space-field1.c new file mode 100644 index 000000000000..f8ec83ca71cf --- /dev/null +++ b/test/CodeGen/address-space-field1.c @@ -0,0 +1,39 @@ +// RUN: clang-cc -emit-llvm < %s -o - | FileCheck %s +// CHECK:%struct.S = type { i32, i32 } +// CHECK:define void @test_addrspace(%struct.S addrspace(1)* %p1, %struct.S addrspace(2)* %p2) nounwind +// CHECK:entry: +// CHECK: %p1.addr = alloca %struct.S addrspace(1)* ; <%struct.S addrspace(1)**> [#uses=3] +// CHECK: %p2.addr = alloca %struct.S addrspace(2)* ; <%struct.S addrspace(2)**> [#uses=3] +// CHECK: store %struct.S addrspace(1)* %p1, %struct.S addrspace(1)** %p1.addr +// CHECK: store %struct.S addrspace(2)* %p2, %struct.S addrspace(2)** %p2.addr +// CHECK: %tmp = load %struct.S addrspace(2)** %p2.addr ; <%struct.S addrspace(2)*> [#uses=1] +// CHECK: %tmp1 = getelementptr inbounds %struct.S addrspace(2)* %tmp, i32 0, i32 1 ; <i32 addrspace(2)*> [#uses=1] +// CHECK: %tmp2 = load i32 addrspace(2)* %tmp1 ; <i32> [#uses=1] +// CHECK: %tmp3 = load %struct.S addrspace(1)** %p1.addr ; <%struct.S addrspace(1)*> [#uses=1] +// CHECK: %tmp4 = getelementptr inbounds %struct.S addrspace(1)* %tmp3, i32 0, i32 0 ; <i32 addrspace(1)*> [#uses=1] +// CHECK: store i32 %tmp2, i32 addrspace(1)* %tmp4 +// CHECK: %tmp5 = load %struct.S addrspace(2)** %p2.addr ; <%struct.S addrspace(2)*> [#uses=1] +// CHECK: %tmp6 = getelementptr inbounds %struct.S addrspace(2)* %tmp5, i32 0, i32 0 ; <i32 addrspace(2)*> [#uses=1] +// CHECK: %tmp7 = load i32 addrspace(2)* %tmp6 ; <i32> [#uses=1] +// CHECK: %tmp8 = load %struct.S addrspace(1)** %p1.addr ; <%struct.S addrspace(1)*> [#uses=1] +// CHECK: %tmp9 = getelementptr inbounds %struct.S addrspace(1)* %tmp8, i32 0, i32 1 ; <i32 addrspace(1)*> [#uses=1] +// CHECK: store i32 %tmp7, i32 addrspace(1)* %tmp9 +// CHECK: ret void +// CHECK:} + +// Check that we don't lose the address space when accessing a member +// of a structure. + +#define __addr1 __attribute__((address_space(1))) +#define __addr2 __attribute__((address_space(2))) + +typedef struct S { + int a; + int b; +} S; + +void test_addrspace(__addr1 S* p1, __addr2 S*p2) { + // swap + p1->a = p2->b; + p1->b = p2->a; +} diff --git a/test/CodeGen/address-space-field2.c b/test/CodeGen/address-space-field2.c new file mode 100644 index 000000000000..5576e55b63fa --- /dev/null +++ b/test/CodeGen/address-space-field2.c @@ -0,0 +1,50 @@ +// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s +// CHECK: addrspace(1) +// CHECK: addrspace(2) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) + +// Check that we don't lose the address space when accessing an array element +// inside a structure. + +#define __addr1 __attribute__((address_space(1))) +#define __addr2 __attribute__((address_space(2))) + +typedef struct S { + int arr[ 3 ]; +} S; + +void test_addrspace(__addr1 S* p1, __addr2 S*p2, int* val, int n) { + for (int i=0; i < 3; ++i) { + int t = val[i]; + p1->arr[i] = t; + for (int j=0; j < n; ++j) + p2[j].arr[i] = t; + } +} diff --git a/test/CodeGen/address-space-field3.c b/test/CodeGen/address-space-field3.c new file mode 100644 index 000000000000..567757fe6670 --- /dev/null +++ b/test/CodeGen/address-space-field3.c @@ -0,0 +1,46 @@ +// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s +// CHECK: addrspace(1) +// CHECK: addrspace(2) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) + +// Check that we don't lose the address space when accessing an array element +// inside a structure. + +#define __addr1 __attribute__((address_space(1))) +#define __addr2 __attribute__((address_space(2))) + +typedef struct S { + int arr[ 3 ]; +} S; + +void test_addrspace(__addr1 S* p1, __addr2 S*p2, int* val, int n) { + for (int i=0; i < 3; ++i) { + int t = val[i]; + p1->arr[i] = p2->arr[i]; + } +} diff --git a/test/CodeGen/address-space-field4.c b/test/CodeGen/address-space-field4.c new file mode 100644 index 000000000000..31df018206b5 --- /dev/null +++ b/test/CodeGen/address-space-field4.c @@ -0,0 +1,61 @@ +// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s +// CHECK: addrspace(2) +// CHECK: addrspace(3) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(3) +// CHECK: addrspace(3) +// CHECK: addrspace(1) +// CHECK: addrspace(3) +// CHECK: addrspace(3) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(1) +// CHECK: addrspace(2) +// CHECK: addrspace(1) +// CHECK: addrspace(2) +// CHECK: addrspace(2) +// CHECK: addrspace(2) + +// Check the load and store are using the correct address space to access +// the variables. + +#define __addr1 __attribute__((address_space(1))) +#define __addr2 __attribute__((address_space(2))) +#define __addr3 __attribute__((address_space(3))) + +typedef struct Pair { + __addr2 int* a; + __addr3 int* b; +} Pair; + +typedef struct S { + Pair arr[ 3 ]; +} S; + +void test_addrspace(__addr1 S* p1, __addr1 S* p2) { + *p1->arr[0].a = *p2->arr[1].b; +} diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c new file mode 100644 index 000000000000..c43ede2ca05e --- /dev/null +++ b/test/CodeGen/arm-arguments.c @@ -0,0 +1,94 @@ +// RUN: clang-cc -triple armv7-apple-darwin9 -target-abi=apcs-gnu -emit-llvm -w -o - %s | FileCheck -check-prefix=APCS-GNU %s && +// RUN: clang-cc -triple armv7-apple-darwin9 -target-abi=aapcs -emit-llvm -w -o - %s | FileCheck -check-prefix=AAPCS %s + +// APCS-GNU: define arm_apcscc signext i8 @f0() +// AAPCS: define arm_aapcscc signext i8 @f0() +char f0(void) { + return 0; +} + +// APCS-GNU: define arm_apcscc i8 @f1() +// AAPCS: define arm_aapcscc i8 @f1() +struct s1 { char f0; }; +struct s1 f1(void) {} + +// APCS-GNU: define arm_apcscc i16 @f2() +// AAPCS: define arm_aapcscc i16 @f2() +struct s2 { short f0; }; +struct s2 f2(void) {} + +// APCS-GNU: define arm_apcscc i32 @f3() +// AAPCS: define arm_aapcscc i32 @f3() +struct s3 { int f0; }; +struct s3 f3(void) {} + +// APCS-GNU: define arm_apcscc i32 @f4() +// AAPCS: define arm_aapcscc i32 @f4() +struct s4 { struct s4_0 { int f0; } f0; }; +struct s4 f4(void) {} + +// APCS-GNU: define arm_apcscc void @f5( +// APCS-GNU: struct.s5* noalias sret +// AAPCS: define arm_aapcscc i32 @f5() +struct s5 { struct { } f0; int f1; }; +struct s5 f5(void) {} + +// APCS-GNU: define arm_apcscc void @f6( +// APCS-GNU: struct.s6* noalias sret +// AAPCS: define arm_aapcscc i32 @f6() +struct s6 { int f0[1]; }; +struct s6 f6(void) {} + +// APCS-GNU: define arm_apcscc void @f7() +// AAPCS: define arm_aapcscc void @f7() +struct s7 { struct { int : 0; } f0; }; +struct s7 f7(void) {} + +// APCS-GNU: define arm_apcscc void @f8( +// APCS-GNU: struct.s8* noalias sret +// AAPCS: define arm_aapcscc void @f8() +struct s8 { struct { int : 0; } f0[1]; }; +struct s8 f8(void) {} + +// APCS-GNU: define arm_apcscc i32 @f9() +// AAPCS: define arm_aapcscc i32 @f9() +struct s9 { int f0; int : 0; }; +struct s9 f9(void) {} + +// APCS-GNU: define arm_apcscc i32 @f10() +// AAPCS: define arm_aapcscc i32 @f10() +struct s10 { int f0; int : 0; int : 0; }; +struct s10 f10(void) {} + +// APCS-GNU: define arm_apcscc void @f11( +// APCS-GNU: struct.s10* noalias sret +// AAPCS: define arm_aapcscc i32 @f11() +struct s11 { int : 0; int f0; }; +struct s11 f11(void) {} + +// APCS-GNU: define arm_apcscc i32 @f12() +// AAPCS: define arm_aapcscc i32 @f12() +union u12 { char f0; short f1; int f2; }; +union u12 f12(void) {} + +// APCS-GNU: define arm_apcscc void @f13( +// APCS-GNU: struct.s13* noalias sret + +// FIXME: This should return a float. +// AAPCS-FIXME: define arm_aapcscc float @f13() +struct s13 { float f0; }; +struct s13 f13(void) {} + +// APCS-GNU: define arm_apcscc void @f14( +// APCS-GNU: struct.s13* noalias sret +// AAPCS: define arm_aapcscc i32 @f14() +union u14 { float f0; }; +union u14 f14(void) {} + +// APCS-GNU: define arm_apcscc void @f15() +// AAPCS: define arm_aapcscc void @f15() +void f15(struct s7 a0) {} + +// APCS-GNU: define arm_apcscc void @f16() +// AAPCS: define arm_aapcscc void @f16() +void f16(struct s8 a0) {} diff --git a/test/CodeGen/arm_asm_clobber.c b/test/CodeGen/arm_asm_clobber.c new file mode 100644 index 000000000000..34e2517aefab --- /dev/null +++ b/test/CodeGen/arm_asm_clobber.c @@ -0,0 +1,21 @@ +// RUN: clang -ccc-host-triple armv6-unknown-unknown -emit-llvm -S -o %t %s + +void test0(void) { + asm volatile("mov r0, r0" :: ); +} +void test1(void) { + asm volatile("mov r0, r0" ::: + "cc", "memory" ); +} +void test2(void) { + asm volatile("mov r0, r0" ::: + "r0", "r1", "r2", "r3"); + asm volatile("mov r0, r0" ::: + "r4", "r5", "r6", "r8"); +} +void test3(void) { + asm volatile("mov r0, r0" ::: + "a1", "a2", "a3", "a4"); + asm volatile("mov r0, r0" ::: + "v1", "v2", "v3", "v5"); +} diff --git a/test/CodeGen/array.c b/test/CodeGen/array.c index 5bcc26ecf38b..294dabfbbb5d 100644 --- a/test/CodeGen/array.c +++ b/test/CodeGen/array.c @@ -1,11 +1,11 @@ // RUN: clang-cc -emit-llvm %s -o %t -int f() { +void f() { int a[2]; a[0] = 0; } -int f2() { +void f2() { int x = 0; int y = 1; int a[10] = { y, x, 2, 3}; diff --git a/test/CodeGen/asm-inout.c b/test/CodeGen/asm-inout.c new file mode 100644 index 000000000000..0d8dbdfb9d38 --- /dev/null +++ b/test/CodeGen/asm-inout.c @@ -0,0 +1,18 @@ +// RUN: clang-cc -triple i386-unknown-unknown -emit-llvm %s -o %t && +// RUN: grep "load i8\*\*\* %p.addr" %t | count 1 +// XFAIL + +// PR3800 +void f(void **p) +{ + __asm__ volatile("" :"+m"(*p)); +} + +#if 0 +// FIXME: Once this works again, we must verify that the code below behaves as expected +// See PR4677. +void f() { + unsigned _data = 42; + __asm__("bswap %0":"+r"(_data)); +} +#endif diff --git a/test/CodeGen/asm.c b/test/CodeGen/asm.c index 58373fc4c96e..52afc9152748 100644 --- a/test/CodeGen/asm.c +++ b/test/CodeGen/asm.c @@ -15,7 +15,7 @@ void t4() { unsigned long long a; struct reg { unsigned long long a, b; } b; - __asm__ volatile ("":: "m"(a), "m"(b)); + __asm__ volatile ("":: "m"(a), "m"(b)); } // PR3417 @@ -33,7 +33,7 @@ void t7(int a) { __asm__ volatile("T7 NAMED: %[input]" : "+r"(a): [input] "i" (4)); } -// RUN: grep "T8 NAMED MODIFIER: \${0:c}" %t +// RUN: grep "T8 NAMED MODIFIER: \${0:c}" %t && void t8() { __asm__ volatile("T8 NAMED MODIFIER: %c[input]" :: [input] "i" (4)); } @@ -101,3 +101,12 @@ void t14(struct S *P) { } +// PR4938 +int t16() { + int a,b; + asm ( "nop;" + :"=%c" (a) + : "r" (b) + ); + return 0; +} diff --git a/test/CodeGen/attr-cleanup.c b/test/CodeGen/attr-cleanup.c index 03dde3341e6c..9105ededa20c 100644 --- a/test/CodeGen/attr-cleanup.c +++ b/test/CodeGen/attr-cleanup.c @@ -3,6 +3,6 @@ // <rdar://problem/6827047> void f(void* arg); void g() { - __attribute__((cleanup(f))) void *g; + __attribute__((cleanup(f))) void *g; } diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c index 8f157f3d314b..d539e033a7e9 100644 --- a/test/CodeGen/attributes.c +++ b/test/CodeGen/attributes.c @@ -1,69 +1,77 @@ -// RUN: clang-cc -emit-llvm -o %t %s && -// RUN: grep 't1.*noreturn' %t && -// RUN: grep 't2.*nounwind' %t && -// RUN: grep 'weak.*t3' %t && -// RUN: grep 'hidden.*t4' %t && -// RUN: grep 't5.*weak' %t && -// RUN: grep 't6.*protected' %t && -// RUN: grep 't7.*noreturn' %t && -// RUN: grep 't7.*nounwind' %t && -// RUN: grep 't9.*alias.*weak.*t8' %t && -// RUN: grep '@t10().*section "SECT"' %t && -// RUN: grep '@t11().*section "SECT"' %t && -// RUN: grep '@t12 =.*section "SECT"' %t && -// RUN: grep '@t13 =.*section "SECT"' %t && -// RUN: grep '@t14.x =.*section "SECT"' %t -// RUN: grep 'declare extern_weak i32 @t15()' %t && -// RUN: grep '@t16 = extern_weak global i32' %t && +// RUN: clang-cc -emit-llvm -triple i386-linux-gnu -o %t %s && +// RUN: FileCheck --input-file=%t %s -void t1() __attribute__((noreturn)); -void t1() {} +// CHECK: @t5 = weak global i32 2 +int t5 __attribute__((weak)) = 2; -void t2() __attribute__((nothrow)); -void t2() {} +// CHECK: @t13 = global %0 zeroinitializer, section "SECT" +struct s0 { int x; }; +struct s0 t13 __attribute__((section("SECT"))) = { 0 }; -void t3() __attribute__((weak)); -void t3() {} +// CHECK: @t14.x = internal global i32 0, section "SECT" +void t14(void) { + static int x __attribute__((section("SECT"))) = 0; +} -void t4() __attribute__((visibility("hidden"))); -void t4() {} +// CHECK: @t18 = global i32 1, align 4 +extern int t18 __attribute__((weak_import)); +int t18 = 1; -int t5 __attribute__((weak)) = 2; +// CHECK: @t16 = extern_weak global i32 +extern int t16 __attribute__((weak_import)); +// CHECK: @t6 = common protected global i32 0 int t6 __attribute__((visibility("protected"))); -void t7() __attribute__((noreturn, nothrow)); -void t7() {} +// CHECK: @t12 = global i32 0, section "SECT" +int t12 __attribute__((section("SECT"))); +// CHECK: @t9 = alias weak bitcast (void ()* @__t8 to void (...)*) void __t8() {} void t9() __attribute__((weak, alias("__t8"))); -void t10(void) __attribute__((section("SECT"))); -void t10(void) {} -void __attribute__((section("SECT"))) t11(void) {} - -int t12 __attribute__((section("SECT"))); -struct s0 { int x; }; -struct s0 t13 __attribute__((section("SECT"))) = { 0 }; - -void t14(void) { - static int x __attribute__((section("SECT"))) = 0; -} - +// CHECK: declare extern_weak i32 @t15() int __attribute__((weak_import)) t15(void); -extern int t16 __attribute__((weak_import)); int t17() { return t15() + t16; } -// RUN: grep '@t18 = global i[0-9]* 1, align .*' %t && -extern int t18 __attribute__((weak_import)); -int t18 = 1; +// CHECK: define void @t1() noreturn nounwind { +void t1() __attribute__((noreturn)); +void t1() { while (1) {} } + +// CHECK: define void @t2() nounwind { +void t2() __attribute__((nothrow)); +void t2() {} -// RUN: grep 'define i[0-9]* @t19()' %t && +// CHECK: define weak void @t3() nounwind { +void t3() __attribute__((weak)); +void t3() {} + +// CHECK: define hidden void @t4() nounwind { +void t4() __attribute__((visibility("hidden"))); +void t4() {} + +// CHECK: define void @t7() noreturn nounwind { +void t7() __attribute__((noreturn, nothrow)); +void t7() { while (1) {} } + +// CHECK: define void @t10() nounwind section "SECT" { +void t10(void) __attribute__((section("SECT"))); +void t10(void) {} +// CHECK: define void @t11() nounwind section "SECT" { +void __attribute__((section("SECT"))) t11(void) {} + +// CHECK: define i32 @t19() nounwind { extern int t19(void) __attribute__((weak_import)); int t19(void) { return 10; } -// RUN: true +// CHECK:define void @t20() nounwind { +// CHECK-NEXT:entry: +// CHECK-NEXT: call void @abort() +// CHECK-NEXT: unreachable +void t20(void) { + __builtin_abort(); +} diff --git a/test/CodeGen/blocks-2.c b/test/CodeGen/blocks-2.c index 5ee2a73a82c9..bc6c2b916abd 100644 --- a/test/CodeGen/blocks-2.c +++ b/test/CodeGen/blocks-2.c @@ -1,6 +1,7 @@ -// RUN: clang-cc -g %s -emit-llvm -o %t -fblocks +// RUN: clang-cc -g %s -emit-llvm -o %t -fblocks && // RUN: grep "func.start" %t | count 4 // 1 declaration, 1 bar, 1 test_block_dbg and 1 for the block. +// XFAIL static __inline__ __attribute__((always_inline)) int bar(int va, int vb) { return (va == vb); } diff --git a/test/CodeGen/blocks-aligned-byref-variable.c b/test/CodeGen/blocks-aligned-byref-variable.c new file mode 100644 index 000000000000..1ae306254157 --- /dev/null +++ b/test/CodeGen/blocks-aligned-byref-variable.c @@ -0,0 +1,19 @@ +// RUN: clang-cc -emit-llvm -o - -triple x86_64-apple-darwin10 && +// RUN: clang-cc -emit-llvm -o - -triple i386-apple-darwin10 +typedef int __attribute__((aligned(32))) ai; + +void f() { + __block ai a = 10; + + ^{ + a = 20; + }(); +} + +void g() { + __block double a = 10; + + ^{ + a = 20; + }(); +} diff --git a/test/CodeGen/blocks-seq.c b/test/CodeGen/blocks-seq.c index f637fbc0782e..3ff241e3f6e3 100644 --- a/test/CodeGen/blocks-seq.c +++ b/test/CodeGen/blocks-seq.c @@ -1,13 +1,13 @@ -// RUN: clang-cc -fblocks -triple x86_64-apple-darwin10 -emit-llvm -o %t %s && -// RUN: grep '%call = call i32 (...)\* @rhs()' %t | count 1 && -// If this fails, see about sliding %4, %5, %6 and %7... -// RUN: grep '%forwarding1 = getelementptr %0\* %i, i32 0, i32 1' %t | count 1 && -// RUN: grep '%4 = bitcast i8\*\* %forwarding1 to %0\*\*' %t | count 1 && -// RUN: grep '%5 = load %0\*\* %4' %t | count 1 && -// RUN: grep '%call2 = call i32 (...)\* @rhs()' %t | count 1 && -// RUN: grep '%forwarding3 = getelementptr %0\* %i, i32 0, i32 1' %t | count 1 && -// RUN: grep '%6 = bitcast i8\*\* %forwarding3 to %0\*\*' %t | count 1 && -// RUN: grep '%7 = load %0\*\* %6' %t | count 1 +// FIXME: We forcibly strip the names so that the test doesn't vary between +// builds with and without asserts. We need a better solution for this. + +// RUN: clang-cc -fblocks -triple x86_64-apple-darwin10 -emit-llvm-bc -o - %s | opt -strip | llvm-dis > %t && +// RUN: grep '%6 = call i32 (...)\* @rhs()' %t | count 1 && +// RUN: grep '%7 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 && +// RUN: grep '%8 = load %0\*\* %7' %t | count 1 && +// RUN: grep '%10 = call i32 (...)\* @rhs()' %t | count 1 && +// RUN: grep '%11 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 && +// RUN: grep '%12 = load %0\*\* %11' %t | count 1 int rhs(); diff --git a/test/CodeGen/boolassign.c b/test/CodeGen/boolassign.c index 2d14f8c1de19..73aab8db7cb1 100644 --- a/test/CodeGen/boolassign.c +++ b/test/CodeGen/boolassign.c @@ -1,6 +1,7 @@ // RUN: clang-cc %s -emit-llvm -o %t int testBoolAssign(void) { -int ss; -if ((ss = ss && ss)) {} + int ss; + if ((ss = ss && ss)) {} + return 1; } diff --git a/test/CodeGen/builtin-attributes.c b/test/CodeGen/builtin-attributes.c new file mode 100644 index 000000000000..184e9676edaa --- /dev/null +++ b/test/CodeGen/builtin-attributes.c @@ -0,0 +1,12 @@ +// RUN: clang-cc -triple arm-unknown-unknown -emit-llvm -o - %s | FileCheck %s + +// CHECK: declare arm_aapcscc i32 @printf(i8*, ...) +void f0() { + printf("a\n"); +} + +// CHECK: call arm_aapcscc void @exit +// CHECK: unreachable +void f1() { + exit(1); +} diff --git a/test/CodeGen/builtins-ffs_parity_popcount.c b/test/CodeGen/builtins-ffs_parity_popcount.c index 47469985eeda..e3fa4d2d8212 100644 --- a/test/CodeGen/builtins-ffs_parity_popcount.c +++ b/test/CodeGen/builtins-ffs_parity_popcount.c @@ -1,5 +1,5 @@ -// RUN: clang-cc -emit-llvm -o - %s > %t -// RUN: ! grep "__builtin" %t +// RUN: clang-cc -emit-llvm -o - %s > %t && +// RUN: not grep "__builtin" %t #include <stdio.h> diff --git a/test/CodeGen/builtins-powi.c b/test/CodeGen/builtins-powi.c index 73f752f5e80e..5b413a889502 100644 --- a/test/CodeGen/builtins-powi.c +++ b/test/CodeGen/builtins-powi.c @@ -1,5 +1,5 @@ -// RUN: clang-cc -emit-llvm -o - %s > %t -// RUN: ! grep "__builtin" %t +// RUN: clang-cc -emit-llvm -o - %s > %t && +// RUN: not grep "__builtin" %t #include <stdio.h> #include <stdlib.h> diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c index ce5cd74bd4c4..165db9c26753 100644 --- a/test/CodeGen/builtins.c +++ b/test/CodeGen/builtins.c @@ -54,6 +54,8 @@ int main() { P(islessgreater, (1., 2.)); P(isunordered, (1., 2.)); + P(isnan, (1.)); + // Bitwise & Numeric Functions P(abs, (N)); diff --git a/test/CodeGen/cast-to-union.c b/test/CodeGen/cast-to-union.c index 6098bcc5a07c..674299294928 100644 --- a/test/CodeGen/cast-to-union.c +++ b/test/CodeGen/cast-to-union.c @@ -1,7 +1,7 @@ -// RUN: clang-cc -emit-llvm < %s -o %t && -// RUN: grep "store i32 351, i32*" %t && -// RUN: grep "w = global %0 <{ i32 2, i8 0, i8 0, i8 0, i8 0 }>" %t && -// RUN: grep "y = global %1 <{ double 7.300000e+01 }>" %t +// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s +// CHECK: w = global %0 { i32 2, [4 x i8] zeroinitializer } +// CHECK: y = global %union.u { double 7.300000e+0{{[0]*}}1 } +// CHECK: store i32 351, i32 union u { int i; double d; }; diff --git a/test/CodeGen/conditional.c b/test/CodeGen/conditional.c index 22286705c89c..8a30463cb7e4 100644 --- a/test/CodeGen/conditional.c +++ b/test/CodeGen/conditional.c @@ -1,11 +1,10 @@ // RUN: clang-cc -emit-llvm %s -o %t -float test1(int cond, float a, float b) -{ +float test1(int cond, float a, float b) { return cond ? a : b; } -double test2(int cond, float a, double b) -{ + +double test2(int cond, float a, double b) { return cond ? a : b; } @@ -16,8 +15,8 @@ void test3(){ } void test4() { -int i; short j; -float* k = 1 ? &i : &j; + int i; short j; + float* k = 1 ? &i : &j; } void test5() { @@ -33,12 +32,10 @@ void* test8() {return 1 ? test6 : test7;} void _efree(void *ptr); -void _php_stream_free3() -{ - (1 ? free(0) : _efree(0)); +void _php_stream_free3() { + (1 ? free(0) : _efree(0)); } -void _php_stream_free4() -{ - 1 ? _efree(0) : free(0); +void _php_stream_free4() { + 1 ? _efree(0) : free(0); } diff --git a/test/CodeGen/const-init.c b/test/CodeGen/const-init.c index 0364cc153ff8..29e9c5561527 100644 --- a/test/CodeGen/const-init.c +++ b/test/CodeGen/const-init.c @@ -1,4 +1,4 @@ -// RUN: clang-cc -triple i386-pc-linux-gnu -verify -emit-llvm -o %t %s && +// RUN: clang-cc -triple i386-pc-linux-gnu -verify -emit-llvm -o - %s | FileCheck %s #include <stdint.h> @@ -22,44 +22,57 @@ union s2 { int g0 = (int)(&(((union s2 *) 0)->f0.f0) - 0); -// RUN: grep '@g1x = global %. { double 1.000000e+00, double 0.000000e+00 }' %t && +// CHECK: @g1x = global {{%.}} { double 1.000000e+00{{[0]*}}, double 0.000000e+00{{[0]*}} } _Complex double g1x = 1.0f; -// RUN: grep '@g1y = global %. { double 0.000000e+00, double 1.000000e+00 }' %t && +// CHECK: @g1y = global {{%.}} { double 0.000000e+00{{[0]*}}, double 1.000000e+00{{[0]*}} } _Complex double g1y = 1.0fi; -// RUN: grep '@g1 = global %. { i8 1, i8 10 }' %t && +// CHECK: @g1 = global {{%.}} { i8 1, i8 10 } _Complex char g1 = (char) 1 + (char) 10 * 1i; -// RUN: grep '@g2 = global %2 { i32 1, i32 10 }' %t && +// CHECK: @g2 = global %2 { i32 1, i32 10 } _Complex int g2 = 1 + 10i; -// RUN: grep '@g3 = global %. { float 1.000000e+00, float 1.000000e+01 }' %t && +// CHECK: @g3 = global {{%.}} { float 1.000000e+00{{[0]*}}, float 1.000000e+0{{[0]*}}1 } _Complex float g3 = 1.0 + 10.0i; -// RUN: grep '@g4 = global %. { double 1.000000e+00, double 1.000000e+01 }' %t && +// CHECK: @g4 = global {{%.}} { double 1.000000e+00{{[0]*}}, double 1.000000e+0{{[0]*}}1 } _Complex double g4 = 1.0 + 10.0i; -// RUN: grep '@g5 = global %2 zeroinitializer' %t && +// CHECK: @g5 = global %2 zeroinitializer _Complex int g5 = (2 + 3i) == (5 + 7i); -// RUN: grep '@g6 = global %. { double -1.100000e+01, double 2.900000e+01 }' %t && +// CHECK: @g6 = global {{%.}} { double -1.100000e+0{{[0]*}}1, double 2.900000e+0{{[0]*}}1 } _Complex double g6 = (2.0 + 3.0i) * (5.0 + 7.0i); -// RUN: grep '@g7 = global i32 1' %t && +// CHECK: @g7 = global i32 1 int g7 = (2 + 3i) * (5 + 7i) == (-11 + 29i); -// RUN: grep '@g8 = global i32 1' %t && +// CHECK: @g8 = global i32 1 int g8 = (2.0 + 3.0i) * (5.0 + 7.0i) == (-11.0 + 29.0i); -// RUN: grep '@g9 = global i32 0' %t && +// CHECK: @g9 = global i32 0 int g9 = (2 + 3i) * (5 + 7i) != (-11 + 29i); -// RUN: grep '@g10 = global i32 0' %t && +// CHECK: @g10 = global i32 0 int g10 = (2.0 + 3.0i) * (5.0 + 7.0i) != (-11.0 + 29.0i); +// PR5108 +// CHECK: @gv1 = global %4 <{ i32 0, i8 7 }>, align 1 +struct { + unsigned long a; + unsigned long b:3; +} __attribute__((__packed__)) gv1 = { .a = 0x0, .b = 7, }; + +// PR5118 +// CHECK: @gv2 = global %5 <{ i8 1, i8* null }>, align 1 +struct { + unsigned char a; + char *b; +} __attribute__((__packed__)) gv2 = { 1, (void*)0 }; // Global references -// RUN: grep '@g11.l0 = internal global i32 ptrtoint (i32 ()\* @g11 to i32)' %t && +// CHECK: @g11.l0 = internal global i32 ptrtoint (i32 ()* @g11 to i32) long g11() { static long l0 = (long) g11; return l0; } -// RUN: grep '@g12 = global i32 ptrtoint (i8\* @g12_tmp to i32)' %t && +// CHECK: @g12 = global i32 ptrtoint (i8* @g12_tmp to i32) static char g12_tmp; long g12 = (long) &g12_tmp; -// RUN: grep '@g13 = global \[1 x .struct.g13_s0\] \[.struct.g13_s0 <{ i32 ptrtoint (i8\* @g12_tmp to i32) }>\]' %t && +// CHECK: @g13 = global [1 x %struct.g13_s0] [%struct.g13_s0 { i32 ptrtoint (i8* @g12_tmp to i32) }] struct g13_s0 { long a; }; @@ -67,26 +80,25 @@ struct g13_s0 g13[] = { { (long) &g12_tmp } }; -// RUN: grep '@g14 = global i8\* inttoptr (i64 100 to i8\*)' %t && +// CHECK: @g14 = global i8* inttoptr (i64 100 to i8*) void *g14 = (void*) 100; -// RUN: grep '@g15 = global i32 -1' %t && +// CHECK: @g15 = global i32 -1 int g15 = (int) (char) ((void*) 0 + 255); -// RUN: grep '@g16 = global i64 4294967295' %t && +// CHECK: @g16 = global i64 4294967295 long long g16 = (long long) ((void*) 0xFFFFFFFF); -// RUN: grep '@g17 = global i32\* @g15' %t && +// CHECK: @g17 = global i32* @g15 int *g17 = (int *) ((long) &g15); -// RUN: grep '@g18.p = internal global \[1 x i32\*\] \[i32\* @g19\]' %t && +// CHECK: @g18.p = internal global [1 x i32*] [i32* @g19] void g18(void) { extern int g19; static int *p[] = { &g19 }; } -// RUN: grep '@g20.l0 = internal global .struct.g20_s1 <{ .struct.g20_s0\* null, .struct.g20_s0\*\* getelementptr (.struct.g20_s1\* @g20.l0, i32 0, i32 0) }>' %t && - +// CHECK: @g20.l0 = internal global %struct.g20_s1 { %struct.g20_s0* null, %struct.g20_s0** getelementptr inbounds (%struct.g20_s1* @g20.l0, i32 0, i32 0) } struct g20_s0; struct g20_s1 { struct g20_s0 *f0, **f1; @@ -99,6 +111,3 @@ void *g20(void) { // PR4108 struct g21 {int g21;}; const struct g21 g21 = (struct g21){1}; - -// RUN: true - diff --git a/test/CodeGen/darwin-string-literals.c b/test/CodeGen/darwin-string-literals.c index ff245fcc7a5c..04e43a234d19 100644 --- a/test/CodeGen/darwin-string-literals.c +++ b/test/CodeGen/darwin-string-literals.c @@ -1,10 +1,16 @@ -// RUN: clang-cc -triple i386-apple-darwin9 -emit-llvm %s -o %t && +// RUN: clang-cc -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix LSB %s && -// RUN: grep -F '@"\01LC" = internal constant [8 x i8] c"string0\00"' %t && -// RUN: grep -F '@"\01LC1" = internal constant [8 x i8] c"string1\00", section "__TEXT,__cstring,cstring_literals"' %t && -// RUN: grep -F '@__utf16_string_ = internal global [35 x i8] c"h\00e\00l\00l\00o\00 \00\92! \00\03& \00\90! \00w\00o\00r\00l\00d\00\00", section "__TEXT,__ustring", align 2' %t && -// RUN: true +// CHECK-LSB: @.str = private constant [8 x i8] c"string0\00" +// CHECK-LSB: @.str1 = private constant [8 x i8] c"string1\00" +// CHECK-LSB: @.str2 = internal constant [36 x i8] c"h\00e\00l\00l\00o\00 \00\92! \00\03& \00\90! \00w\00o\00r\00l\00d\00\00\00", section "__TEXT,__ustring", align 2 + +// RUN: clang-cc -triple powerpc-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix MSB %s + +// CHECK-MSB: @.str = private constant [8 x i8] c"string0\00" +// CHECK-MSB: @.str1 = private constant [8 x i8] c"string1\00" +// CHECK-MSB: @.str2 = internal constant [36 x i8] c"\00h\00e\00l\00l\00o\00 !\92\00 &\03\00 !\90\00 \00w\00o\00r\00l\00d\00\00", section "__TEXT,__ustring", align 2 const char *g0 = "string0"; const void *g1 = __builtin___CFStringMakeConstantString("string1"); const void *g2 = __builtin___CFStringMakeConstantString("hello \u2192 \u2603 \u2190 world"); +const void *g3 = __builtin___CFStringMakeConstantString("testâ„¢"); diff --git a/test/CodeGen/debug-info.c b/test/CodeGen/debug-info.c index e0ec2c9027cf..beee7ac9b61a 100644 --- a/test/CodeGen/debug-info.c +++ b/test/CodeGen/debug-info.c @@ -24,14 +24,14 @@ char xpto[]; // PR3427 struct foo { - int a; - void *ptrs[]; + int a; + void *ptrs[]; }; struct foo bar; // PR4143 struct foo2 { - enum bar *bar; + enum bar *bar; }; struct foo2 foo2; diff --git a/test/CodeGen/designated-initializers.c b/test/CodeGen/designated-initializers.c index 466933928665..f20bc782b6ac 100644 --- a/test/CodeGen/designated-initializers.c +++ b/test/CodeGen/designated-initializers.c @@ -1,5 +1,6 @@ -// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm -o - | grep "<{ i8\* null, i32 1024 }>" && -// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm -o - | grep "i32 0, i32 22" +// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm -o %t && +// RUN: grep "{ i8\* null, i32 1024 }" %t && +// RUN: grep "i32 0, i32 22" %t struct foo { void *a; diff --git a/test/CodeGen/exprs.c b/test/CodeGen/exprs.c index 36cfff9e8a69..a0e5b7644aeb 100644 --- a/test/CodeGen/exprs.c +++ b/test/CodeGen/exprs.c @@ -15,7 +15,7 @@ void *test(int *i) { } _Bool test2b; -int test2() {if (test2b);} +int test2() { if (test2b); return 0; } // PR1921 int test3() { @@ -48,9 +48,9 @@ int ola() { // this one shouldn't fold as well void eMaisUma() { - double t[1]; - if (*t) - return; + double t[1]; + if (*t) + return; } // rdar://6520707 diff --git a/test/CodeGen/ext-vector-shuffle.c b/test/CodeGen/ext-vector-shuffle.c index 37d3ed42d060..f53db945da03 100644 --- a/test/CodeGen/ext-vector-shuffle.c +++ b/test/CodeGen/ext-vector-shuffle.c @@ -1,5 +1,5 @@ -// RUN: clang-cc %s -emit-llvm -o - | not grep 'extractelement' -// RUN: clang-cc %s -emit-llvm -o - | not grep 'insertelement' +// RUN: clang-cc %s -emit-llvm -o - | not grep 'extractelement' && +// RUN: clang-cc %s -emit-llvm -o - | not grep 'insertelement' && // RUN: clang-cc %s -emit-llvm -o - | grep 'shufflevector' typedef __attribute__(( ext_vector_type(2) )) float float2; diff --git a/test/CodeGen/ext-vector.c b/test/CodeGen/ext-vector.c index e3b6211ee991..6a246db63515 100644 --- a/test/CodeGen/ext-vector.c +++ b/test/CodeGen/ext-vector.c @@ -115,9 +115,21 @@ void test7(int4 *ap, int4 *bp, int c) { a /= c; a %= c; - // Vector comparisons can sometimes crash the x86 backend: rdar://6326239, - // reject them until the implementation is stable. -#if 0 + // Vector comparisons. + int4 cmp; + cmp = a < b; + cmp = a <= b; + cmp = a < b; + cmp = a >= b; + cmp = a == b; + cmp = a != b; +} + +void test8(float4 *ap, float4 *bp, int c) { + float4 a = *ap; + float4 b = *bp; + + // Vector comparisons. int4 cmp; cmp = a < b; cmp = a <= b; @@ -125,5 +137,4 @@ void test7(int4 *ap, int4 *bp, int c) { cmp = a >= b; cmp = a == b; cmp = a != b; -#endif } diff --git a/test/CodeGen/function-attributes.c b/test/CodeGen/function-attributes.c index ba2e4e4d564d..d2d3b031a83b 100644 --- a/test/CodeGen/function-attributes.c +++ b/test/CodeGen/function-attributes.c @@ -56,7 +56,7 @@ int ai_1() { return 4; } static __inline__ __attribute__((always_inline)) struct { int a, b, c, d, e; -} ai_2() { } +} ai_2() { while (1) {} } int foo() { diff --git a/test/CodeGen/functions.c b/test/CodeGen/functions.c index 12dff1b72cbc..dba29316e1a3 100644 --- a/test/CodeGen/functions.c +++ b/test/CodeGen/functions.c @@ -3,11 +3,11 @@ int g(); int foo(int i) { - return g(i); + return g(i); } int g(int i) { - return g(i); + return g(i); } // rdar://6110827 @@ -32,6 +32,7 @@ void f1() {} // RUN: grep 'define .* @f3' %t | not grep -F '...' struct foo { int X, Y, Z; } f3() { + while (1) {} } // PR4423 - This shouldn't crash in codegen diff --git a/test/CodeGen/global-decls.c b/test/CodeGen/global-decls.c index 80222ea85ef1..decb6a981c7f 100644 --- a/test/CodeGen/global-decls.c +++ b/test/CodeGen/global-decls.c @@ -11,7 +11,7 @@ int g0_common __attribute__((weak)); // RUN: grep '@g0_def = weak global i32' %t && int g0_def __attribute__((weak)) = 52; // RUN: grep 'define weak i32 @g1_def()' %t && -int __attribute__((weak)) g1_def (void) {} +int __attribute__((weak)) g1_def (void) { return 0; } // Force _ext references void f0() { diff --git a/test/CodeGen/global-init.c b/test/CodeGen/global-init.c index 4b769f8ccbb0..2368422f3ab7 100644 --- a/test/CodeGen/global-init.c +++ b/test/CodeGen/global-init.c @@ -1,7 +1,30 @@ -// RUN: clang-cc -emit-llvm -o - %s | not grep "common" +// RUN: clang-cc -emit-llvm -o - -triple i386-linux-gnu %s | FileCheck %s // This checks that the global won't be marked as common. // (It shouldn't because it's being initialized). int a; int a = 242; +// CHECK: @a = global i32 242 + +// This should get normal weak linkage. +int c __attribute__((weak))= 0; +// CHECK: @c = weak global i32 0 + + + +// Since this is marked const, it should get weak_odr linkage, since all +// definitions have to be the same. +// CHECK: @d = weak_odr constant i32 0 +const int d __attribute__((weak))= 0; + + + +// NOTE: tentative definitions are processed at the end of the translation unit. + +// This shouldn't be emitted as common because it has an explicit section. +// rdar://7119244 +int b __attribute__((section("foo"))); + +// CHECK: @b = global i32 0, section "foo" + diff --git a/test/CodeGen/global-with-initialiser.c b/test/CodeGen/global-with-initialiser.c index 29b4e21b9129..d253782f66e1 100644 --- a/test/CodeGen/global-with-initialiser.c +++ b/test/CodeGen/global-with-initialiser.c @@ -17,9 +17,9 @@ long double globalLongDouble = 1; long double globalLongDoubleArray[5] = { 1.0, 2.0 }; struct Struct { - int member1; - float member2; - char *member3; + int member1; + float member2; + char *member3; }; struct Struct globalStruct = { 1, 2.0f, "foobar"}; diff --git a/test/CodeGen/globalinit.c b/test/CodeGen/globalinit.c index 2798cae712a2..b3d0cb54d15c 100644 --- a/test/CodeGen/globalinit.c +++ b/test/CodeGen/globalinit.c @@ -37,7 +37,7 @@ static int a = { 1 }; // References to enums. enum { - EnumA, EnumB + EnumA, EnumB }; int c[] = { EnumA, EnumB }; diff --git a/test/CodeGen/init-with-member-expr.c b/test/CodeGen/init-with-member-expr.c index 7750dbf9869d..197a9ab4e3b8 100644 --- a/test/CodeGen/init-with-member-expr.c +++ b/test/CodeGen/init-with-member-expr.c @@ -14,7 +14,7 @@ typedef struct mark_header_tag { } mark_header_t; int is_rar_archive(int fd) { const mark_header_t rar_hdr[2] = {{0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}, {'U', 'n', 'i', 'q', 'u', 'E', '!'}}; - foo(rar_hdr); + foo(rar_hdr); return 0; } diff --git a/test/CodeGen/inline.c b/test/CodeGen/inline.c index 234f1f8d93a8..bf17fd7c22ba 100644 --- a/test/CodeGen/inline.c +++ b/test/CodeGen/inline.c @@ -1,5 +1,5 @@ -// RUN: echo "C89 tests:" && -// RUN: clang %s -emit-llvm -S -o %t -std=c89 && +// RUN: echo "GNU89 tests:" && +// RUN: clang %s -emit-llvm -S -o %t -std=gnu89 && // RUN: grep "define available_externally i32 @ei()" %t && // RUN: grep "define i32 @foo()" %t && // RUN: grep "define i32 @bar()" %t && @@ -24,9 +24,9 @@ // RUN: grep "define available_externally void @gnu_ei_inline()" %t && // RUN: grep "define i32 @test1" %t && // RUN: grep "define i32 @test2" %t && -// RUN: grep "define available_externally void @test3" %t && +// RUN: grep "define void @test3" %t && // RUN: grep "define available_externally i32 @test4" %t && -// RUN: grep "define i32 @test5" %t && +// RUN: grep "define available_externally i32 @test5" %t && // RUN: echo "\nC++ tests:" && // RUN: clang %s -emit-llvm -S -o %t -std=c++98 && @@ -67,20 +67,20 @@ void test_test2() { test2(); } // PR3989 extern __inline void test3() __attribute__((gnu_inline)); -__inline void test3() {} - -void test_test3() { test3(); } +__inline void __attribute__((gnu_inline)) test3() {} extern int test4(void); extern __inline __attribute__ ((__gnu_inline__)) int test4(void) { + return 0; } void test_test4() { test4(); } -extern __inline int test5(void); +extern __inline int test5(void) __attribute__ ((__gnu_inline__)); extern __inline int __attribute__ ((__gnu_inline__)) test5(void) { + return 0; } void test_test5() { test5(); } diff --git a/test/CodeGen/inline2.c b/test/CodeGen/inline2.c new file mode 100644 index 000000000000..6f165f50f8b7 --- /dev/null +++ b/test/CodeGen/inline2.c @@ -0,0 +1,62 @@ +// RUN: clang-cc -std=gnu89 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix GNU89 %s && +// RUN: clang-cc -std=c99 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix C99 %s + +// CHECK-GNU89: define i32 @f0() +// CHECK-C99: define i32 @f0() +int f0(void); +int f0(void) { return 0; } + +// CHECK-GNU89: define i32 @f1() +// CHECK-C99: define i32 @f1() +inline int f1(void); +int f1(void) { return 0; } + +// CHECK-GNU89: define i32 @f2() +// CHECK-C99: define i32 @f2() +int f2(void); +inline int f2(void) { return 0; } + +// CHECK-GNU89: define i32 @f3() +// CHECK-C99: define i32 @f3() +extern inline int f3(void); +int f3(void) { return 0; } + +// CHECK-GNU89: define i32 @f5() +// CHECK-C99: define i32 @f5() +extern inline int f5(void); +inline int f5(void) { return 0; } + +// CHECK-GNU89: define i32 @f6() +// CHECK-C99: define i32 @f6() +inline int f6(void); +extern inline int f6(void) { return 0; } + +// CHECK-GNU89: define i32 @f7() +// CHECK-C99: define i32 @f7() +extern inline int f7(void); +extern int f7(void) { return 0; } + +// CHECK-GNU89: define i32 @fA() +inline int fA(void) { return 0; } + +// CHECK-GNU89: define available_externally i32 @f4() +// CHECK-C99: define i32 @f4() +int f4(void); +extern inline int f4(void) { return 0; } + +// CHECK-GNU89: define available_externally i32 @f8() +// CHECK-C99: define i32 @f8() +extern int f8(void); +extern inline int f8(void) { return 0; } + +// CHECK-GNU89: define available_externally i32 @f9() +// CHECK-C99: define i32 @f9() +extern inline int f9(void); +extern inline int f9(void) { return 0; } + +// CHECK-C99: define available_externally i32 @fA() + +int test_all() { + return f0() + f1() + f2() + f3() + f4() + f5() + f6() + f7() + f8() + f9() + + fA(); +} diff --git a/test/CodeGen/packed-union.c b/test/CodeGen/packed-union.c new file mode 100644 index 000000000000..d11d3a490234 --- /dev/null +++ b/test/CodeGen/packed-union.c @@ -0,0 +1,16 @@ +// RUN: clang-cc -triple x86_64-apple-darwin10 -emit-llvm %s -o %t && + +// RUN: grep "struct._attrs = type <{ i32, i8 }>" %t && +typedef struct _attrs { + unsigned file_attributes; + unsigned char filename_length; +} __attribute__((__packed__)) attrs; + +// RUN: grep "union._attr_union = type <{ i32, i8 }>" %t +typedef union _attr_union { + attrs file_attrs; + unsigned owner_id; +} __attribute__((__packed__)) attr_union; + +attr_union u; + diff --git a/test/CodeGen/parameter-passing.c b/test/CodeGen/parameter-passing.c index 2ace299ef770..dce0ff80cdc4 100644 --- a/test/CodeGen/parameter-passing.c +++ b/test/CodeGen/parameter-passing.c @@ -11,7 +11,7 @@ // RUN: clang-cc %s -triple x86_64-unknown-unknown -O3 -emit-llvm -o %t && // RUN: not grep '@g0' %t && -// RUN: clang-cc %s -triple ppc-unknown-unknown -O3 -emit-llvm -o %t && +// RUN: clang-cc %s -triple powerpc-unknown-unknown -O3 -emit-llvm -o %t && // RUN: not grep '@g0' %t && // RUN: true diff --git a/test/CodeGen/pragma-pack-1.c b/test/CodeGen/pragma-pack-1.c new file mode 100644 index 000000000000..bcfcd5ac3ab9 --- /dev/null +++ b/test/CodeGen/pragma-pack-1.c @@ -0,0 +1,7 @@ +// RUN: clang-cc -emit-llvm -o - + +// PR4610 +#pragma pack(4) +struct ref { + struct ref *next; +} refs; diff --git a/test/CodeGen/pragma-pack-2.c b/test/CodeGen/pragma-pack-2.c new file mode 100644 index 000000000000..306f02dd8cfe --- /dev/null +++ b/test/CodeGen/pragma-pack-2.c @@ -0,0 +1,23 @@ +// RUN: clang-cc -triple i386-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X32 %s && +// CHECK-X32: %struct.s0 = type { i64, i64, i32, [12 x i32] } +// CHECK-X32: %struct.s1 = type { [15 x i32], %struct.s0 } + +// RUN: clang-cc -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X64 %s +// CHECK-X64: %struct.s0 = type <{ i64, i64, i32, [12 x i32] }> +// CHECK-X64: %struct.s1 = type <{ [15 x i32], %struct.s0 }> + +// rdar://problem/7095436 +#pragma pack(4) + +struct s0 { + long long a __attribute__((aligned(8))); + long long b __attribute__((aligned(8))); + unsigned int c __attribute__((aligned(8))); + int d[12]; +} a; + +struct s1 { + int a[15]; + struct s0 b; +} b; + diff --git a/test/CodeGen/pragma-pack-3.c b/test/CodeGen/pragma-pack-3.c new file mode 100644 index 000000000000..b9166ae5d390 --- /dev/null +++ b/test/CodeGen/pragma-pack-3.c @@ -0,0 +1,19 @@ +// RUN: clang-cc -triple i386-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X32 %s && +// CHECK-X32: %struct.menu = type <{ i8*, i8, i8 }> +// CHECK-X32: %union.command = type <{ i8*, [2 x i8] }> + +// RUN: clang-cc -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X64 %s +// CHECK-X64: %struct.menu = type <{ i8*, i8, i8 }> +// CHECK-X64: %union.command = type <{ i8*, [2 x i8] }> + +// <rdar://problem/7184250> +#pragma pack(push, 2) +typedef union command { + void *windowRef; + struct menu { + void *menuRef; + unsigned char menuItemIndex; + } menu; +} command; + +command c; diff --git a/test/CodeGen/pragma-weak.c b/test/CodeGen/pragma-weak.c new file mode 100644 index 000000000000..497039a8f42c --- /dev/null +++ b/test/CodeGen/pragma-weak.c @@ -0,0 +1,165 @@ +// RUN: clang-cc -emit-llvm %s -o - -verify | FileCheck %s + +// CHECK: @weakvar = weak global +// CHECK: @__weakvar_alias = common global +// CHECK: @correct_linkage = weak global + + +// CHECK: @both = alias void ()* @__both +// CHECK: @both2 = alias void ()* @__both2 +// CHECK: @both3 = alias weak void ()* @__both3 +// CHECK: @a3 = alias weak void ()* @__a3 +// CHECK: @weakvar_alias = alias weak i32* @__weakvar_alias +// CHECK: @foo = alias weak void ()* @__foo +// CHECK: @foo2 = alias weak void ()* @__foo2 +// CHECK: @stutter = alias weak void ()* @__stutter +// CHECK: @stutter2 = alias weak void ()* @__stutter2 +// CHECK: @declfirst = alias weak void ()* @__declfirst +// CHECK: @declfirstattr = alias weak void ()* @__declfirstattr +// CHECK: @mix2 = alias weak void ()* @__mix2 +// CHECK: @a1 = alias weak void ()* @__a1 +// CHECK: @xxx = alias weak void ()* @__xxx + + + +// CHECK: define weak void @weakdef() + + +#pragma weak weakvar +int weakvar; + +#pragma weak weakdef +void weakdef(void) {} + +#pragma weak param // expected-warning {{weak identifier 'param' never declared}} +#pragma weak correct_linkage +void f(int param) { + int correct_linkage; +} + +#pragma weak weakvar_alias = __weakvar_alias +int __weakvar_alias; + +#pragma weak foo = __foo +void __foo(void) {} +// CHECK: define void @__foo() + + +void __foo2(void) {} +#pragma weak foo2 = __foo2 +// CHECK: define void @__foo2() + + +///// test errors + +#pragma weak unused // expected-warning {{weak identifier 'unused' never declared}} +#pragma weak unused_alias = __unused_alias // expected-warning {{weak identifier '__unused_alias' never declared}} + +#pragma weak td // expected-warning {{weak identifier 'td' never declared}} +typedef int td; + +#pragma weak td2 = __td2 // expected-warning {{weak identifier '__td2' never declared}} +typedef int __td2; + + +///// test weird cases + +// test repeats + +#pragma weak stutter = __stutter +#pragma weak stutter = __stutter +void __stutter(void) {} +// CHECK: define void @__stutter() + +void __stutter2(void) {} +#pragma weak stutter2 = __stutter2 +#pragma weak stutter2 = __stutter2 +// CHECK: define void @__stutter2() + + +// test decl/pragma weak order + +void __declfirst(void); +#pragma weak declfirst = __declfirst +void __declfirst(void) {} +// CHECK: define void @__declfirst() + +void __declfirstattr(void) __attribute((noinline)); +#pragma weak declfirstattr = __declfirstattr +void __declfirstattr(void) {} +// CHECK: define void @__declfirstattr() + +//// test that other attributes are preserved + +//// ensure that pragma weak/__attribute((weak)) play nice + +void mix(void); +#pragma weak mix +__attribute((weak)) void mix(void) { } +// CHECK: define weak void @mix() + +// ensure following __attributes are preserved and that only a single +// alias is generated +#pragma weak mix2 = __mix2 +void __mix2(void) __attribute((noinline)); +void __mix2(void) __attribute((noinline)); +void __mix2(void) {} +// CHECK: define void @__mix2() + +////////////// test #pragma weak/__attribute combinations + +// if the SAME ALIAS is already declared then it overrides #pragma weak +// resulting in a non-weak alias in this case +void both(void) __attribute((alias("__both"))); +#pragma weak both = __both +void __both(void) {} +// CHECK: define void @__both() + +// if the TARGET is previously declared then whichever aliasing method +// comes first applies and subsequent aliases are discarded. +// TODO: warn about this + +void __both2(void); +void both2(void) __attribute((alias("__both2"))); // first, wins +#pragma weak both2 = __both2 +void __both2(void) {} +// CHECK: define void @__both2() + +void __both3(void); +#pragma weak both3 = __both3 // first, wins +void both3(void) __attribute((alias("__both3"))); +void __both3(void) {} +// CHECK: define void @__both3() + +///////////// ensure that #pragma weak does not alter existing __attributes() + +void __a1(void) __attribute((noinline)); +#pragma weak a1 = __a1 +void __a1(void) {} +// CHECK: define void @__a1() + +// attributes introduced BEFORE a combination of #pragma weak and alias() +// hold... +void __a3(void) __attribute((noinline)); +#pragma weak a3 = __a3 +void a3(void) __attribute((alias("__a3"))); +void __a3(void) {} +// CHECK: define void @__a3() + +#pragma weak xxx = __xxx +__attribute((pure,noinline,const,fastcall)) void __xxx(void) { } +// CHECK: void @__xxx() + +/// TODO: stuff that still doesn't work + +// due to the fact that disparate TopLevelDecls cannot affect each other +// (due to clang's Parser and ASTConsumer behavior, and quite reasonable) +// #pragma weak must appear before or within the same TopLevelDecl as it +// references. +void yyy(void){} +void zzz(void){} +#pragma weak yyy +// NOTE: weak doesn't apply, not before or in same TopLevelDec(!) +// CHECK: define void @yyy() + +int correct_linkage; diff --git a/test/CodeGen/predefined-expr.c b/test/CodeGen/predefined-expr.c new file mode 100644 index 000000000000..9b645931a4a7 --- /dev/null +++ b/test/CodeGen/predefined-expr.c @@ -0,0 +1,45 @@ +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s + +// CHECK: @__func__.plainFunction = private constant [14 x i8] c"plainFunction\00" +// CHECK: @__PRETTY_FUNCTION__.plainFunction = private constant [21 x i8] c"void plainFunction()\00" +// CHECK: @__func__.externFunction = private constant [15 x i8] c"externFunction\00" +// CHECK: @__PRETTY_FUNCTION__.externFunction = private constant [22 x i8] c"void externFunction()\00" +// CHECK: @__func__.privateExternFunction = private constant [22 x i8] c"privateExternFunction\00" +// CHECK: @__PRETTY_FUNCTION__.privateExternFunction = private constant [29 x i8] c"void privateExternFunction()\00" +// CHECK: @__func__.staticFunction = private constant [15 x i8] c"staticFunction\00" +// CHECK: @__PRETTY_FUNCTION__.staticFunction = private constant [22 x i8] c"void staticFunction()\00" + +#include <stdio.h> + +void plainFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); +} + +extern void externFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); +} + +__private_extern__ void privateExternFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); +} + +static void staticFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); +} + +int main() { + plainFunction(); + externFunction(); + privateExternFunction(); + staticFunction(); + + return 0; +} diff --git a/test/CodeGen/regparm.c b/test/CodeGen/regparm.c index fdf07ead6de7..28dfae7f628b 100644 --- a/test/CodeGen/regparm.c +++ b/test/CodeGen/regparm.c @@ -9,11 +9,10 @@ typedef struct { } foo; static void FASTCALL -reduced(char b, double c, foo* d, double e, int f) -{ +reduced(char b, double c, foo* d, double e, int f) { } int main(void) { - reduced(0, 0.0, 0, 0.0, 0); + reduced(0, 0.0, 0, 0.0, 0); } diff --git a/test/CodeGen/stack-protector.c b/test/CodeGen/stack-protector.c index bdac853aed62..0b5924d81112 100644 --- a/test/CodeGen/stack-protector.c +++ b/test/CodeGen/stack-protector.c @@ -12,8 +12,7 @@ // RUN: not grep 'ssp' %t && // RUN: true -#include <stdio.h> -#include <string.h> +int printf(const char * _Format, ...); void test1(const char *msg) { char a[strlen(msg) + 1]; diff --git a/test/CodeGen/statements.c b/test/CodeGen/statements.c index 1ff7601adf68..45bbd9ac024f 100644 --- a/test/CodeGen/statements.c +++ b/test/CodeGen/statements.c @@ -11,3 +11,25 @@ bar(); int test2() { return; } void test3() { return 4; } + +void test4() { +bar: +baz: +blong: +bing: + ; + +// PR5131 +static long x = &&bar - &&baz; +static long y = &&baz; + &&bing; + &&blong; + if (y) + goto *y; + + goto *x; +} + +// PR3869 +int test5(long long b) { goto *b; } + diff --git a/test/CodeGen/staticinit.c b/test/CodeGen/staticinit.c index 91fcdcf69f00..c68366f2ea77 100644 --- a/test/CodeGen/staticinit.c +++ b/test/CodeGen/staticinit.c @@ -2,9 +2,9 @@ // RUN: grep "g.b = internal global i8. getelementptr" %t && struct AStruct { - int i; - char *s; - double d; + int i; + char *s; + double d; }; void f() { diff --git a/test/CodeGen/stdcall-fastcall.c b/test/CodeGen/stdcall-fastcall.c index 11b652178ca8..89ed8c9ef672 100644 --- a/test/CodeGen/stdcall-fastcall.c +++ b/test/CodeGen/stdcall-fastcall.c @@ -1,4 +1,4 @@ -// RUN: clang-cc -emit-llvm < %s | grep 'fastcallcc' | count 4 +// RUN: clang-cc -emit-llvm < %s | grep 'fastcallcc' | count 4 && // RUN: clang-cc -emit-llvm < %s | grep 'stdcallcc' | count 4 void __attribute__((fastcall)) f1(void); diff --git a/test/CodeGen/string-init.c b/test/CodeGen/string-init.c index 38c7ec057597..4a808512601e 100644 --- a/test/CodeGen/string-init.c +++ b/test/CodeGen/string-init.c @@ -1,5 +1,5 @@ // RUN: clang-cc -emit-llvm %s -o %t && -// RUN: grep 'internal constant \[10 x i8\]' %t && +// RUN: grep 'private constant \[10 x i8\]' %t && // RUN: not grep -F "[5 x i8]" %t && // RUN: not grep "store " %t diff --git a/test/CodeGen/struct-init.c b/test/CodeGen/struct-init.c index a38442b1a88f..cb84fef4d1c1 100644 --- a/test/CodeGen/struct-init.c +++ b/test/CodeGen/struct-init.c @@ -2,11 +2,11 @@ typedef struct _zend_ini_entry zend_ini_entry; struct _zend_ini_entry { - void *mh_arg1; + void *mh_arg1; }; char a; const zend_ini_entry ini_entries[] = { - { ((char*)&((zend_ini_entry*)0)->mh_arg1 - (char*)(void*)0)}, + { ((char*)&((zend_ini_entry*)0)->mh_arg1 - (char*)(void*)0)}, }; diff --git a/test/CodeGen/struct-x86-darwin.c b/test/CodeGen/struct-x86-darwin.c index 050e26dcab9e..c61005f1bebd 100644 --- a/test/CodeGen/struct-x86-darwin.c +++ b/test/CodeGen/struct-x86-darwin.c @@ -1,13 +1,13 @@ -// RUN: clang-cc < %s -emit-llvm > %t1 -triple=i686-apple-darwin9 -// Run grep "STest1 = type <{ i32, \[4 x i16\], double }>" %t1 && -// RUN: grep "STest2 = type <{ i16, i16, i32, i32 }>" %t1 && -// RUN: grep "STest3 = type <{ i8, i8, i16, i32 }>" %t1 && -// RUN: grep "STestB1 = type <{ i8, i8 }>" %t1 && -// RUN: grep "STestB2 = type <{ i8, i8, i8 }>" %t1 && -// RUN: grep "STestB3 = type <{ i8, i8 }>" %t1 && -// RUN: grep "STestB4 = type <{ i8, i8, i8, i8 }>" %t1 && -// RUN: grep "STestB5 = type <{ i8, i8, i8, i8, i8, i8 }>" %t1 && -// RUN: grep "STestB6 = type <{ i8, i8, i8, i8 }>" %t1 +// RUN: clang-cc < %s -emit-llvm > %t1 -triple=i686-apple-darwin9 && +// RUN: grep "STest1 = type { i32, \[4 x i16\], double }" %t1 && +// RUN: grep "STest2 = type { i16, i16, i32, i32 }" %t1 && +// RUN: grep "STest3 = type { i8, i16, i32 }" %t1 && +// RUN: grep "STestB1 = type { i8, i8 }" %t1 && +// RUN: grep "STestB2 = type { i8, i8, i8 }" %t1 && +// RUN: grep "STestB3 = type { i8, i8 }" %t1 && +// RUN: grep "STestB4 = type { i8, i8, i8, i8 }" %t1 && +// RUN: grep "STestB5 = type { i8, i8, \[2 x i8\], i8, i8 }" %t1 && +// RUN: grep "STestB6 = type { i8, i8, \[2 x i8\] }" %t1 // Test struct layout for x86-darwin target struct STest1 {int x; short y[4]; double z; } st1; diff --git a/test/CodeGen/struct.c b/test/CodeGen/struct.c index ed3684280e88..d1e58a244561 100644 --- a/test/CodeGen/struct.c +++ b/test/CodeGen/struct.c @@ -70,8 +70,7 @@ typedef struct { int length; } range; extern range f6(); -void f7() -{ +void f7() { range r = f6(); } @@ -81,27 +80,23 @@ typedef struct { range range2; } rangepair; -void f8() -{ +void f8() { rangepair p; range r = p.range1; } -void f9(range *p) -{ +void f9(range *p) { range r = *p; } -void f10(range *p) -{ +void f10(range *p) { range r = p[0]; } /* _Bool types */ -struct _w -{ +struct _w { short a,b; short c,d; short e,f; @@ -113,27 +108,24 @@ struct _w } ws; /* Implicit casts (due to typedefs) */ -typedef struct _a -{ +typedef struct _a { int a; } a; -void f11() -{ - struct _a a1; - a a2; +void f11() { + struct _a a1; + a a2; - a1 = a2; - a2 = a1; + a1 = a2; + a2 = a1; } /* Implicit casts (due to const) */ -void f12() -{ - struct _a a1; - const struct _a a2; - - a1 = a2; +void f12() { + struct _a a1; + const struct _a a2; + + a1 = a2; } /* struct initialization */ @@ -147,8 +139,7 @@ struct a15 {char a; int b[];} c15; int a16(void) {c15.a = 1;} /* compound literals */ -void f13() -{ +void f13() { a13 x; x = (a13){1,2}; } diff --git a/test/CodeGen/union-init.c b/test/CodeGen/union-init.c index c882d3180c72..f4e9e9a08f4d 100644 --- a/test/CodeGen/union-init.c +++ b/test/CodeGen/union-init.c @@ -4,19 +4,19 @@ typedef int Py_ssize_t; typedef union _gc_head { - struct { - union _gc_head *gc_next; - union _gc_head *gc_prev; - Py_ssize_t gc_refs; - } gc; - long double dummy; /* force worst-case alignment */ + struct { + union _gc_head *gc_next; + union _gc_head *gc_prev; + Py_ssize_t gc_refs; + } gc; + long double dummy; /* force worst-case alignment */ } PyGC_Head; struct gc_generation { - PyGC_Head head; - int threshold; /* collection threshold */ - int count; /* count of allocations or collections of younger - generations */ + PyGC_Head head; + int threshold; /* collection threshold */ + int count; /* count of allocations or collections of younger + generations */ }; #define NUM_GENERATIONS 3 @@ -24,8 +24,8 @@ struct gc_generation { /* linked lists of container objects */ struct gc_generation generations[NUM_GENERATIONS] = { - /* PyGC_Head, threshold, count */ - {{{GEN_HEAD(0), GEN_HEAD(0), 0}}, 700, 0}, - {{{GEN_HEAD(1), GEN_HEAD(1), 0}}, 10, 0}, - {{{GEN_HEAD(2), GEN_HEAD(2), 0}}, 10, 0}, + /* PyGC_Head, threshold, count */ + {{{GEN_HEAD(0), GEN_HEAD(0), 0}}, 700, 0}, + {{{GEN_HEAD(1), GEN_HEAD(1), 0}}, 10, 0}, + {{{GEN_HEAD(2), GEN_HEAD(2), 0}}, 10, 0}, }; diff --git a/test/CodeGen/union-init2.c b/test/CodeGen/union-init2.c new file mode 100644 index 000000000000..184d75f47156 --- /dev/null +++ b/test/CodeGen/union-init2.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -emit-llvm %s -o - -triple i686-pc-linux-gnu | grep "bitcast (%0\* @r to %union.x\*), \[4 x i8\] zeroinitializer" + +// Make sure we generate something sane instead of a ptrtoint +union x {long long b;union x* a;} r = {.a = &r}; diff --git a/test/CodeGen/unreachable.c b/test/CodeGen/unreachable.c new file mode 100644 index 000000000000..ea4f0478bbd4 --- /dev/null +++ b/test/CodeGen/unreachable.c @@ -0,0 +1,37 @@ +// RUN: clang-cc -emit-llvm -o %t %s && +// RUN: grep '@unreachable' %t | count 0 + +extern void abort() __attribute__((noreturn)); +extern int unreachable(); + +int f0() { + return 0; + unreachable(); +} + +int f1(int i) { + goto L0; + int a = unreachable(); + L0: + return 0; +} + +int f2(int i) { + goto L0; + unreachable(); + int a; + unreachable(); + L0: + a = i + 1; + return a; +} + +int f3(int i) { + if (i) { + return 0; + } else { + abort(); + } + unreachable(); + return 3; +} diff --git a/test/CodeGen/unwind-attr.c b/test/CodeGen/unwind-attr.c index 4954a0b59ce4..86036f94b981 100644 --- a/test/CodeGen/unwind-attr.c +++ b/test/CodeGen/unwind-attr.c @@ -2,4 +2,5 @@ // RUN: clang-cc -emit-llvm -o - %s | grep "@foo()" | grep nounwind int foo(void) { + return 0; } diff --git a/test/CodeGen/vector.c b/test/CodeGen/vector.c index 1084f6d20b9b..5e48fd42b1d0 100644 --- a/test/CodeGen/vector.c +++ b/test/CodeGen/vector.c @@ -1,9 +1,8 @@ // RUN: clang-cc -emit-llvm %s -o - typedef short __v4hi __attribute__ ((__vector_size__ (8))); -void f() -{ - __v4hi A = (__v4hi)0LL; +void f() { + __v4hi A = (__v4hi)0LL; } __v4hi x = {1,2,3}; @@ -15,7 +14,6 @@ int a() { vty b; return b[2LL]; } // PR4339 typedef float vec4 __attribute__((vector_size(16))); -void vac ( vec4* a, char b, float c ) -{ - (*a)[b] = c; +void vac ( vec4* a, char b, float c ) { + (*a)[b] = c; } diff --git a/test/CodeGen/visibility.c b/test/CodeGen/visibility.c index bb9b6e0d50ce..958eb618ee70 100644 --- a/test/CodeGen/visibility.c +++ b/test/CodeGen/visibility.c @@ -15,7 +15,7 @@ // RUN: grep 'define internal void @f_deferred()' %t && // RUN: grep 'define protected i32 @f_def()' %t && // RUN: clang-cc -triple i386-unknown-unknown -fvisibility=hidden -emit-llvm -o %t %s && -// RUN: grep '@g_com = common hidden global i32 0' %t &&a +// RUN: grep '@g_com = common hidden global i32 0' %t && // RUN: grep '@g_def = hidden global i32 0' %t && // RUN: grep '@g_ext = external global i32' %t && // RUN: grep '@g_deferred = internal global' %t && diff --git a/test/CodeGen/volatile.c b/test/CodeGen/volatile.c index 212a0aeb1e35..87cb5ff4eb4f 100644 --- a/test/CodeGen/volatile.c +++ b/test/CodeGen/volatile.c @@ -38,7 +38,7 @@ volatile extv4 vVE; volatile struct {int x;} aggFct(void); -void main() { +int main() { int i; // load diff --git a/test/CodeGen/x86.c b/test/CodeGen/x86.c index 66d82513795b..be0930237c82 100644 --- a/test/CodeGen/x86.c +++ b/test/CodeGen/x86.c @@ -1,4 +1,4 @@ -// RUN: clang-cc %s -triple=i686-pc-linux-gnu -emit-llvm -o - > %t1 +// RUN: clang-cc %s -triple=i686-pc-linux-gnu -emit-llvm -o - > %t1 && // RUN: grep "ax" %t1 && // RUN: grep "bx" %t1 && // RUN: grep "cx" %t1 && diff --git a/test/CodeGen/x86_32-arguments.c b/test/CodeGen/x86_32-arguments.c index 43a3ab246c71..78fb8342eebd 100644 --- a/test/CodeGen/x86_32-arguments.c +++ b/test/CodeGen/x86_32-arguments.c @@ -1,4 +1,4 @@ -// RUN: clang-cc -triple i386-apple-darwin9 -emit-llvm -o %t %s && +// RUN: clang-cc -fblocks -triple i386-apple-darwin9 -emit-llvm -o %t %s && // RUN: grep 'define signext i8 @f0()' %t && // RUN: grep 'define signext i16 @f1()' %t && // RUN: grep 'define i32 @f2()' %t && @@ -11,39 +11,41 @@ // RUN: grep 'define void @f8_2(i32 %a0.0, i32 %a0.1)' %t && char f0(void) { + return 0; } short f1(void) { + return 0; } int f2(void) { + return 0; } float f3(void) { + return 0; } double f4(void) { + return 0; } long double f5(void) { + return 0; } -void f6(char a0, short a1, int a2, long long a3, void *a4) { -} +void f6(char a0, short a1, int a2, long long a3, void *a4) {} typedef enum { A, B, C } E; -void f7(E a0) { -} +void f7(E a0) {} struct s8 { int a; int b; }; -struct s8 f8_1(void) { -} -void f8_2(struct s8 a0) { -} +struct s8 f8_1(void) { while (1) {} } +void f8_2(struct s8 a0) {} // This should be passed just as s8. @@ -56,10 +58,8 @@ struct s9 { int a : 17; int b; }; -struct s9 f9_1(void) { -} -void f9_2(struct s9 a0) { -} +struct s9 f9_1(void) { while (1) {} } +void f9_2(struct s9 a0) {} // Return of small structures and unions @@ -67,7 +67,7 @@ void f9_2(struct s9 a0) { struct s10 { union { }; float f; -} f10(void) {} +} f10(void) { while (1) {} } // Small vectors and 1 x {i64,double} are returned in registers @@ -78,17 +78,17 @@ struct s10 { // RUN: grep '<2 x i64> @f15()' %t && // RUN: grep '<2 x i64> @f16()' %t && typedef short T11 __attribute__ ((vector_size (4))); -T11 f11(void) {} +T11 f11(void) { while (1) {} } typedef int T12 __attribute__ ((vector_size (8))); -T12 f12(void) {} +T12 f12(void) { while (1) {} } typedef long long T13 __attribute__ ((vector_size (8))); -T13 f13(void) {} +T13 f13(void) { while (1) {} } typedef double T14 __attribute__ ((vector_size (8))); -T14 f14(void) {} +T14 f14(void) { while (1) {} } typedef long long T15 __attribute__ ((vector_size (16))); -T15 f15(void) {} +T15 f15(void) { while (1) {} } typedef double T16 __attribute__ ((vector_size (16))); -T16 f16(void) {} +T16 f16(void) { while (1) {} } // And when the single element in a struct (but not for 64 and // 128-bits). @@ -99,64 +99,107 @@ T16 f16(void) {} // RUN: grep -F 'void @f20(%4* noalias sret %agg.result)' %t && // RUN: grep -F 'void @f21(%5* noalias sret %agg.result)' %t && // RUN: grep -F 'void @f22(%6* noalias sret %agg.result)' %t && -struct { T11 a; } f17(void) {} -struct { T12 a; } f18(void) {} -struct { T13 a; } f19(void) {} -struct { T14 a; } f20(void) {} -struct { T15 a; } f21(void) {} -struct { T16 a; } f22(void) {} +struct { T11 a; } f17(void) { while (1) {} } +struct { T12 a; } f18(void) { while (1) {} } +struct { T13 a; } f19(void) { while (1) {} } +struct { T14 a; } f20(void) { while (1) {} } +struct { T15 a; } f21(void) { while (1) {} } +struct { T16 a; } f22(void) { while (1) {} } // Single element structures are handled specially // RUN: grep -F 'float @f23()' %t && // RUN: grep -F 'float @f24()' %t && // RUN: grep -F 'float @f25()' %t && -struct { float a; } f23(void) {} -struct { float a[1]; } f24(void) {} -struct { struct {} a; struct { float a[1]; } b; } f25(void) {} +struct { float a; } f23(void) { while (1) {} } +struct { float a[1]; } f24(void) { while (1) {} } +struct { struct {} a; struct { float a[1]; } b; } f25(void) { while (1) {} } // Small structures are handled recursively // RUN: grep -F 'i32 @f26()' %t && // RUN: grep 'void @f27(%.truct.s27\* noalias sret %agg.result)' %t && -struct s26 { struct { char a, b; } a; struct { char a, b; } b; } f26(void) {} -struct s27 { struct { char a, b, c; } a; struct { char a; } b; } f27(void) {} +struct s26 { struct { char a, b; } a; struct { char a, b; } b; } f26(void) { while (1) {} } +struct s27 { struct { char a, b, c; } a; struct { char a; } b; } f27(void) { while (1) {} } // RUN: grep 'void @f28(%.truct.s28\* noalias sret %agg.result)' %t && -struct s28 { int a; int b[]; } f28(void) {} +struct s28 { int a; int b[]; } f28(void) { while (1) {} } // RUN: grep 'define i16 @f29()' %t && -struct s29 { struct { } a[1]; char b; char c; } f29(void) {} +struct s29 { struct { } a[1]; char b; char c; } f29(void) { while (1) {} } // RUN: grep 'define i16 @f30()' %t && -struct s30 { char a; char b : 4; } f30(void) {} +struct s30 { char a; char b : 4; } f30(void) { while (1) {} } // RUN: grep 'define float @f31()' %t && -struct s31 { char : 0; float b; char : 0; } f31(void) {} +struct s31 { char : 0; float b; char : 0; } f31(void) { while (1) {} } // RUN: grep 'define i32 @f32()' %t && -struct s32 { char a; unsigned : 0; } f32(void) {} +struct s32 { char a; unsigned : 0; } f32(void) { while (1) {} } // RUN: grep 'define float @f33()' %t && -struct s33 { float a; long long : 0; } f33(void) {} +struct s33 { float a; long long : 0; } f33(void) { while (1) {} } // RUN: grep 'define float @f34()' %t && -struct s34 { struct { int : 0; } a; float b; } f34(void) {} +struct s34 { struct { int : 0; } a; float b; } f34(void) { while (1) {} } // RUN: grep 'define i16 @f35()' %t && -struct s35 { struct { int : 0; } a; char b; char c; } f35(void) {} +struct s35 { struct { int : 0; } a; char b; char c; } f35(void) { while (1) {} } // RUN: grep 'define i16 @f36()' %t && -struct s36 { struct { int : 0; } a[2][10]; char b; char c; } f36(void) {} +struct s36 { struct { int : 0; } a[2][10]; char b; char c; } f36(void) { while (1) {} } // RUN: grep 'define float @f37()' %t && -struct s37 { float c[1][1]; } f37(void) {} +struct s37 { float c[1][1]; } f37(void) { while (1) {} } // RUN: grep 'define void @f38(.struct.s38. noalias sret .agg.result)' %t && -struct s38 { char a[3]; short b; } f38(void) {} +struct s38 { char a[3]; short b; } f38(void) { while (1) {} } // RUN: grep 'define void @f39(.struct.s39. byval align 16 .x)' %t && typedef int v39 __attribute((vector_size(16))); struct s39 { v39 x; }; void f39(struct s39 x) {} +// <rdar://problem/7247671> +// RUN: grep 'define i32 @f40()' %t && +enum e40 { ec0 = 0 }; +enum e40 f40(void) { } + +// RUN: grep 'define void ()\* @f41()' %t && +typedef void (^vvbp)(void); +vvbp f41(void) { } + +// RUN: grep 'define i32 @f42()' %t && +struct s42 { enum e40 f0; } f42(void) { } + +// RUN: grep 'define i64 @f43()' %t && +struct s43 { enum e40 f0; int f1; } f43(void) { } + +// RUN: grep 'define i32 @f44()' %t && +struct s44 { vvbp f0; } f44(void) { } + +// RUN: grep 'define i64 @f45()' %t && +struct s45 { vvbp f0; int f1; } f45(void) { } + +// RUN: grep 'define void @f46(i32 %a0)' %t && +void f46(enum e40 a0) { } + +// RUN: grep 'define void @f47(void ()\* %a1)' %t && +void f47(vvbp a1) { } + +// RUN: grep 'define void @f48(i32 %a0.0)' %t && +struct s48 { enum e40 f0; }; +void f48(struct s48 a0) { } + +// RUN: grep 'define void @f49(i32 %a0.0, i32 %a0.1)' %t && +struct s49 { enum e40 f0; int f1; }; +void f49(struct s49 a0) { } + +// RUN: grep 'define void @f50(void ()\* %a0.0)' %t && +struct s50 { vvbp f0; }; +void f50(struct s50 a0) { } + +// RUN: grep 'define void @f51(void ()\* %a0.0, i32 %a0.1)' %t && +struct s51 { vvbp f0; int f1; }; +void f51(struct s51 a0) { } + // RUN: true diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c index 0b68afdb4edd..19f9cdaa2918 100644 --- a/test/CodeGen/x86_64-arguments.c +++ b/test/CodeGen/x86_64-arguments.c @@ -7,26 +7,32 @@ // RUN: grep 'define x86_fp80 @f5()' %t && // RUN: grep 'define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8\* %a4)' %t && // RUN: grep 'define void @f7(i32 %a0)' %t && -// RUN: grep 'type { i64, double }.*type .0' %t && +// RUN: grep '.0 = type { i64, double }' %t && // RUN: grep 'define .0 @f8_1()' %t && // RUN: grep 'define void @f8_2(.0)' %t && char f0(void) { + return 0; } short f1(void) { + return 0; } int f2(void) { + return 0; } float f3(void) { + return 0; } double f4(void) { + return 0; } long double f5(void) { + return 0; } void f6(char a0, short a1, int a2, long long a3, void *a4) { @@ -42,23 +48,23 @@ union u8 { long double a; int b; }; -union u8 f8_1() {} +union u8 f8_1() { while (1) {} } void f8_2(union u8 a0) {} // RUN: grep 'define i64 @f9()' %t && -struct s9 { int a; int b; int : 0; } f9(void) {} +struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} } // RUN: grep 'define void @f10(i64)' %t && struct s10 { int a; int b; int : 0; }; void f10(struct s10 a0) {} // RUN: grep 'define void @f11(.union.anon. noalias sret .agg.result)' %t && -union { long double a; float b; } f11() {} +union { long double a; float b; } f11() { while (1) {} } // RUN: grep 'define i64 @f12_0()' %t && // RUN: grep 'define void @f12_1(i64)' %t && struct s12 { int a __attribute__((aligned(16))); }; -struct s12 f12_0(void) {} +struct s12 f12_0(void) { while (1) {} } void f12_1(struct s12 a0) {} // Check that sret parameter is accounted for when checking available integer @@ -66,8 +72,9 @@ void f12_1(struct s12 a0) {} // RUN: grep 'define void @f13(.struct.s13_0. noalias sret .agg.result, i32 .a, i32 .b, i32 .c, i32 .d, .struct.s13_1. byval .e, i32 .f)' %t && struct s13_0 { long long f0[3]; }; +struct s13_1 { long long f0[2]; }; struct s13_0 f13(int a, int b, int c, int d, - struct s13_1 { long long f0[2]; } e, int f) {} + struct s13_1 e, int f) { while (1) {} } // RUN: grep 'define void @f14(.*, i8 signext .X)' %t && void f14(int a, int b, int c, int d, int e, int f, @@ -83,9 +90,10 @@ void f17(float a, float b, float c, float d, float e, float f, float g, float h, long double X) {} // Check for valid coercion. -// RUN: grep '.1 = bitcast i64. .tmp to .struct.f18_s0.' %t && -// RUN: grep '.2 = load .struct.f18_s0. .1, align 1' %t && -// RUN: grep 'store .struct.f18_s0 .2, .struct.f18_s0. .f18_arg1' %t && -void f18(int a, struct f18_s0 { int f0; } f18_arg1) {} +// RUN: grep '.. = bitcast i64. .* to .struct.f18_s0.' %t && +// RUN: grep '.. = load .struct.f18_s0. .., align 1' %t && +// RUN: grep 'store .struct.f18_s0 .., .struct.f18_s0. .f18_arg1' %t && +struct f18_s0 { int f0; }; +void f18(int a, struct f18_s0 f18_arg1) { while (1) {} } // RUN: true diff --git a/test/CodeGenCXX/PR4827-cast.cpp b/test/CodeGenCXX/PR4827-cast.cpp new file mode 100644 index 000000000000..958798d77f60 --- /dev/null +++ b/test/CodeGenCXX/PR4827-cast.cpp @@ -0,0 +1,5 @@ +// RUN: clang-cc -emit-llvm -o - %s +struct A; +struct B; +extern A *f(); +void a() { (B *) f(); } diff --git a/test/CodeGenCXX/PR4890-debug-info-dtor.cpp b/test/CodeGenCXX/PR4890-debug-info-dtor.cpp new file mode 100644 index 000000000000..a0d3a8ddac23 --- /dev/null +++ b/test/CodeGenCXX/PR4890-debug-info-dtor.cpp @@ -0,0 +1,6 @@ +// RUN: clang-cc -emit-llvm-only -g %s +struct X { + ~X(); +}; + +X::~X() { } diff --git a/test/CodeGenCXX/PR4983-constructor-conversion.cpp b/test/CodeGenCXX/PR4983-constructor-conversion.cpp new file mode 100644 index 000000000000..31eae2e791f6 --- /dev/null +++ b/test/CodeGenCXX/PR4983-constructor-conversion.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -emit-llvm-only %s + +struct A { + A(const char *s){} +}; + +struct B { + A a; + + B() : a("test") { } +}; + +void f() { + A a("test"); +} + diff --git a/test/CodeGenCXX/PR5050-constructor-conversion.cpp b/test/CodeGenCXX/PR5050-constructor-conversion.cpp new file mode 100644 index 000000000000..e5f722c513de --- /dev/null +++ b/test/CodeGenCXX/PR5050-constructor-conversion.cpp @@ -0,0 +1,19 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +struct A { A(const A&, int i1 = 1); }; + +struct B : A { }; + +A f(const B &b) { + return b; +} + +// CHECK-LP64: call __ZN1AC1ERKS_i + +// CHECK-LP32: call L__ZN1AC1ERKS_i + + diff --git a/test/CodeGenCXX/PR5093-static-member-function.cpp b/test/CodeGenCXX/PR5093-static-member-function.cpp new file mode 100644 index 000000000000..a27b08f6ada7 --- /dev/null +++ b/test/CodeGenCXX/PR5093-static-member-function.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s +struct a { + static void f(); +}; + +void g(a *a) { + // CHECK: call void @_ZN1a1fEv() + a->f(); +} diff --git a/test/CodeGenCXX/anonymous-namespaces.cpp b/test/CodeGenCXX/anonymous-namespaces.cpp new file mode 100644 index 000000000000..dcfd518d684b --- /dev/null +++ b/test/CodeGenCXX/anonymous-namespaces.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s + +namespace { + // CHECK: @_ZN12_GLOBAL__N_11aE = internal global i32 0 + int a = 0; + + // CHECK: define internal i32 @_ZN12_GLOBAL__N_13fooEv() + int foo() { + return 32; + } + + // CHECK: define internal i32 @_ZN12_GLOBAL__N_11A3fooEv() + namespace A { + int foo() { + return 45; + } + } +} + +int concrete() { + return a + foo() + A::foo(); +} diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp new file mode 100644 index 000000000000..2030f4053c90 --- /dev/null +++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc -emit-llvm -o - %s + +struct A { + union { + int a; + void* b; + }; + + A() : a(0) { } +}; + +A a; diff --git a/test/CodeGenCXX/array-pointer-decay.cpp b/test/CodeGenCXX/array-pointer-decay.cpp new file mode 100644 index 000000000000..5751b67b7491 --- /dev/null +++ b/test/CodeGenCXX/array-pointer-decay.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc %s -emit-llvm -o - + +void f(const char*); + +void g() { + f("hello"); +} diff --git a/test/CodeGenCXX/attr.cpp b/test/CodeGenCXX/attr.cpp new file mode 100644 index 000000000000..8077b7839d88 --- /dev/null +++ b/test/CodeGenCXX/attr.cpp @@ -0,0 +1,36 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -O0 -S %s -o %t.s && +// RUN: FileCheck --input-file=%t.s %s + +int foo() __attribute__((aligned(1024))); +int foo() { } + +// CHECK:.align 10, 0x90 +// CHECK:.globl __Z3foov +// CHECK:__Z3foov: + + +class C { + virtual void bar1() __attribute__((aligned(1))); + virtual void bar2() __attribute__((aligned(2))); + virtual void bar3() __attribute__((aligned(1024))); +} c; + +void C::bar1() { } + +// CHECK:.align 1, 0x90 +// CHECK-NEXT:.globl __ZN1C4bar1Ev +// CHECK-NEXT:__ZN1C4bar1Ev: + + +void C::bar2() { } + +// CHECK:.align 1, 0x90 +// CHECK-NEXT:.globl __ZN1C4bar2Ev +// CHECK-NEXT:__ZN1C4bar2Ev: + + +void C::bar3() { } + +// CHECK:.align 10, 0x90 +// CHECK-NEXT:.globl __ZN1C4bar3Ev +// CHECK-NEXT:__ZN1C4bar3Ev: diff --git a/test/CodeGenCXX/cast-conversion.cpp b/test/CodeGenCXX/cast-conversion.cpp new file mode 100644 index 000000000000..f571f549d094 --- /dev/null +++ b/test/CodeGenCXX/cast-conversion.cpp @@ -0,0 +1,33 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +struct A { + A(int); +}; + +struct B { + B(A); +}; + +int main () { + (B)10; + B(10); + static_cast<B>(10); +} + +// CHECK-LP64: call __ZN1AC1Ei +// CHECK-LP64: call __ZN1BC1E1A +// CHECK-LP64: call __ZN1AC1Ei +// CHECK-LP64: call __ZN1BC1E1A +// CHECK-LP64: call __ZN1AC1Ei +// CHECK-LP64: call __ZN1BC1E1A + +// CHECK-LP32: call L__ZN1AC1Ei +// CHECK-LP32: call L__ZN1BC1E1A +// CHECK-LP32: call L__ZN1AC1Ei +// CHECK-LP32: call L__ZN1BC1E1A +// CHECK-LP32: call L__ZN1AC1Ei +// CHECK-LP32: call L__ZN1BC1E1A diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp new file mode 100644 index 000000000000..7255d3e4f94d --- /dev/null +++ b/test/CodeGenCXX/class-layout.cpp @@ -0,0 +1,5 @@ +// RUN: clang-cc %s -emit-llvm -o %t && + +// An extra byte shoudl be allocated for an empty class. +// RUN: grep '%.truct.A = type { i8 }' %t +struct A { } a; diff --git a/test/CodeGenCXX/conditional-expr-lvalue.cpp b/test/CodeGenCXX/conditional-expr-lvalue.cpp new file mode 100644 index 000000000000..7b3233a5bed0 --- /dev/null +++ b/test/CodeGenCXX/conditional-expr-lvalue.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -emit-llvm-only %s +void f(bool flag) { + int a = 1; + int b = 2; + + (flag ? a : b) = 3; +} diff --git a/test/CodeGenCXX/constructor-conversion.cpp b/test/CodeGenCXX/constructor-conversion.cpp new file mode 100644 index 000000000000..980b230118d8 --- /dev/null +++ b/test/CodeGenCXX/constructor-conversion.cpp @@ -0,0 +1,55 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +extern "C" int printf(...); + +class X { // ... +public: + X(int) : iX(2), fX(2.3) , name("HELLO\n") { } + + X(const char* arg, int ix=0) { iX = ix; fX = 6.0; name = arg+ix; } + X(): iX(100), fX(1.2) {} + int iX; + float fX; + const char *name; + void pr(void) { + printf("iX = %d fX = %f name = %s\n", iX, fX, name); + } +}; + +void g(X arg) { + arg.pr(); +} + +void f(X arg) { + X a = 1; // a = X(1) + + a.pr(); + + X b = "Jessie"; // b=X("Jessie",0) + + b.pr(); + + + a = 2; // a = X(2) + + a.pr(); +} + + +int main() { + X x; + f(x); + g(3); // g(X(3)) +} + +// CHECK-LP64: call __ZN1XC1Ei +// CHECK-LP64: call __ZN1XC1EPKci +// CHECK-LP64: call __ZN1XC1Ev + +// CHECK-LP32: call L__ZN1XC1Ei +// CHECK-LP32: call L__ZN1XC1EPKci +// CHECK-LP32: call L__ZN1XC1Ev diff --git a/test/CodeGenCXX/constructor-default-arg.cpp b/test/CodeGenCXX/constructor-default-arg.cpp new file mode 100644 index 000000000000..7e6a7cd8f71a --- /dev/null +++ b/test/CodeGenCXX/constructor-default-arg.cpp @@ -0,0 +1,40 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +extern "C" int printf(...); + + +struct C { + C() : iC(6) {} + int iC; +}; + +int foo() { + return 6; +}; + +class X { // ... +public: + X(int) {} + X(const X&, int i = 1, int j = 2, int k = foo()) { + printf("X(const X&, %d, %d, %d)\n", i, j, k); + } +}; + +int main() { + X a(1); + X b(a, 2); + X c = b; + X d(a, 5, 6); +} + +// CHECK-LP64: call __ZN1XC1ERKS_iii +// CHECK-LP64: call __ZN1XC1ERKS_iii +// CHECK-LP64: call __ZN1XC1ERKS_iii + +// CHECK-LP32: call L__ZN1XC1ERKS_iii +// CHECK-LP32: call L__ZN1XC1ERKS_iii +// CHECK-LP32: call L__ZN1XC1ERKS_iii diff --git a/test/CodeGenCXX/constructor-for-array-members.cpp b/test/CodeGenCXX/constructor-for-array-members.cpp new file mode 100644 index 000000000000..fbb13e0aa3c2 --- /dev/null +++ b/test/CodeGenCXX/constructor-for-array-members.cpp @@ -0,0 +1,44 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +extern "C" int printf(...); + +int i = 1234; +float vf = 1.00; + +struct S { + S() : iS(i++), f1(vf++) {printf("S::S()\n");} + ~S(){printf("S::~S(iS = %d f1 = %f)\n", iS, f1); } + int iS; + float f1; +}; + +struct M { + double dM; + S ARR_S[3]; + void pr() { + for (int i = 0; i < 3; i++) + printf("ARR_S[%d].iS = %d ARR_S[%d].f1 = %f\n", i, ARR_S[i].iS, i, ARR_S[i].f1); + + for (int i = 0; i < 2; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 4; k++) + printf("MULTI_ARR[%d][%d][%d].iS = %d MULTI_ARR[%d][%d][%d].f1 = %f\n", + i,j,k, MULTI_ARR[i][j][k].iS, i,j,k, MULTI_ARR[i][j][k].f1); + + } + + S MULTI_ARR[2][3][4]; +}; + +int main() { + M m1; + m1.pr(); +} + +// CHECK-LP64: call __ZN1SC1Ev + +// CHECK-LP32: call L__ZN1SC1Ev diff --git a/test/CodeGenCXX/constructor-init-reference.cpp b/test/CodeGenCXX/constructor-init-reference.cpp new file mode 100644 index 000000000000..040441fde0f8 --- /dev/null +++ b/test/CodeGenCXX/constructor-init-reference.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc -emit-llvm -o - %s | grep "store i32\* @x, i32\*\*" + +int x; +class A { + int& y; + A() : y(x) {} +}; +A z; + diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp new file mode 100644 index 000000000000..1b025126a345 --- /dev/null +++ b/test/CodeGenCXX/constructor-init.cpp @@ -0,0 +1,61 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +extern "C" int printf(...); + +struct M { + M() { printf("M()\n"); } + M(int i) { iM = i; printf("M(%d)\n", i); } + int iM; + void MPR() {printf("iM = %d\n", iM); }; +}; + +struct P { + P() { printf("P()\n"); } + P(int i) { iP = i; printf("P(%d)\n", i); } + int iP; + void PPR() {printf("iP = %d\n", iP); }; +}; + +struct Q { + Q() { printf("Q()\n"); } + Q(int i) { iQ = i; printf("Q(%d)\n", i); } + int iQ; + void QPR() {printf("iQ = %d\n", iQ); }; +}; + +struct N : M , P, Q { + N() : f1(1.314), P(2000), ld(00.1234+f1), M(1000), Q(3000), + d1(3.4567), i1(1234), m1(100) { printf("N()\n"); } + M m1; + M m2; + float f1; + int i1; + float d1; + void PR() { + printf("f1 = %f d1 = %f i1 = %d ld = %f \n", f1,d1,i1, ld); + MPR(); + PPR(); + QPR(); + printf("iQ = %d\n", iQ); + printf("iP = %d\n", iP); + printf("iM = %d\n", iM); + // FIXME. We don't yet support this syntax. + // printf("iQ = %d\n", (*this).iQ); + printf("iQ = %d\n", this->iQ); + printf("iP = %d\n", this->iP); + printf("iM = %d\n", this->iM); + } + float ld; + float ff; + M arr_m[3]; + P arr_p[1][3]; + Q arr_q[2][3][4]; +}; + +int main() { + M m1; + + N n1; + n1.PR(); +} + diff --git a/test/CodeGenCXX/constructor-template.cpp b/test/CodeGenCXX/constructor-template.cpp new file mode 100644 index 000000000000..8c4f2c912709 --- /dev/null +++ b/test/CodeGenCXX/constructor-template.cpp @@ -0,0 +1,56 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +// PR4826 +struct A { + A() { + } +}; + +template<typename T> +struct B { + B(T) {} + + A nodes; +}; + + +// PR4853 +template <typename T> class List { +public: + List(){ } // List<BinomialNode<int>*>::List() remains undefined. + ~List() {} +}; + +template <typename T> class Node { + int i; +public: + Node(){ } // Node<BinomialNode<int>*>::Node() remains undefined. + ~Node() {} +}; + + +template<typename T> class BinomialNode : Node<BinomialNode<T>*> { +public: + BinomialNode(T value) {} + List<BinomialNode<T>*> nodes; +}; + +int main() { + B<int> *n = new B<int>(4); + BinomialNode<int> *node = new BinomialNode<int>(1); + delete node; +} + +// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev: +// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED2Ev: +// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC1Ev: +// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev: + +// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev: +// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED2Ev: +// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC1Ev: +// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev: diff --git a/test/CodeGenCXX/conversion-function.cpp b/test/CodeGenCXX/conversion-function.cpp new file mode 100644 index 000000000000..0bfd4af7e265 --- /dev/null +++ b/test/CodeGenCXX/conversion-function.cpp @@ -0,0 +1,115 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +extern "C" int printf(...); +struct S { + operator int(); +}; + +S::operator int() { + return 10; +} + + +class X { // ... + public: operator int() { printf("operator int()\n"); return iX; } + public: operator float() { printf("operator float()\n"); return fX; } + X() : iX(100), fX(1.234) {} + int iX; + float fX; +}; + +X x; + +struct Z { + operator X() { printf("perator X()\n"); x.iX += iZ; x.fX += fZ; return x; } + int iZ; + float fZ; + Z() : iZ(1), fZ(1.00) {} +}; + +Z z; + +class Y { // ... + public: operator Z(){printf("perator Z()\n"); return z; } +}; + +Y y; + +int count=0; +class O { // ... +public: + operator int(){ return ++iO; } + O() : iO(count++) {} + int iO; +}; + +void g(O a, O b) { + int i = (a) ? 1+a : 0; + int j = (a&&b) ? a+b : i; + if (a) { } + printf("i = %d j = %d a.iO = %d b.iO = %d\n", i, j, a.iO, b.iO); +} + +int main() { + int c = X(Z(y)); // OK: y.operator Z().operator X().operator int() + printf("c = %d\n", c); + float f = X(Z(y)); + printf("f = %f\n", f); + int i = x; + printf("i = %d float = %f\n", i, float(x)); + i = int(X(Z(y))); + f = float(X(Z(y))); + printf("i = %d float = %f\n", i,f); + f = (float)x; + i = (int)x; + printf("i = %d float = %f\n", i,f); + + int d = (X)((Z)y); + printf("d = %d\n", d); + + int e = (int)((X)((Z)y)); + printf("e = %d\n", e); + O o1, o2; + g(o1, o2); +} + +// Test. Conversion in base class is visible in derived class. +class XB { + int a; +public: + operator int(); +}; + +class Yb : public XB { + double b; +public: + operator char(); +}; + +void f(Yb& a) { + int i = a; // OK. calls XB::operator int(); + char ch = a; // OK. calls Yb::operator char(); +} + + +// CHECK-LP64: .globl __ZN1ScviEv +// CHECK-LP64-NEXT: __ZN1ScviEv: +// CHECK-LP64: call __ZN1Ycv1ZEv +// CHECK-LP64: call __ZN1Zcv1XEv +// CHECK-LP64: call __ZN1XcviEv +// CHECK-LP64: call __ZN1XcvfEv +// CHECK-LP64: call __ZN2XBcviEv +// CHECK-LP64: call __ZN2YbcvcEv + +// CHECK-LP32: .globl __ZN1ScviEv +// CHECK-LP32-NEXT: __ZN1ScviEv: +// CHECK-LP32: call L__ZN1Ycv1ZEv +// CHECK-LP32: call L__ZN1Zcv1XEv +// CHECK-LP32: call L__ZN1XcviEv +// CHECK-LP32: call L__ZN1XcvfEv +// CHECK-LP32: call L__ZN2XBcviEv +// CHECK-LP32: call L__ZN2YbcvcEv diff --git a/test/CodeGenCXX/convert-to-fptr.cpp b/test/CodeGenCXX/convert-to-fptr.cpp new file mode 100644 index 000000000000..c0bd2f7b856e --- /dev/null +++ b/test/CodeGenCXX/convert-to-fptr.cpp @@ -0,0 +1,47 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +extern "C" int printf(...); + +int f1(int arg) { return arg; }; + +int f2(float arg) { return int(arg); }; + +typedef int (*fp1)(int); + +typedef int (*fp2)(float); + +struct A { + operator fp1() { return f1; } + operator fp2() { return f2; } +} a; + + +// Test for function reference. +typedef int (&fr1)(int); +typedef int (&fr2)(float); + +struct B { + operator fr1() { return f1; } + operator fr2() { return f2; } +} b; + +int main() +{ + int i = a(10); // Calls f1 via pointer returned from conversion function + printf("i = %d\n", i); + + int j = b(20); // Calls f1 via pointer returned from conversion function + printf("j = %d\n", j); + return 0; +} + +// CHECK-LP64: call __ZN1AcvPFiiEEv +// CHECK-LP64: call __ZN1BcvRFiiEEv + +// CHECK-LP32: call L__ZN1AcvPFiiEEv +// CHECK-LP32: call L__ZN1BcvRFiiEEv + diff --git a/test/CodeGenCXX/copy-assign-synthesis-1.cpp b/test/CodeGenCXX/copy-assign-synthesis-1.cpp new file mode 100644 index 000000000000..d4a93afefbfa --- /dev/null +++ b/test/CodeGenCXX/copy-assign-synthesis-1.cpp @@ -0,0 +1,109 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +extern "C" int printf(...); + +struct B { + B() : B1(3.14), B2(3.15), auB2(3.16) {} + float B1; + float B2; + void pr() { + printf("B1 = %f B2 = %f auB1 = %f\n", B1, B2, auB1); + } + + B& operator=(const B& arg) { B1 = arg.B1; B2 = arg.B2; + auB1 = arg.auB1; return *this; } + union { + float auB1; + float auB2; + }; +}; + +struct M { + M() : M1(10), M2(11) , auM1(12) {} + int M1; + int M2; + void pr() { + printf("M1 = %d M2 = %d auM1 = %d auM2 = %d\n", M1, M2, auM1, auM2); + } + union { + int auM1; + int auM2; + }; +}; + +struct N : B { + N() : N1(20), N2(21) {} + int N1; + int N2; + void pr() { + printf("N1 = %d N2 = %d\n", N1, N2); + for (unsigned i = 0; i < 3; i++) + for (unsigned j = 0; j < 2; j++) + printf("arr_b[%d][%d] = %f\n", i,j,arr_b[i][j].B1); + B::pr(); + } + N& operator=(const N& arg) { + N1 = arg.N1; N2 = arg.N2; + for (unsigned i = 0; i < 3; i++) + for (unsigned j = 0; j < 2; j++) + arr_b[i][j] = arg.arr_b[i][j]; + return *this; + } + B arr_b[3][2]; +}; + +struct Q : B { + Q() : Q1(30), Q2(31) {} + int Q1; + int Q2; + void pr() { + printf("Q1 = %d Q2 = %d\n", Q1, Q2); + } +}; + + +struct X : M , N { + X() : d(0.0), d1(1.1), d2(1.2), d3(1.3) {} + double d; + double d1; + double d2; + double d3; + void pr() { + printf("d = %f d1 = %f d2 = %f d3 = %f\n", d, d1,d2,d3); + M::pr(); N::pr(); + q1.pr(); q2.pr(); + } + + Q q1, q2; +}; + + +X srcX; +X dstX; +X dstY; + +int main() { + dstY = dstX = srcX; + srcX.pr(); + dstX.pr(); + dstY.pr(); +} + +// CHECK-LP64: .globl __ZN1XaSERKS_ +// CHECK-LP64: .weak_definition __ZN1XaSERKS_ +// CHECK-LP64: __ZN1XaSERKS_: +// CHECK-LP64: .globl __ZN1QaSERKS_ +// CHECK-LP64: .weak_definition __ZN1QaSERKS_ +// CHECK-LP64: __ZN1QaSERKS_: + +// CHECK-LP32: .globl __ZN1XaSERKS_ +// CHECK-LP32: .weak_definition __ZN1XaSERKS_ +// CHECK-LP32: __ZN1XaSERKS_: +// CHECK-LP32: .globl __ZN1QaSERKS_ +// CHECK-LP32: .weak_definition __ZN1QaSERKS_ +// CHECK-LP32: __ZN1QaSERKS_: + diff --git a/test/CodeGenCXX/copy-assign-synthesis.cpp b/test/CodeGenCXX/copy-assign-synthesis.cpp new file mode 100644 index 000000000000..f9baa8f03f3c --- /dev/null +++ b/test/CodeGenCXX/copy-assign-synthesis.cpp @@ -0,0 +1,79 @@ +// RUN: clang-cc -emit-llvm -o %t %s && +// RUN: grep "_ZN1XaSERK1X" %t | count 0 + +extern "C" int printf(...); + +struct B { + B() : B1(3.14), B2(3.15), auB2(3.16) {} + float B1; + float B2; + void pr() { + printf("B1 = %f B2 = %f auB1 = %f\n", B1, B2, auB1); + } + + union { + float auB1; + float auB2; + }; +}; + +struct M { + M() : M1(10), M2(11) , auM1(12) {} + int M1; + int M2; + void pr() { + printf("M1 = %d M2 = %d auM1 = %d auM2 = %d\n", M1, M2, auM1, auM2); + } + union { + int auM1; + int auM2; + }; +}; + +struct N : B { + N() : N1(20), N2(21) {} + int N1; + int N2; + void pr() { + printf("N1 = %d N2 = %d\n", N1, N2); + B::pr(); + } +}; + +struct Q { + Q() : Q1(30), Q2(31) {} + int Q1; + int Q2; + void pr() { + printf("Q1 = %d Q2 = %d\n", Q1, Q2); + } +}; + + +struct X : M , N { + X() : d(0.0), d1(1.1), d2(1.2), d3(1.3) {} + double d; + double d1; + double d2; + double d3; + void pr() { + printf("d = %f d1 = %f d2 = %f d3 = %f\n", d, d1,d2,d3); + M::pr(); N::pr(); + q1.pr(); q2.pr(); + } + + Q q1, q2; +}; + + +X srcX; +X dstX; +X dstY; + +int main() { + dstY = dstX = srcX; + srcX.pr(); + dstX.pr(); + dstY.pr(); +} + diff --git a/test/CodeGenCXX/copy-constructor-elim.cpp b/test/CodeGenCXX/copy-constructor-elim.cpp new file mode 100644 index 000000000000..daef92cdb767 --- /dev/null +++ b/test/CodeGenCXX/copy-constructor-elim.cpp @@ -0,0 +1,43 @@ +// RUN: clang-cc -emit-llvm -o %t %s && +// RUN: grep "_ZN1CC1ERK1C" %t | count 0 && +// RUN: grep "_ZN1SC1ERK1S" %t | count 0 && +// RUN: true + +extern "C" int printf(...); + + +struct C { + C() : iC(6) {printf("C()\n"); } + C(const C& c) { printf("C(const C& c)\n"); } + int iC; +}; + +C foo() { + return C(); +}; + +class X { // ... +public: + X(int) {} + X(const X&, int i = 1, int j = 2, C c = foo()) { + printf("X(const X&, %d, %d, %d)\n", i, j, c.iC); + } +}; + + +struct S { + S(); +}; + +S::S() { printf("S()\n"); } + +void Call(S) {}; + +int main() { + X a(1); + X b(a, 2); + X c = b; + X d(a, 5, 6); + S s; + Call(s); +} diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp new file mode 100644 index 000000000000..47971afe61d4 --- /dev/null +++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp @@ -0,0 +1,110 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +extern "C" int printf(...); + +int init = 100; + +struct M { + int iM; + M() : iM(init++) {} +}; + +struct N { + int iN; + N() : iN(200) {} + N(N const & arg){this->iN = arg.iN; } +}; + +struct P { + int iP; + P() : iP(init++) {} +}; + + +struct X : M, N, P { // ... + X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd), + au_i1(1234), au1_4("MASKED") {} + P p0; + void pr() { + printf("iM = %d iN = %d, m1.iM = %d\n", iM, iN, m1.iM); + printf("im = %d p0.iP = %d, p1.iP = %d\n", iP, p0.iP, p1.iP); + printf("f1 = %f d1 = %f i1 = %d name(%s) \n", f1, d1, i1, name); + printf("bf1 = %x bf2 = %x\n", bf1, bf2); + printf("au_i2 = %d\n", au_i2); + printf("au1_1 = %s\n", au1_1); + } + M m1; + P p1; + float f1; + double d1; + int i1; + const char *name; + unsigned bf1 : 8; + unsigned bf2 : 16; + + union { + int au_i1; + int au_i2; + }; + union { + const char * au1_1; + float au1_2; + int au1_3; + const char * au1_4; + }; +}; + +static int ix = 1; +// class with user-defined copy constructor. +struct S { + S() : iS(ix++) { } + S(const S& arg) { *this = arg; } + int iS; +}; + +// class with trivial copy constructor. +struct I { + I() : iI(ix++) { } + int iI; +}; + +struct XM { + XM() { } + double dXM; + S ARR_S[3][4][2]; + void pr() { + for (unsigned i = 0; i < 3; i++) + for (unsigned j = 0; j < 4; j++) + for (unsigned k = 0; k < 2; k++) + printf("ARR_S[%d][%d][%d] = %d\n", i,j,k, ARR_S[i][j][k].iS); + for (unsigned i = 0; i < 3; i++) + for (unsigned k = 0; k < 2; k++) + printf("ARR_I[%d][%d] = %d\n", i,k, ARR_I[i][k].iI); + } + I ARR_I[3][2]; +}; + +int main() { + X a; + X b(a); + b.pr(); + X x; + X c(x); + c.pr(); + + XM m0; + XM m1 = m0; + m1.pr(); +} + +// CHECK-LP64: .globl __ZN1XC1ERKS_ +// CHECK-LP64: .weak_definition __ZN1XC1ERKS_ +// CHECK-LP64: __ZN1XC1ERKS_: + +// CHECK-LP32: .globl __ZN1XC1ERKS_ +// CHECK-LP32: .weak_definition __ZN1XC1ERKS_ +// CHECK-LP32: __ZN1XC1ERKS_: diff --git a/test/CodeGenCXX/decl-ref-init.cpp b/test/CodeGenCXX/decl-ref-init.cpp new file mode 100644 index 000000000000..27d200f4635b --- /dev/null +++ b/test/CodeGenCXX/decl-ref-init.cpp @@ -0,0 +1,31 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +struct A {}; + +struct B +{ + operator A&(); +}; + + +struct D : public B { + operator A(); +}; + +extern B f(); +extern D d(); + +int main() { + const A& rca = f(); + const A& rca2 = d(); +} + +// CHECK-LP64: call __ZN1BcvR1AEv +// CHECK-LP64: call __ZN1BcvR1AEv + +// CHECK-LP32: call L__ZN1BcvR1AEv +// CHECK-LP32: call L__ZN1BcvR1AEv diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp index 2dcf773346a8..2651446669b8 100644 --- a/test/CodeGenCXX/default-arg-temps.cpp +++ b/test/CodeGenCXX/default-arg-temps.cpp @@ -7,9 +7,19 @@ struct T { void f(const T& t = T()); +class X { // ... +public: + X(); + X(const X&, const T& t = T()); +}; + void g() { - // RUN: grep "call void @_ZN1TC1Ev" %t | count 2 && - // RUN: grep "call void @_ZN1TD1Ev" %t | count 2 + // RUN: grep "call void @_ZN1TC1Ev" %t | count 4 && + // RUN: grep "call void @_ZN1TD1Ev" %t | count 4 f(); f(); + + X a; + X b(a); + X c = a; } diff --git a/test/CodeGenCXX/default-constructor-for-members.cpp b/test/CodeGenCXX/default-constructor-for-members.cpp new file mode 100644 index 000000000000..2d04bc941427 --- /dev/null +++ b/test/CodeGenCXX/default-constructor-for-members.cpp @@ -0,0 +1,24 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +extern "C" int printf(...); + +struct S { + S() { printf("S::S()\n"); } + int iS; +}; + +struct M { + S ARR_S; +}; + +int main() { + M m1; +} + +// CHECK-LP64: call __ZN1SC1Ev + +// CHECK-LP32: call L__ZN1SC1Ev diff --git a/test/CodeGenCXX/default-destructor-synthesis.cpp b/test/CodeGenCXX/default-destructor-synthesis.cpp new file mode 100644 index 000000000000..9cc802c85dfa --- /dev/null +++ b/test/CodeGenCXX/default-destructor-synthesis.cpp @@ -0,0 +1,60 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -O0 -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -O0 -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 -input-file=%t-32.s %s && +// RUN: true + +extern "C" int printf(...); + +int count = 1; + +struct S { + S() : iS(count++), fS(1.23) {}; + ~S(){printf("S::~S(%d, %f)\n", iS, fS); }; + int iS; + float fS; +}; + +struct Q { + Q() : iQ(count++), dQ(2.34) {}; + ~Q(){printf("Q::~Q(%d, %f)\n", iQ, dQ); }; + int iQ; + double dQ; +}; + +struct P { + P() : fP(3.45) , iP(count++) {}; + ~P(){printf("P::~P(%d, %f)\n", iP, fP); }; + float fP; + int iP; +}; + +struct M : Q, P { + S s; + + Q q; + + P p; + + P p_arr[3]; + + Q q_arr[2][3]; + +}; + +M gm; + +int main() {M m1;} + +// CHECK-LP64: call __ZN1MC1Ev +// CHECK-LP64: call __ZN1MD1Ev +// CHECK-LP64: .globl __ZN1MD1Ev +// CHECK-LP64-NEXT: .weak_definition __ZN1MD1Ev +// CHECK-LP64-NEXT: __ZN1MD1Ev: + + +// CHECK-LP32: call L__ZN1MC1Ev +// CHECK-LP32: call L__ZN1MD1Ev +// CHECK-LP32: .globl __ZN1MD1Ev +// CHECK-LP32-NEXT: .weak_definition __ZN1MD1Ev +// CHECK-LP32-NEXT:__ZN1MD1Ev: diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp new file mode 100644 index 000000000000..9e3feefefeda --- /dev/null +++ b/test/CodeGenCXX/delete.cpp @@ -0,0 +1,37 @@ +// RUN: clang-cc %s -emit-llvm -o %t && + +void t1(int *a) { + delete a; +} + +struct S { + int a; +}; + +// POD types. +void t3(S *s) { + delete s; +} + +// Non-POD +struct T { + ~T(); + int a; +}; + +void t4(T *t) { + // RUN: grep "call void @_ZN1TD1Ev" %t | count 1 + delete t; +} + +// PR5102 +template <typename T> +class A { + operator T *() const; +}; + +void f() { + A<char*> a; + + delete a; +} diff --git a/test/CodeGenCXX/derived-to-base.cpp b/test/CodeGenCXX/derived-to-base.cpp new file mode 100644 index 000000000000..63492d604d17 --- /dev/null +++ b/test/CodeGenCXX/derived-to-base.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -emit-llvm %s -o - +struct A { + void f(); + + int a; +}; + +struct B : A { + double b; +}; + +void f() { + B b; + + b.f(); +} diff --git a/test/CodeGenCXX/destructor-calls.cpp b/test/CodeGenCXX/destructor-calls.cpp new file mode 100644 index 000000000000..3f0288b85c14 --- /dev/null +++ b/test/CodeGenCXX/destructor-calls.cpp @@ -0,0 +1,41 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +extern "C" int printf(...); + +static int val; + +struct B { + B() : iB(++val) { printf("B()\n"); } + int iB; + ~B() { printf("~B(%d)\n", iB); --val; } +}; + +struct M : B { + M() : iM(++val) { printf("M()\n"); } + int iM; + ~M() { printf("~M(%d)\n", iM); --val; } +}; + +struct P { + P() : iP(++val) { printf("P()\n"); } + int iP; + ~P() { printf("~P(%d)\n", iP); --val; } +}; + +struct N : M, P { + N() { printf("N()\n"); iN = ++val; } + ~N() { printf("~N(%d) val = %d\n", iN, --val); } + int iN; + M m; + P p; +}; + +struct O : B { + ~O() { return; } +}; + +int main() { + N n1; + N n2; + O o; +} diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp new file mode 100644 index 000000000000..44d2b2936864 --- /dev/null +++ b/test/CodeGenCXX/destructors.cpp @@ -0,0 +1,30 @@ +// RUN: clang-cc %s -emit-llvm -o - +struct A { + int a; + + ~A(); +}; + +// Base with non-trivial destructor +struct B : A { + ~B(); +}; + +B::~B() { } + +// Field with non-trivial destructor +struct C { + A a; + + ~C(); +}; + +C::~C() { } + +// PR5084 +template<typename T> +class A1 { + ~A1(); +}; + +template<> A1<char>::~A1(); diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp new file mode 100644 index 000000000000..cbf55ad61331 --- /dev/null +++ b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp @@ -0,0 +1,47 @@ +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s + +struct A { + virtual void f(); + + A h(); +}; + +A g(); + +void f(A a, A *ap, A& ar) { + // This should not be a virtual function call. + + // CHECK: call void @_ZN1A1fEv(%struct.A* %a) + a.f(); + + // CHECK: call void % + ap->f(); + + // CHECK: call void % + ar.f(); + + // CHECK: call void @_ZN1A1fEv + A().f(); + + // CHECK: call void @_ZN1A1fEv + g().f(); + + // CHECK: call void @_ZN1A1fEv + a.h().f(); +} + +struct B { + virtual void f(); + ~B(); + + B h(); +}; + + +void f() { + // CHECK: call void @_ZN1B1fEv + B().f(); + + // CHECK: call void @_ZN1B1fEv + B().h().f(); +} diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp index 38966aad2deb..8a9e65c4e2e3 100644 --- a/test/CodeGenCXX/explicit-instantiation.cpp +++ b/test/CodeGenCXX/explicit-instantiation.cpp @@ -1,11 +1,14 @@ -// RUN: clang-cc -emit-llvm -femit-all-decls -o %t %s && -// RUN: grep "_ZNK4plusIillEclERKiRKl" %t | count 1 +// RUN: clang-cc -emit-llvm -triple i686-pc-linue-gnu -o %t %s && +// RUN: grep "define i32 @_ZNK4plusIillEclERKiRKl" %t | count 1 template<typename T, typename U, typename Result> struct plus { - Result operator()(const T& t, const U& u) const { - return t + u; - } + Result operator()(const T& t, const U& u) const; }; +template<typename T, typename U, typename Result> +Result plus<T, U, Result>::operator()(const T& t, const U& u) const { + return t + u; +} + template struct plus<int, long, long>; diff --git a/test/CodeGenCXX/function-template-specialization.cpp b/test/CodeGenCXX/function-template-specialization.cpp index bea3af2bb5af..677be4cc0f9a 100644 --- a/test/CodeGenCXX/function-template-specialization.cpp +++ b/test/CodeGenCXX/function-template-specialization.cpp @@ -1,4 +1,4 @@ -// RUN: clang-cc -emit-llvm %s -o %t && +// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s template<typename T, typename U> T* next(T* ptr, const U& diff); @@ -8,11 +8,10 @@ T* next(T* ptr, const U& diff) { } void test(int *iptr, float *fptr, int diff) { - // FIXME: should be "_Z4nextIiiEPT_S1_RKT0_" - // RUN: grep "_Z4nextIiiEPiPiRKi" %t && + // CHECK: _Z4nextIiiEPT_S1_RKT0_ iptr = next(iptr, diff); - // FIXME: should be "_Z4nextIfiEPT_S1_RKT0_" - // RUN: grep "_Z4nextIfiEPfPfRKi" %t && + + // CHECK: _Z4nextIfiEPT_S1_RKT0_ fptr = next(fptr, diff); } @@ -21,7 +20,7 @@ T* next(T* ptr, const U& diff); void test2(int *iptr, double *dptr, int diff) { iptr = next(iptr, diff); - // FIXME: should be "_Z4nextIdiEPT_S1_RKT0_" - // RUN: grep "_Z4nextIdiEPdPdRKi" %t + + // CHECK: _Z4nextIdiEPT_S1_RKT0_ dptr = next(dptr, diff); -}
\ No newline at end of file +} diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp new file mode 100644 index 000000000000..ae450e17e85e --- /dev/null +++ b/test/CodeGenCXX/global-init.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck %s + +struct A { + A(); + ~A(); +}; + +struct B { B(); ~B(); }; + +// CHECK: call void @_ZN1AC1Ev(%struct.A* @a) +// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) +A a; + +// CHECK: call void @_ZN1BC1Ev(%struct.A* @b) +// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @b, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) +B b; diff --git a/test/CodeGenCXX/mangle-extreme.cpp b/test/CodeGenCXX/mangle-extreme.cpp new file mode 100644 index 000000000000..77558d29d824 --- /dev/null +++ b/test/CodeGenCXX/mangle-extreme.cpp @@ -0,0 +1,47 @@ +// RUN: clang-cc -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s + +struct X { }; + +// CHECK: define void @_Z1fPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP1XS13_S12_S11_S10_SZ_SY_SX_SW_SV_SU_ST_SS_SR_SQ_SP_SO_SN_SM_SL_SK_SJ_SI_SH_SG_SF_SE_SD_SC_SB_SA_S9_S8_S7_S6_S5_S4_S3_S2_S1_S0_S_( +void f(X****************************************, + X****************************************, + X***************************************, + X**************************************, + X*************************************, + X************************************, + X***********************************, + X**********************************, + X*********************************, + X********************************, + X*******************************, + X******************************, + X*****************************, + X****************************, + X***************************, + X**************************, + X*************************, + X************************, + X***********************, + X**********************, + X*********************, + X********************, + X*******************, + X******************, + X*****************, + X****************, + X***************, + X**************, + X*************, + X************, + X***********, + X**********, + X*********, + X********, + X*******, + X******, + X*****, + X****, + X***, + X**, + X*, + X) { } diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp new file mode 100644 index 000000000000..fbce20451264 --- /dev/null +++ b/test/CodeGenCXX/mangle-subst-std.cpp @@ -0,0 +1,39 @@ +// RUN: clang-cc -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s + +namespace std { + struct A { A(); }; + + // CHECK: define void @_ZNSt1AC1Ev + // CHECK: define void @_ZNSt1AC2Ev + A::A() { } +}; + +namespace std { + template<typename> struct allocator { }; +} + +// CHECK: define void @_Z1fSaIcESaIiE +void f(std::allocator<char>, std::allocator<int>) { } + +namespace std { + template<typename, typename, typename> struct basic_string { }; +} + +// CHECK: define void @_Z1fSbIcciE +void f(std::basic_string<char, char, int>) { } + +namespace std { + template<typename> struct char_traits { }; + + typedef std::basic_string<char, std::char_traits<char>, std::allocator<char> > string; +} + +// CHECK: _Z1fSs +void f(std::string) { } + +namespace std { + template<typename, typename> struct basic_ostream { }; +} + +// CHECK: _Z1fSo +void f(std::basic_ostream<char, std::char_traits<char> >) { } diff --git a/test/CodeGenCXX/mangle-subst.cpp b/test/CodeGenCXX/mangle-subst.cpp new file mode 100644 index 000000000000..c53a6300aa19 --- /dev/null +++ b/test/CodeGenCXX/mangle-subst.cpp @@ -0,0 +1,56 @@ +// RUN: clang-cc -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s + +struct X {}; + +// CHECK: define void @_Z1f1XS_( +void f(X, X) { } + +// CHECK: define void @_Z1fR1XS0_( +void f(X&, X&) { } + +// CHECK: define void @_Z1fRK1XS1_( +void f(const X&, const X&) { } + +typedef void T(); +struct S {}; + +// CHECK: define void @_Z1fPFvvEM1SFvvE( +void f(T*, T (S::*)) {} + +namespace A { + struct A { }; + struct B { }; +}; + +// CHECK: define void @_Z1fN1A1AENS_1BE( +void f(A::A a, A::B b) { } + +struct C { + struct D { }; +}; + +// CHECK: define void @_Z1fN1C1DERS_PS_S1_( +void f(C::D, C&, C*, C&) { } + +template<typename T> +struct V { + typedef int U; +}; + +template <typename T> void f1(typename V<T>::U, V<T>) { } + +// CHECK: @_Z2f1IiEvN1VIT_E1UES2_ +template void f1<int>(int, V<int>); + +template <typename T> void f2(V<T>, typename V<T>::U) { } + +// CHECK: @_Z2f2IiEv1VIT_ENS2_1UE +template void f2<int>(V<int>, int); + +namespace NS { +template <typename T> struct S1 {}; +template<typename T> void ft3(S1<T>, S1<char>) { } + +// CHECK: @_ZN2NS3ft3IiEEvNS_2S1IT_EENS1_IcEE +template void ft3<int>(S1<int>, S1<char>); +} diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index ef36a8b23cfc..2ffbae71da01 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -1,87 +1,223 @@ -// RUN: clang-cc -emit-llvm %s -o %t -triple=x86_64-apple-darwin9 && +// RUN: clang-cc -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s -// FIXME: This test is intentionally trivial, because we can't yet -// CodeGen anything real in C++. struct X { }; struct Y { }; -// RUN: grep _ZplRK1YRA100_P1X %t | count 1 && +// CHECK: @unmangled_variable = global +// CHECK: @_ZN1N1iE = global +// CHECK: @_ZZN1N1fEiiE1b = internal global +// CHECK: @_ZZN1N1gEvE1a = internal global +// CHECK: @_ZGVZN1N1gEvE1a = internal global + +// CHECK: define zeroext i1 @_ZplRK1YRA100_P1X bool operator+(const Y&, X* (&xs)[100]) { return false; } -// RUN: grep _Z1f1s %t | count 1 && +// CHECK: define void @_Z1f1s typedef struct { int a; } s; void f(s) { } -// RUN: grep _Z1f1e %t| count 1 && +// CHECK: define void @_Z1f1e typedef enum { foo } e; void f(e) { } -// RUN: grep _Z1f1u %t | count 1 && +// CHECK: define void @_Z1f1u typedef union { int a; } u; void f(u) { } -// RUN: grep _Z1f1x %t | count 1 && +// CHECK: define void @_Z1f1x typedef struct { int a; } x,y; void f(y) { } -// RUN: grep _Z1fv %t | count 1 && +// CHECK: define void @_Z1fv void f() { } -// RUN: grep _ZN1N1fEv %t | count 1 && +// CHECK: define void @_ZN1N1fEv namespace N { void f() { } } -// RUN: grep _ZN1N1N1fEv %t | count 1 && +// CHECK: define void @_ZN1N1N1fEv namespace N { namespace N { void f() { } } } -// RUN: grep unmangled_function %t | count 1 && +// CHECK: define void @unmangled_function extern "C" { namespace N { void unmangled_function() { } } } -// RUN: grep unmangled_variable %t | count 1 && extern "C" { namespace N { int unmangled_variable = 10; } } -// RUN: grep _ZN1N1iE %t | count 1 && namespace N { int i; } -// RUN: grep _ZZN1N1fEiiE1b %t | count 2 && namespace N { int f(int, int) { static int b; return b; } } -// RUN: grep "_ZZN1N1gEvE1a =" %t | count 1 && -// RUN: grep "_ZGVZN1N1gEvE1a =" %t | count 1 && namespace N { int h(); void g() { static int a = h(); } } -// RUN: grep "_Z1fno" %t | count 1 && +// CHECK: define void @_Z1fno void f(__int128_t, __uint128_t) { } template <typename T> struct S1 {}; -// RUN: grep "_Z1f2S1IiE" %t | count 1 && +// CHECK: define void @_Z1f2S1IiE void f(S1<int>) {} -// RUN: grep "_Z1f2S1IdE" %t | count 1 && +// CHECK: define void @_Z1f2S1IdE void f(S1<double>) {} template <int N> struct S2 {}; -// RUN: grep "_Z1f2S2ILi100EE" %t | count 1 && +// CHECK: define void @_Z1f2S2ILi100EE void f(S2<100>) {} -// RUN: grep "_Z1f2S2ILin100EE" %t | count 1 && +// CHECK: define void @_Z1f2S2ILin100EE void f(S2<-100>) {} template <bool B> struct S3 {}; -// RUN: grep "_Z1f2S3ILb1EE" %t | count 1 && +// CHECK: define void @_Z1f2S3ILb1EE void f(S3<true>) {} -// RUN: grep "_Z1f2S3ILb0EE" %t | count 1 && +// CHECK: define void @_Z1f2S3ILb0EE void f(S3<false>) {} -// RUN: grep "_Z2f22S3ILb1EE" %t | count 1 && +// CHECK: define void @_Z2f22S3ILb1EE void f2(S3<100>) {} struct S; -// RUN: grep "_Z1fM1SKFvvE" %t | count 1 && +// CHECK: define void @_Z1fM1SKFvvE void f(void (S::*)() const) {} -// RUN: grep "_Z1fM1SFvvE" %t | count 1 +// CHECK: define void @_Z1fM1SFvvE void f(void (S::*)()) {} + +// CHECK: define void @_Z1fi +void f(const int) { } + +template<typename T, typename U> void ft1(U u, T t) { } + +template<typename T> void ft2(T t, void (*)(T), void (*)(T)) { } + +template<typename T, typename U = S1<T> > struct S4 { }; +template<typename T> void ft3(S4<T>*) { } + +namespace NS { + template<typename T> void ft1(T) { } +} + +void g1() { + // CHECK: @_Z3ft1IidEvT0_T_ + ft1<int, double>(1, 0); + + // CHECK: @_Z3ft2IcEvT_PFvS0_ES2_ + ft2<char>(1, 0, 0); + + // CHECK: @_Z3ft3IiEvP2S4IT_2S1IS1_EE + ft3<int>(0); + + // CHECK: @_ZN2NS3ft1IiEEvT_ + NS::ft1<int>(1); +} + +// Expressions +template<int I> struct S5 { }; + +template<int I> void ft4(S5<I>) { } +void g2() { + // CHECK: @_Z3ft4ILi10EEv2S5IXT_EE + ft4(S5<10>()); + + // CHECK: @_Z3ft4ILi20EEv2S5IXT_EE + ft4(S5<20>()); +} + +extern "C++" { + // CHECK: @_Z1hv + void h() { } +} + +// PR5019 +extern "C" { struct a { int b; }; } + +// CHECK: @_Z1fP1a +int f(struct a *x) { + return x->b; +} + +// PR5017 +extern "C" { +struct Debug { + const Debug& operator<< (unsigned a) const { } +}; +Debug dbg; +// CHECK: @_ZNK5DebuglsEj +int main(void) { dbg << 32 ;} +} + +template<typename T> struct S6 { + typedef int B; +}; + +template<typename T> void ft5(typename S6<T>::B) { } +// CHECK: @_Z3ft5IiEvN2S6IT_E1BE +template void ft5<int>(int); + +template<typename T> class A {}; + +namespace NS { +template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; } +} + +// CHECK: @_ZN2NSeqIcEEbRK1AIT_ES5_ +template bool NS::operator==(const ::A<char>&, const ::A<char>&); + +namespace std { +template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; } +} + +// CHECK: @_ZSteqIcEbRK1AIT_ES4_ +template bool std::operator==(const ::A<char>&, const ::A<char>&); + +struct S { + typedef int U; +}; + +template <typename T> typename T::U ft6(const T&) { return 0; } + +// CHECK: @_Z3ft6I1SENT_1UERKS1_ +template int ft6<S>(const S&); + +template<typename> struct __is_scalar { + enum { __value = 1 }; +}; + +template<bool, typename> struct __enable_if { }; + +template<typename T> struct __enable_if<true, T> { + typedef T __type; +}; + +// PR5063 +template<typename T> typename __enable_if<__is_scalar<T>::__value, void>::__type ft7() { } + +// CHECK: @_Z3ft7IiEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv +template void ft7<int>(); +// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv +template void ft7<void*>(); + +// PR5144 +extern "C" { +void extern_f(void); +}; + +// CHECK: @extern_f +void extern_f(void) { } + +struct S7 { + struct S { S(); }; + + struct { + S s; + } a; +}; + +// PR5139 +// CHECK: @_ZN2S7C1Ev +// CHECK: @_ZN2S7C2Ev +// CHECK: @"_ZN2S73$_0C1Ev" +S7::S7() {} + diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp new file mode 100644 index 000000000000..13f7de5a631b --- /dev/null +++ b/test/CodeGenCXX/member-function-pointers.cpp @@ -0,0 +1,73 @@ +// RUN: clang-cc %s -emit-llvm -o - -triple=x86_64-apple-darwin9 | FileCheck %s + +struct A { int a; void f(); virtual void vf(); }; +struct B { int b; virtual void g(); }; +struct C : B, A { }; + +void (A::*pa)(); +void (A::*volatile vpa)(); +void (B::*pb)(); +void (C::*pc)(); + +// CHECK: @pa2 = global %0 { i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64 0 }, align 8 +void (A::*pa2)() = &A::f; + +// CHECK: @pa3 = global %0 { i64 1, i64 0 }, align 8 +void (A::*pa3)() = &A::vf; + +// CHECK: @pc2 = global %0 { i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64 16 }, align 8 +void (C::*pc2)() = &C::f; + +// CHECK: @pc3 = global %0 { i64 1, i64 0 }, align 8 +void (A::*pc3)() = &A::vf; + +void f() { + // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0) + // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 1) + pa = 0; + + // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 0) + // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 1) + vpa = 0; + + // CHECK: store i64 %0, i64* getelementptr inbounds (%0* @pc, i32 0, i32 0) + // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 %1, 16 + // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pc, i32 0, i32 1) + pc = pa; +} + +void f2() { + // CHECK: [[pa2ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 0 + // CHECK: store i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64* [[pa2ptr]] + // CHECK: [[pa2adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 1 + // CHECK: store i64 0, i64* [[pa2adj]] + void (A::*pa2)() = &A::f; + + // CHECK: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0 + // CHECK: store i64 1, i64* [[pa3ptr]] + // CHECK: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1 + // CHECK: store i64 0, i64* [[pa2adj]] + void (A::*pa3)() = &A::vf; +} + +void f3(A *a, A &ar) { + (a->*pa)(); + (ar.*pa)(); +} + +// PR5177 +namespace PR5177 { + struct A { + bool foo(int*) const; + } a; + + struct B1 { + bool (A::*pmf)(int*) const; + const A* pa; + + B1() : pmf(&A::foo), pa(&a) {} + bool operator()() const { return (pa->*pmf)(new int); } + }; + + void bar(B1 b2) { while (b2()) ; } +} diff --git a/test/CodeGenCXX/member-functions.cpp b/test/CodeGenCXX/member-functions.cpp index 8ada907117be..29629d5bf824 100644 --- a/test/CodeGenCXX/member-functions.cpp +++ b/test/CodeGenCXX/member-functions.cpp @@ -58,6 +58,6 @@ struct T { void test3() { T t1, t2; - // RUN: grep "call void @_ZN1TpsERK1T" %t + // RUN: grep "call void @_ZN1TpsERKS_" %t T result = t1 + t2; } diff --git a/test/CodeGenCXX/member-pointers-zero-init.cpp b/test/CodeGenCXX/member-pointers-zero-init.cpp new file mode 100644 index 000000000000..e7b0fdafba6a --- /dev/null +++ b/test/CodeGenCXX/member-pointers-zero-init.cpp @@ -0,0 +1,34 @@ +// RUN: clang-cc -emit-llvm %s -o %t -triple=x86_64-apple-darwin9 && + +struct A { + int i; +}; + +// RUN: grep "@a = global i64 -1" %t && +int A::* a; + +// RUN: grep "@aa = global \[2 x i64\] \[i64 -1, i64 -1\]" %t && +int A::* aa[2]; + +// RUN: grep "@aaa = global \[2 x \[2 x i64\]\] \[\[2 x i64\] \[i64 -1, i64 -1\], \[2 x i64\] \[i64 -1, i64 -1\]\]" %t && +int A::* aaa[2][2]; + +// RUN: grep "@b = global i64 -1" %t && +int A::* b = 0; + +void f() { + // RUN: grep "%.* = icmp ne i64 %.*, -1" %t | count 2 && + if (a) { } + if (a != 0) { } + + // RUN: grep "%.* = icmp ne i64 -1, %.*" %t | count 1 && + if (0 != a) { } + + // RUN: grep "%.* = icmp eq i64 %.*, -1" %t | count 1 && + if (a == 0) { } + + // RUN: grep "%.* = icmp eq i64 -1, %.*" %t | count 1 + if (0 == a) { } + +} + diff --git a/test/CodeGenCXX/namespace-aliases.cpp b/test/CodeGenCXX/namespace-aliases.cpp new file mode 100644 index 000000000000..5baea8791ef9 --- /dev/null +++ b/test/CodeGenCXX/namespace-aliases.cpp @@ -0,0 +1,3 @@ +// RUN: clang-cc -emit-llvm-only %s +namespace A { } +namespace B = A; diff --git a/test/CodeGenCXX/nested-base-member-access.cpp b/test/CodeGenCXX/nested-base-member-access.cpp new file mode 100644 index 000000000000..308f952c6dc2 --- /dev/null +++ b/test/CodeGenCXX/nested-base-member-access.cpp @@ -0,0 +1,52 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +extern "C" int printf(...); + +struct M { + M(int i){ iM = i; } + int iM; + void MPR() { printf("iM = %d\n", iM); } + +}; + +struct Q { + Q(int i){ iQ = i; } + int iQ; + void QPR() { printf("iQ = %d\n", iQ); } +}; + +struct IQ { + IQ(int i) { iIQ = i; } + void IQPR() { printf("iIQ = %d\n", iIQ); } + int iIQ; +}; + +struct L : IQ { + L(int i) : IQ(i+100) { iL = i; } + int iL; +}; + +struct P : Q, L { + P(int i) : Q(i+100), L(i+200) { iP = i; } + int iP; + void PPR() { printf("iP = %d\n", iP); } +}; + + +struct N : M,P { + N() : M(100), P(200) {} + void PR() { + this->MPR(); this->PPR(); this->QPR(); + IQPR(); + printf("iM = %d\n", iM); + printf("iP = %d\n", iP); + printf("iQ = %d\n", iQ); + printf("iL = %d\n", iL); + printf("iIQ = %d\n", iIQ); + } +}; + +int main() { + N n1; + n1.PR(); +} diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp index 480bbcefc08d..c6cee1845670 100644 --- a/test/CodeGenCXX/new.cpp +++ b/test/CodeGenCXX/new.cpp @@ -1,4 +1,4 @@ -// RUN: clang-cc %s -emit-llvm -o %t && +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s void t1() { int* a = new int; @@ -32,7 +32,7 @@ struct T { }; void t4() { - // RUN: grep "call void @_ZN1TC1Ev" %t | count 1 && + // CHECK: call void @_ZN1TC1Ev T *t = new T; } @@ -42,7 +42,7 @@ struct T2 { }; void t5() { - // RUN: grep "call void @_ZN2T2C1Eii" %t | count 1 + // CHECK: call void @_ZN2T2C1Eii T2 *t2 = new T2(10, 10); } @@ -54,3 +54,20 @@ int *t6() { void t7() { new int(); } + +struct U { + ~U(); +}; + +void t8(int n) { + new int[10]; + new int[n]; + + // Non-POD + new T[10]; + new T[n]; + + // Cookie required + new U[10]; + new U[n]; +} diff --git a/test/CodeGenCXX/nullptr.cpp b/test/CodeGenCXX/nullptr.cpp new file mode 100644 index 000000000000..7bc52ad5210a --- /dev/null +++ b/test/CodeGenCXX/nullptr.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -std=c++0x %s -emit-llvm -o %t + +int* a = nullptr; + +void f() { + int* a = nullptr; +} diff --git a/test/CodeGenCXX/overload-binop-implicitconvert.cpp b/test/CodeGenCXX/overload-binop-implicitconvert.cpp new file mode 100644 index 000000000000..f17a4585e69f --- /dev/null +++ b/test/CodeGenCXX/overload-binop-implicitconvert.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc %s -emit-llvm-only +class T +{}; + +void print(const char *t); + +T& operator<< (T& t,const char* c) +{ + print(c); + return t; +} + + +int main() +{ + T t; + print("foo"); + t<<"foo"; + + return 0; +} + diff --git a/test/CodeGenCXX/predefined-expr-sizeof.cpp b/test/CodeGenCXX/predefined-expr-sizeof.cpp new file mode 100644 index 000000000000..e318fbec18ae --- /dev/null +++ b/test/CodeGenCXX/predefined-expr-sizeof.cpp @@ -0,0 +1,30 @@ +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s + +// CHECK: store i32 49, i32* %size +// CHECK: store i32 52, i32* %size +template<typename T> +class TemplateClass { +public: + void templateClassFunction() { + int size = sizeof(__PRETTY_FUNCTION__); + } +}; + +// CHECK: store i32 27, i32* %size +// CHECK: store i32 30, i32* %size +template<typename T> +void functionTemplate(T t) { + int size = sizeof(__PRETTY_FUNCTION__); +} + +int main() { + TemplateClass<int> t1; + t1.templateClassFunction(); + TemplateClass<double> t2; + t2.templateClassFunction(); + + functionTemplate<int>(0); + functionTemplate(0.0); + + return 0; +} diff --git a/test/CodeGenCXX/predefined-expr.cpp b/test/CodeGenCXX/predefined-expr.cpp new file mode 100644 index 000000000000..95bc255bdde0 --- /dev/null +++ b/test/CodeGenCXX/predefined-expr.cpp @@ -0,0 +1,226 @@ +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s + +// CHECK: private constant [15 x i8] c"externFunction\00" +// CHECK: private constant [26 x i8] c"void NS::externFunction()\00" + +// CHECK: private constant [22 x i8] c"classTemplateFunction\00" +// CHECK: private constant [60 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction()\00" +// CHECK: private constant [53 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction()\00" + +// CHECK: private constant [18 x i8] c"functionTemplate1\00" +// CHECK: private constant [45 x i8] c"void NS::Base::functionTemplate1(NS::Base *)\00" +// CHECK: private constant [38 x i8] c"void NS::Base::functionTemplate1(int)\00" + +// CHECK: private constant [12 x i8] c"~Destructor\00" +// CHECK: private constant [35 x i8] c"void NS::Destructor::~Destructor()\00" + +// CHECK: private constant [12 x i8] c"Constructor\00" +// CHECK: private constant [46 x i8] c"void NS::Constructor::Constructor(NS::Base *)\00" +// CHECK: private constant [39 x i8] c"void NS::Constructor::Constructor(int)\00" +// CHECK: private constant [36 x i8] c"void NS::Constructor::Constructor()\00" + +// CHECK: private constant [16 x i8] c"virtualFunction\00" +// CHECK: private constant [44 x i8] c"virtual void NS::Derived::virtualFunction()\00" + +// CHECK: private constant [26 x i8] c"functionReturingTemplate2\00" +// CHECK: private constant [64 x i8] c"ClassTemplate<NS::Base *> NS::Base::functionReturingTemplate2()\00" + +// CHECK: private constant [26 x i8] c"functionReturingTemplate1\00" +// CHECK: private constant [57 x i8] c"ClassTemplate<int> NS::Base::functionReturingTemplate1()\00" + +// CHECK: private constant [23 x i8] c"withTemplateParameter2\00" +// CHECK: private constant [65 x i8] c"void NS::Base::withTemplateParameter2(ClassTemplate<NS::Base *>)\00" + +// CHECK: private constant [23 x i8] c"withTemplateParameter1\00" +// CHECK: private constant [58 x i8] c"void NS::Base::withTemplateParameter1(ClassTemplate<int>)\00" + +// CHECK: private constant [23 x i8] c"functionReturningClass\00" +// CHECK: private constant [45 x i8] c"NS::Base *NS::Base::functionReturningClass()\00" + +// CHECK: private constant [23 x i8] c"functionWithParameters\00" +// CHECK: private constant [64 x i8] c"void NS::Base::functionWithParameters(int, float *, NS::Base *)\00" + +// CHECK: private constant [17 x i8] c"variadicFunction\00" +// CHECK: private constant [42 x i8] c"void NS::Base::variadicFunction(int, ...)\00" + +// CHECK: private constant [41 x i8] c"virtual void NS::Base::virtualFunction()\00" + +// CHECK: private constant [15 x i8] c"inlineFunction\00" +// CHECK: private constant [32 x i8] c"void NS::Base::inlineFunction()\00" + +// CHECK: private constant [11 x i8] c"staticFunc\00" +// CHECK: private constant [28 x i8] c"void NS::Base::staticFunc()\00" + +int printf(const char * _Format, ...); + +namespace NS { + +template<typename T> +class ClassTemplate { +public: + void classTemplateFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } +}; + +class Base { +public: + static void staticFunc() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } + + inline void inlineFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } + + virtual void virtualFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } + + void functionWithParameters(int, float*, Base* base) { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } + + Base *functionReturningClass() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + return 0; + } + + void variadicFunction(int, ...) { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } + + void withTemplateParameter1(ClassTemplate<int>) { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } + + void withTemplateParameter2(ClassTemplate<Base *>) { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } + + ClassTemplate<int> functionReturingTemplate1() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + return ClassTemplate<int>(); + } + + ClassTemplate<Base *> functionReturingTemplate2() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + return ClassTemplate<Base *>(); + } + + template<typename T> + void functionTemplate1(T t) { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } +}; + +class Derived : public Base { +public: + // Virtual function without being explicitally written. + void virtualFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } +}; + +class Constructor { +public: + Constructor() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } + + Constructor(int) { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } + + Constructor(Base *) { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } + +}; + +class Destructor { +public: + ~Destructor() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); + } +}; + +extern void externFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); +} + +} + +int main() { + NS::Base::staticFunc(); + + NS::Base b; + b.inlineFunction(); + b.virtualFunction(); + b.variadicFunction(0); + b.functionWithParameters(0, 0, 0); + b.functionReturningClass(); + + b.withTemplateParameter1(NS::ClassTemplate<int>()); + b.withTemplateParameter2(NS::ClassTemplate<NS::Base *>()); + b.functionReturingTemplate1(); + b.functionReturingTemplate2(); + b.functionTemplate1<int>(0); + b.functionTemplate1<NS::Base *>(0); + + NS::Derived d; + d.virtualFunction(); + + NS::ClassTemplate<int> t1; + t1.classTemplateFunction(); + NS::ClassTemplate<NS::Base *> t2; + t2.classTemplateFunction(); + + NS::Constructor c1; + NS::Constructor c2(0); + NS::Constructor c3((NS::Base *)0); + + { + NS::Destructor destructor; + } + + NS::externFunction(); + + return 0; +} diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp index 8e1935675766..c235521d43b1 100644 --- a/test/CodeGenCXX/references.cpp +++ b/test/CodeGenCXX/references.cpp @@ -87,3 +87,16 @@ int reference_decl() { const int& b = 1; return a+b; } + +struct A { + int& b(); +}; + +void f(A* a) { + int b = a->b(); +} + +// PR5122 +void *foo = 0; +void * const & kFoo = foo; + diff --git a/test/CodeGenCXX/reinterpret-cast.cpp b/test/CodeGenCXX/reinterpret-cast.cpp new file mode 100644 index 000000000000..ae3ab2f8b0d7 --- /dev/null +++ b/test/CodeGenCXX/reinterpret-cast.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc -emit-llvm -o - %s -std=c++0x +void *f1(unsigned long l) { + return reinterpret_cast<void *>(l); +} + +unsigned long f2() { + return reinterpret_cast<unsigned long>(nullptr); +} + +unsigned long f3(void *p) { + return reinterpret_cast<unsigned long>(p); +}
\ No newline at end of file diff --git a/test/CodeGenCXX/static-data-member.cpp b/test/CodeGenCXX/static-data-member.cpp new file mode 100644 index 000000000000..6e2abcc1adea --- /dev/null +++ b/test/CodeGenCXX/static-data-member.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -emit-llvm -o - %s +struct S { + static int i; +}; + +void f() { + int a = S::i; +} diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp new file mode 100644 index 000000000000..44dd14284107 --- /dev/null +++ b/test/CodeGenCXX/static-init.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -triple=x86_64-apple-darwin9 -emit-llvm %s -o %t && +// RUN: grep "call void @_ZN1AC1Ev" %t | count 1 && +// RUN: grep "call i32 @__cxa_atexit(void (i8\*)\* bitcast (void (%.truct.A\*)\* @_ZN1AD1Ev to void (i8\*)\*), i8\* getelementptr inbounds (%.truct.A\* @_ZZ1fvE1a, i32 0, i32 0), i8\* bitcast (i8\*\* @__dso_handle to i8\*))" %t | count 1 + +struct A { + A(); + ~A(); +}; + +void f() { + static A a; +} + diff --git a/test/CodeGenCXX/temp-1.cpp b/test/CodeGenCXX/temp-1.cpp new file mode 100644 index 000000000000..9b97f0083c83 --- /dev/null +++ b/test/CodeGenCXX/temp-1.cpp @@ -0,0 +1,83 @@ +// RUN: clang-cc -emit-llvm %s -o %t -triple=x86_64-apple-darwin9 && +struct A { + A(); + ~A(); + void f(); +}; + +// RUN: grep "call void @_ZN1AC1Ev" %t | count 2 && +// RUN: grep "call void @_ZN1AD1Ev" %t | count 2 && +void f1() { + (void)A(); + A().f(); +} + +// Function calls +struct B { + B(); + ~B(); +}; + +B g(); + +// RUN: grep "call void @_ZN1BC1Ev" %t | count 0 && +// RUN: grep "call void @_ZN1BD1Ev" %t | count 1 && +void f2() { + (void)g(); +} + +// Member function calls +struct C { + C(); + ~C(); + + C f(); +}; + +// RUN: grep "call void @_ZN1CC1Ev" %t | count 1 && +// RUN: grep "call void @_ZN1CD1Ev" %t | count 2 && +void f3() { + C().f(); +} + +// Function call operator +struct D { + D(); + ~D(); + + D operator()(); +}; + +// RUN: grep "call void @_ZN1DC1Ev" %t | count 1 && +// RUN: grep "call void @_ZN1DD1Ev" %t | count 2 && +void f4() { + D()(); +} + +// Overloaded operators +struct E { + E(); + ~E(); + E operator+(const E&); + E operator!(); +}; + +// RUN: grep "call void @_ZN1EC1Ev" %t | count 3 && +// RUN: grep "call void @_ZN1ED1Ev" %t | count 5 && +void f5() { + E() + E(); + !E(); +} + +struct F { + F(); + ~F(); + F& f(); +}; + +// RUN: grep "call void @_ZN1FC1Ev" %t | count 1 && +// RUN: grep "call void @_ZN1FD1Ev" %t | count 1 +void f6() { + F().f(); +} + diff --git a/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp b/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp new file mode 100644 index 000000000000..f8454282badc --- /dev/null +++ b/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm -o %t %s +template <typename T> +class A +{ + union { void *d; }; + + A() : d(0) { } +}; + +A<int> a0; diff --git a/test/CodeGenCXX/trivial-constructor-init.cpp b/test/CodeGenCXX/trivial-constructor-init.cpp new file mode 100644 index 000000000000..183b31a801e3 --- /dev/null +++ b/test/CodeGenCXX/trivial-constructor-init.cpp @@ -0,0 +1,21 @@ +// RUN: clang-cc -S %s -o %t-64.s && +// RUN: clang-cc -S %s -o %t-32.s && +// RUN: true + +extern "C" int printf(...); + +struct S { + S() { printf("S::S\n"); } +}; + +struct A { + double x; + A() : x(), y(), s() { printf("x = %f y = %x \n", x, y); } + int *y; + S s; +}; + +A a; + +int main() { +} diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp new file mode 100644 index 000000000000..9ae81e5d3f33 --- /dev/null +++ b/test/CodeGenCXX/virt.cpp @@ -0,0 +1,1024 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -O0 -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -O0 -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 -input-file=%t-32.s %s && + +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -O3 -S %s -o %t-O3-64.s && +// RUN: FileCheck -check-prefix LPOPT64 --input-file=%t-O3-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -O3 -S %s -o %t-O3-32.s && +// RUN: FileCheck -check-prefix LPOPT32 -input-file=%t-O3-32.s %s && + +// RUN: true + +struct B { + virtual void bar1(); + virtual void bar2(); + int b; +}; +void B::bar1() { } +void B::bar2() { } + +struct C { + virtual void bee1(); + virtual void bee2(); +}; +void C::bee1() { } +void C::bee2() { } + +struct D { + virtual void boo(); +}; +void D::boo() { } + +struct D1 { + virtual void bar(); + virtual void bar2(); + virtual void bar3(); + virtual void bar4(); + virtual void bar5(); + void *d1; +}; +void D1::bar() { } + +class F : virtual public D1, virtual public D { +public: + virtual void foo(); + void *f; +}; +void F::foo() { } + +int j; +void test2() { + F f; + static int sz = (char *)(&f.f) - (char *)(&f); + j = sz; + // FIXME: These should result in a frontend constant a la fold, no run time + // initializer + // CHECK-LPOPT32: movl $4, __ZZ5test2vE2sz + // CHECK-LPOPT64: movl $8, __ZZ5test2vE2sz(%rip) +} + +static_assert(sizeof(F) == sizeof(void*)*4, "invalid vbase size"); + +struct E { + int e; +}; + +static_assert (sizeof (C) == (sizeof(void *)), "vtable pointer layout"); + +class A : public E, public B, public C { +public: + virtual void foo1(); + virtual void foo2(); + A() { } + int a; +} *ap; +void A::foo1() { } +void A::foo2() { } + +int main() { + A a; + B b; + ap->e = 1; + ap->b = 2; +} + +// CHECK-LP32: main: +// CHECK-LP32: movl $1, 8(%eax) +// CHECK-LP32: movl $2, 4(%eax) + +// CHECK-LP64: main: +// CHECK-LP64: movl $1, 12(%rax) +// CHECK-LP64: movl $2, 8(%rax) + +struct test12_A { + virtual void foo0() { } + virtual void foo(); +} *test12_pa; + +struct test12_B : public test12_A { + virtual void foo() { } +} *test12_pb; + +struct test12_D : public test12_B { +} *test12_pd; +void test12_foo() { + test12_pa->foo0(); + test12_pb->foo0(); + test12_pd->foo0(); + test12_pa->foo(); + test12_pb->foo(); + test12_pd->foo(); + test12_pa->test12_A::foo(); +} + +// CHECK-LPOPT32:__Z10test12_foov: +// CHECK-LPOPT32: movl _test12_pa, %eax +// CHECK-LPOPT32-NEXT: movl (%eax), %ecx +// CHECK-LPOPT32-NEXT: movl %eax, (%esp) +// CHECK-LPOPT32-NEXT: call *(%ecx) +// CHECK-LPOPT32-NEXT: movl _test12_pb, %eax +// CHECK-LPOPT32-NEXT: movl (%eax), %ecx +// CHECK-LPOPT32-NEXT: movl %eax, (%esp) +// CHECK-LPOPT32-NEXT: call *(%ecx) +// CHECK-LPOPT32-NEXT: movl _test12_pd, %eax +// CHECK-LPOPT32-NEXT: movl (%eax), %ecx +// CHECK-LPOPT32-NEXT: movl %eax, (%esp) +// CHECK-LPOPT32-NEXT: call *(%ecx) +// CHECK-LPOPT32-NEXT: movl _test12_pa, %eax +// CHECK-LPOPT32-NEXT: movl (%eax), %ecx +// CHECK-LPOPT32-NEXT: movl %eax, (%esp) +// CHECK-LPOPT32-NEXT: call *4(%ecx) +// CHECK-LPOPT32-NEXT: movl _test12_pb, %eax +// CHECK-LPOPT32-NEXT: movl (%eax), %ecx +// CHECK-LPOPT32-NEXT: movl %eax, (%esp) +// CHECK-LPOPT32-NEXT: call *4(%ecx) +// CHECK-LPOPT32-NEXT: movl _test12_pd, %eax +// CHECK-LPOPT32-NEXT: movl (%eax), %ecx +// CHECK-LPOPT32-NEXT: movl %eax, (%esp) +// CHECK-LPOPT32-NEXT: call *4(%ecx) +// CHECK-LPOPT32-NEXT: movl _test12_pa, %eax +// CHECK-LPOPT32-NEXT: movl %eax, (%esp) +// CHECK-LPOPT32-NEXT: call L__ZN8test12_A3fooEv$stub + +// CHECK-LPOPT64:__Z10test12_foov: +// CHECK-LPOPT64: movq _test12_pa(%rip), %rdi +// CHECK-LPOPT64-NEXT: movq (%rdi), %rax +// CHECK-LPOPT64-NEXT: call *(%rax) +// CHECK-LPOPT64-NEXT: movq _test12_pb(%rip), %rdi +// CHECK-LPOPT64-NEXT: movq (%rdi), %rax +// CHECK-LPOPT64-NEXT: call *(%rax) +// CHECK-LPOPT64-NEXT: movq _test12_pd(%rip), %rdi +// CHECK-LPOPT64-NEXT: movq (%rdi), %rax +// CHECK-LPOPT64-NEXT: call *(%rax) +// CHECK-LPOPT64-NEXT: movq _test12_pa(%rip), %rdi +// CHECK-LPOPT64-NEXT: movq (%rdi), %rax +// CHECK-LPOPT64-NEXT: call *8(%rax) +// CHECK-LPOPT64-NEXT: movq _test12_pb(%rip), %rdi +// CHECK-LPOPT64-NEXT: movq (%rdi), %rax +// CHECK-LPOPT64-NEXT: call *8(%rax) +// CHECK-LPOPT64-NEXT: movq _test12_pd(%rip), %rdi +// CHECK-LPOPT64-NEXT: movq (%rdi), %rax +// CHECK-LPOPT64-NEXT: call *8(%rax) +// CHECK-LPOPT64-NEXT: movq _test12_pa(%rip), %rdi +// CHECK-LPOPT64-NEXT: call __ZN8test12_A3fooEv + +struct test6_B2 { virtual void funcB2(); char b[1000]; }; +struct test6_B1 : virtual test6_B2 { virtual void funcB1(); }; + +struct test6_D : test6_B2, virtual test6_B1 { +}; + +// CHECK-LP32: .zerofill __DATA, __common, _d6, 2012, 4 +// CHECK-LP64: .zerofill __DATA, __common, _d6, 2024, 4 + +struct test7_B2 { virtual void funcB2(); }; +struct test7_B1 : virtual test7_B2 { virtual void funcB1(); }; + +struct test7_D : test7_B2, virtual test7_B1 { +}; + +// CHECK-LP32: .zerofill __DATA, __common, _d7, 8, 3 +// CHECK-LP64: .zerofill __DATA, __common, _d7, 16, 3 + + +struct test3_B3 { virtual void funcB3(); }; +struct test3_B2 : virtual test3_B3 { virtual void funcB2(); }; +struct test3_B1 : virtual test3_B2 { virtual void funcB1(); }; + +struct test3_D : virtual test3_B1 { + virtual void funcD() { } +}; + +// CHECK-LP32:__ZTV7test3_D: +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI7test3_D +// CHECK-LP32-NEXT: .long __ZN8test3_B36funcB3Ev +// CHECK-LP32-NEXT: .long __ZN8test3_B26funcB2Ev +// CHECK-LP32-NEXT: .long __ZN8test3_B16funcB1Ev +// CHECK-LP32-NEXT: .long __ZN7test3_D5funcDEv + +// CHECK-LP64:__ZTV7test3_D: +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI7test3_D +// CHECK-LP64-NEXT: .quad __ZN8test3_B36funcB3Ev +// CHECK-LP64-NEXT: .quad __ZN8test3_B26funcB2Ev +// CHECK-LP64-NEXT: .quad __ZN8test3_B16funcB1Ev +// CHECK-LP64-NEXT: .quad __ZN7test3_D5funcDEv + +struct test4_D : virtual B, virtual C { +}; + +// CHECK-LP32:__ZTV7test4_D: +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI7test4_D +// CHECK-LP32-NEXT: .long __ZN1C4bee1Ev +// CHECK-LP32-NEXT: .long __ZN1C4bee2Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967292 +// CHECK-LP32-NEXT: .long __ZTI7test4_D +// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev +// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev + +// CHECK-LP64:__ZTV7test4_D: +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI7test4_D +// CHECK-LP64-NEXT: .quad __ZN1C4bee1Ev +// CHECK-LP64-NEXT: .quad __ZN1C4bee2Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .quad __ZTI7test4_D +// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev +// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev + + +struct test5_B3 { virtual void funcB3(); }; +struct test5_B2 : virtual test5_B3 { virtual void funcB2(); }; +struct test5_B1 : virtual test5_B2 { virtual void funcB1(); }; + +struct test5_B23 { virtual void funcB23(); }; +struct test5_B22 : virtual test5_B23 { virtual void funcB22(); }; +struct test5_B21 : virtual test5_B22 { virtual void funcB21(); }; + + +struct B232 { virtual void funcB232(); }; +struct B231 { virtual void funcB231(); }; + +struct test5_B33 { virtual void funcB33(); }; +struct test5_B32 : virtual test5_B33, virtual B232 { virtual void funcB32(); }; +struct test5_B31 : virtual test5_B32, virtual B231 { virtual void funcB31(); }; + +struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 { + virtual void funcD() { } +}; + +// CHECK-LP32:__ZTV7test5_D: +// CHECK-LP32-NEXT: .long 16 +// CHECK-LP32-NEXT: .long 12 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 4 +// CHECK-LP32-NEXT: .long 4 +// CHECK-LP32-NEXT: .long 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI7test5_D +// CHECK-LP32-NEXT: .long __ZN8test5_B36funcB3Ev +// CHECK-LP32-NEXT: .long __ZN8test5_B26funcB2Ev +// CHECK-LP32-NEXT: .long __ZN8test5_B16funcB1Ev +// CHECK-LP32-NEXT: .long __ZN7test5_D5funcDEv +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967292 +// CHECK-LP32-NEXT: .long __ZTI7test5_D +// CHECK-LP32-NEXT: .long __ZN9test5_B237funcB23Ev +// CHECK-LP32-NEXT: .long __ZN9test5_B227funcB22Ev +// CHECK-LP32-NEXT: .long __ZN9test5_B217funcB21Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32: .long 8 +// CHECK-LP32 .space 4 +// CHECK-LP32 .space 4 FIXME +// CHECK-LP32: .long 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967288 +// CHECK-LP32-NEXT: .long __ZTI7test5_D +// CHECK-LP32-NEXT: .long __ZN9test5_B337funcB33Ev +// CHECK-LP32-NEXT: .long __ZN9test5_B327funcB32Ev +// CHECK-LP32-NEXT: .long __ZN9test5_B317funcB31Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967284 +// CHECK-LP32-NEXT: .long __ZTI7test5_D +// CHECK-LP32-NEXT: .long __ZN4B2328funcB232Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967280 +// CHECK-LP32-NEXT: .long __ZTI7test5_D +// CHECK-LP32-NEXT: .long __ZN4B2318funcB231Ev + +// CHECK-LP64:__ZTV7test5_D: +// CHECK-LP64-NEXT: .quad 32 +// CHECK-LP64-NEXT: .quad 24 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 8 +// CHECK-LP64-NEXT: .quad 8 +// CHECK-LP64-NEXT: .quad 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI7test5_D +// CHECK-LP64-NEXT: .quad __ZN8test5_B36funcB3Ev +// CHECK-LP64-NEXT: .quad __ZN8test5_B26funcB2Ev +// CHECK-LP64-NEXT: .quad __ZN8test5_B16funcB1Ev +// CHECK-LP64-NEXT: .quad __ZN7test5_D5funcDEv +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .quad __ZTI7test5_D +// CHECK-LP64-NEXT: .quad __ZN9test5_B237funcB23Ev +// CHECK-LP64-NEXT: .quad __ZN9test5_B227funcB22Ev +// CHECK-LP64-NEXT: .quad __ZN9test5_B217funcB21Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64: .quad 16 +// CHECK-LP64 .space 8 +// CHECK-LP64 .space 8 +// CHECK-LP64: .quad 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551600 +// CHECK-LP64-NEXT: .quad __ZTI7test5_D +// CHECK-LP64-NEXT: .quad __ZN9test5_B337funcB33Ev +// CHECK-LP64-NEXT: .quad __ZN9test5_B327funcB32Ev +// CHECK-LP64-NEXT: .quad __ZN9test5_B317funcB31Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551592 +// CHECK-LP64-NEXT: .quad __ZTI7test5_D +// CHECK-LP64-NEXT: .quad __ZN4B2328funcB232Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551584 +// CHECK-LP64-NEXT: .quad __ZTI7test5_D +// CHECK-LP64-NEXT: .quad __ZN4B2318funcB231Ev + +struct test8_B1 { + virtual void ftest8_B1() { } +}; +struct test8_B2aa { + virtual void ftest8_B2aa() { } + int i; +}; +struct test8_B2ab { + virtual void ftest8_B2ab() { } + int i; +}; +struct test8_B2a : virtual test8_B2aa, virtual test8_B2ab { + virtual void ftest8_B2a() { } +}; +struct test8_B2b { + virtual void ftest8_B2b() { } +}; +struct test8_B2 : test8_B2a, test8_B2b { + virtual void ftest8_B2() { } +}; +struct test8_B3 { + virtual void ftest8_B3() { } +}; +class test8_D : test8_B1, test8_B2, test8_B3 { +}; + +// CHECK-LP32:__ZTV7test8_D: +// CHECK-LP32-NEXT: .long 24 +// CHECK-LP32-NEXT: .long 16 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI7test8_D +// CHECK-LP32-NEXT: .long __ZN8test8_B19ftest8_B1Ev +// CHECK-LP32-NEXT: .long 20 +// CHECK-LP32-NEXT: .long 12 +// CHECK-LP32-NEXT: .long 4294967292 +// CHECK-LP32-NEXT: .long __ZTI7test8_D +// CHECK-LP32-NEXT: .long __ZN9test8_B2a10ftest8_B2aEv +// CHECK-LP32-NEXT: .long __ZN8test8_B29ftest8_B2Ev +// CHECK-LP32-NEXT: .long 4294967288 +// CHECK-LP32-NEXT: .long __ZTI7test8_D +// CHECK-LP32-NEXT: .long __ZN9test8_B2b10ftest8_B2bEv +// CHECK-LP32-NEXT: .long 4294967284 +// CHECK-LP32-NEXT: .long __ZTI7test8_D +// CHECK-LP32-NEXT: .long __ZN8test8_B39ftest8_B3Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967280 +// CHECK-LP32-NEXT: .long __ZTI7test8_D +// CHECK-LP32-NEXT: .long __ZN10test8_B2aa11ftest8_B2aaEv +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967272 +// CHECK-LP32-NEXT: .long __ZTI7test8_D +// CHECK-LP32-NEXT: .long __ZN10test8_B2ab11ftest8_B2abEv + +// CHECK-LP64:__ZTV7test8_D: +// CHECK-LP64-NEXT: .quad 48 +// CHECK-LP64-NEXT: .quad 32 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI7test8_D +// CHECK-LP64-NEXT: .quad __ZN8test8_B19ftest8_B1Ev +// CHECK-LP64-NEXT: .quad 40 +// CHECK-LP64-NEXT: .quad 24 +// CHECK-LP64-NEXT: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .quad __ZTI7test8_D +// CHECK-LP64-NEXT: .quad __ZN9test8_B2a10ftest8_B2aEv +// CHECK-LP64-NEXT: .quad __ZN8test8_B29ftest8_B2Ev +// CHECK-LP64-NEXT: .quad 18446744073709551600 +// CHECK-LP64-NEXT: .quad __ZTI7test8_D +// CHECK-LP64-NEXT: .quad __ZN9test8_B2b10ftest8_B2bEv +// CHECK-LP64-NEXT: .quad 18446744073709551592 +// CHECK-LP64-NEXT: .quad __ZTI7test8_D +// CHECK-LP64-NEXT: .quad __ZN8test8_B39ftest8_B3Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551584 +// CHECK-LP64-NEXT: .quad __ZTI7test8_D +// CHECK-LP64-NEXT: .quad __ZN10test8_B2aa11ftest8_B2aaEv +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551568 +// CHECK-LP64-NEXT: .quad __ZTI7test8_D +// CHECK-LP64-NEXT: .quad __ZN10test8_B2ab11ftest8_B2abEv + + +struct test9_B3 { virtual void funcB3(); int i; }; +struct test9_B2 : virtual test9_B3 { virtual void funcB2(); int i; }; +struct test9_B1 : virtual test9_B2 { virtual void funcB1(); int i; }; + +struct test9_B23 { virtual void funcB23(); int i; }; +struct test9_B22 : virtual test9_B23 { virtual void funcB22(); int i; }; +struct test9_B21 : virtual test9_B22 { virtual void funcB21(); int i; }; + + +struct test9_B232 { virtual void funcB232(); int i; }; +struct test9_B231 { virtual void funcB231(); int i; }; + +struct test9_B33 { virtual void funcB33(); int i; }; +struct test9_B32 : virtual test9_B33, virtual test9_B232 { virtual void funcB32(); int i; }; +struct test9_B31 : virtual test9_B32, virtual test9_B231 { virtual void funcB31(); int i; }; + +struct test9_D : virtual test9_B1, virtual test9_B21, virtual test9_B31 { + virtual void funcD() { } +}; + +// CHECK-LP64: __ZTV7test9_D: +// CHECK-LP64-NEXT: .quad 168 +// CHECK-LP64-NEXT: .quad 152 +// CHECK-LP64-NEXT: .quad 136 +// CHECK-LP64-NEXT: .quad 120 +// CHECK-LP64-NEXT: .quad 104 +// CHECK-LP64-NEXT: .quad 88 +// CHECK-LP64-NEXT: .quad 72 +// CHECK-LP64-NEXT: .quad 56 +// CHECK-LP64-NEXT: .quad 40 +// CHECK-LP64-NEXT: .quad 24 +// CHECK-LP64-NEXT: .quad 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN7test9_D5funcDEv +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 32 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN8test9_B16funcB1Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 18446744073709551592 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN8test9_B26funcB2Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551576 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN8test9_B36funcB3Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 32 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 18446744073709551560 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN9test9_B217funcB21Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 18446744073709551544 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN9test9_B227funcB22Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551528 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN9test9_B237funcB23Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 64 +// CHECK-LP64-NEXT: .quad 48 +// CHECK-LP64-NEXT: .quad 32 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 18446744073709551512 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN9test9_B317funcB31Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 32 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 18446744073709551496 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN9test9_B327funcB32Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551480 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN9test9_B337funcB33Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551464 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN10test9_B2328funcB232Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551448 +// CHECK-LP64-NEXT: .quad __ZTI7test9_D +// CHECK-LP64-NEXT: .quad __ZN10test9_B2318funcB231Ev + +// CHECK-LP32: __ZTV7test9_D: +// CHECK-LP32-NEXT: .long 84 +// CHECK-LP32-NEXT: .long 76 +// CHECK-LP32-NEXT: .long 68 +// CHECK-LP32-NEXT: .long 60 +// CHECK-LP32-NEXT: .long 52 +// CHECK-LP32-NEXT: .long 44 +// CHECK-LP32-NEXT: .long 36 +// CHECK-LP32-NEXT: .long 28 +// CHECK-LP32-NEXT: .long 20 +// CHECK-LP32-NEXT: .long 12 +// CHECK-LP32-NEXT: .long 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN7test9_D5funcDEv +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 16 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 4294967292 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN8test9_B16funcB1Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 4294967284 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN8test9_B26funcB2Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967276 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN8test9_B36funcB3Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 16 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 4294967268 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN9test9_B217funcB21Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 4294967260 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN9test9_B227funcB22Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967252 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN9test9_B237funcB23Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 32 +// CHECK-LP32-NEXT: .long 24 +// CHECK-LP32-NEXT: .long 16 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 4294967244 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN9test9_B317funcB31Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 16 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 4294967236 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN9test9_B327funcB32Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967228 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN9test9_B337funcB33Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967220 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN10test9_B2328funcB232Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967212 +// CHECK-LP32-NEXT: .long __ZTI7test9_D +// CHECK-LP32-NEXT: .long __ZN10test9_B2318funcB231Ev + +struct test10_O { int i; }; + +struct test10_B1 : virtual test10_O { + virtual void ftest10_B1() { } +}; + +struct test10_B2aa : virtual test10_O { + int i; +}; +struct test10_B2ab : virtual test10_O { + int i; +}; +struct test10_B2a : virtual test10_B2aa, virtual test10_B2ab,virtual test10_O { + virtual void ftest10_B2a() { } +}; +struct test10_B2b : virtual test10_O { + virtual void ftest10_B2b() { } +}; +struct test10_B2 : test10_B2a { + virtual void ftest10_B2() { } +}; +class test10_D : test10_B1, test10_B2 { + + void ftest10_B2aa() { } +}; + +// CHECK-LP64:__ZTV8test10_D: +// CHECK-LP64-NEXT: .quad 40 +// CHECK-LP64-NEXT: .quad 24 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI8test10_D +// CHECK-LP64-NEXT: .quad __ZN9test10_B110ftest10_B1Ev +// CHECK-LP64-NEXT: .quad 32 +// CHECK-LP64-NEXT: .quad 8 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .quad __ZTI8test10_D +// CHECK-LP64-NEXT: .quad __ZN10test10_B2a11ftest10_B2aEv +// CHECK-LP64-NEXT: .quad __ZN9test10_B210ftest10_B2Ev +// CHECK-LP64-NEXT: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .quad 18446744073709551592 +// CHECK-LP64-NEXT: .quad __ZTI8test10_D +// CHECK-LP64-NEXT: .quad 18446744073709551592 +// CHECK-LP64-NEXT: .quad 18446744073709551576 +// CHECK-LP64-NEXT: .quad __ZTI8test10_D + +// CHECK-LP32: __ZTV8test10_D: +// CHECK-LP32-NEXT: .long 20 +// CHECK-LP32-NEXT: .long 12 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI8test10_D +// CHECK-LP32-NEXT: .long __ZN9test10_B110ftest10_B1Ev +// CHECK-LP32-NEXT: .long 16 +// CHECK-LP32-NEXT: .long 4 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 4294967292 +// CHECK-LP32-NEXT: .long __ZTI8test10_D +// CHECK-LP32-NEXT: .long __ZN10test10_B2a11ftest10_B2aEv +// CHECK-LP32-NEXT: .long __ZN9test10_B210ftest10_B2Ev +// CHECK-LP32-NEXT: .long 4294967292 +// CHECK-LP32-NEXT: .long 4294967284 +// CHECK-LP32-NEXT: .long __ZTI8test10_D +// CHECK-LP32-NEXT: .long 4294967284 +// CHECK-LP32-NEXT: .long 4294967276 +// CHECK-LP32-NEXT: .long __ZTI8test10_D + +struct test11_B { + virtual void B1() { } + virtual void D() { } + virtual void B2() { } +}; + +struct test11_D : test11_B { + virtual void D1() { } + virtual void D() { } + virtual void D2() { } +}; + +// CHECK-LP32:__ZTV8test11_D: +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI8test11_D +// CHECK-LP32-NEXT: .long __ZN8test11_B2B1Ev +// CHECK-LP32-NEXT: .long __ZN8test11_D1DEv +// CHECK-LP32-NEXT: .long __ZN8test11_B2B2Ev +// CHECK-LP32-NEXT: .long __ZN8test11_D2D1Ev +// CHECK-LP32-NEXT: .long __ZN8test11_D2D2Ev + + +// CHECK-LP64:__ZTV8test11_D: +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI8test11_D +// CHECK-LP64-NEXT: .quad __ZN8test11_B2B1Ev +// CHECK-LP64-NEXT: .quad __ZN8test11_D1DEv +// CHECK-LP64-NEXT: .quad __ZN8test11_B2B2Ev +// CHECK-LP64-NEXT: .quad __ZN8test11_D2D1Ev +// CHECK-LP64-NEXT: .quad __ZN8test11_D2D2Ev + +struct test13_B { + virtual void B1() { } + virtual void D() { } + virtual void Da(); + virtual void Db() { } + virtual void Dc() { } + virtual void B2() { } + int i; +}; + + +struct test13_NV1 { + virtual void fooNV1() { } + virtual void D() { } +}; + + +struct test13_B2 : /* test13_NV1, */ virtual test13_B { + virtual void B2a() { } + virtual void B2() { } + virtual void D() { } + virtual void Da(); + virtual void Dd() { } + virtual void B2b() { } + int i; +}; + + +struct test13_D : test13_NV1, virtual test13_B2 { + virtual void D1() { } + virtual void D() { } + virtual void Db() { } + virtual void Dd() { } + virtual void D2() { } + virtual void fooNV1() { } +}; + +// CHECK-LP64:__ZTV8test13_D: +// CHECK-LP64-NEXT: .quad 24 +// CHECK-LP64-NEXT: .quad 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI8test13_D +// CHECK-LP64-NEXT: .quad __ZN8test13_D6fooNV1Ev +// CHECK-LP64-NEXT: .quad __ZN8test13_D1DEv +// CHECK-LP64-NEXT: .quad __ZN8test13_D2D1Ev +// CHECK-LP64-NEXT: .quad __ZN8test13_D2DbEv +// CHECK-LP64-NEXT: .quad __ZN8test13_D2DdEv +// CHECK-LP64-NEXT: .quad __ZN8test13_D2D2Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .quad __ZTI8test13_D +// CHECK-LP64-NEXT: .quad __ZN9test13_B23B2aEv +// CHECK-LP64-NEXT: .quad __ZN9test13_B22B2Ev +// CHECK-LP64-NEXT: .quad __ZTv0_n48_N8test13_D1DEv +// CHECK-LP64-NEXT: .quad __ZN9test13_B22DaEv +// CHECK-LP64-NEXT: .quad __ZTv0_n64_N8test13_D2DdEv +// CHECK-LP64-NEXT: .quad __ZN9test13_B23B2bEv +// CHECK-LP64-NEXT: .quad 18446744073709551600 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551592 +// CHECK-LP64-NEXT: .quad 18446744073709551600 +// CHECK-LP64-NEXT: .quad 18446744073709551592 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551592 +// CHECK-LP64-NEXT: .quad __ZTI8test13_D +// CHECK-LP64-NEXT: .quad __ZN8test13_B2B1Ev +// CHECK-LP64-NEXT: .quad __ZTv0_n32_N8test13_D1DEv +// CHECK-LP64-NEXT: .quad __ZTv0_n40_N9test13_B22DaEv +// CHECK-LP64-NEXT: .quad __ZTv0_n48_N8test13_D2DbEv +// CHECK-LP64-NEXT: .quad __ZN8test13_B2DcEv +// CHECK-LP64-NEXT: .quad __ZTv0_n64_N9test13_B22B2Ev + +// CHECK-LP32:__ZTV8test13_D: +// CHECK-LP32-NEXT: .long 12 +// CHECK-LP32-NEXT: .long 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI8test13_D +// CHECK-LP32-NEXT: .long __ZN8test13_D6fooNV1Ev +// CHECK-LP32-NEXT: .long __ZN8test13_D1DEv +// CHECK-LP32-NEXT: .long __ZN8test13_D2D1Ev +// CHECK-LP32-NEXT: .long __ZN8test13_D2DbEv +// CHECK-LP32-NEXT: .long __ZN8test13_D2DdEv +// CHECK-LP32-NEXT: .long __ZN8test13_D2D2Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967292 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967292 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 4294967292 +// CHECK-LP32-NEXT: .long __ZTI8test13_D +// CHECK-LP32-NEXT: .long __ZN9test13_B23B2aEv +// CHECK-LP32-NEXT: .long __ZN9test13_B22B2Ev +// CHECK-LP32-NEXT: .long __ZTv0_n24_N8test13_D1DEv +// CHECK-LP32-NEXT: .long __ZN9test13_B22DaEv +// CHECK-LP32-NEXT: .long __ZTv0_n32_N8test13_D2DdEv +// CHECK-LP32-NEXT: .long __ZN9test13_B23B2bEv +// CHECK-LP32-NEXT: .long 4294967288 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967284 +// CHECK-LP32-NEXT: .long 4294967288 +// CHECK-LP32-NEXT: .long 4294967284 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967284 +// CHECK-LP32-NEXT: .long __ZTI8test13_D +// CHECK-LP32-NEXT: .long __ZN8test13_B2B1Ev +// CHECK-LP32-NEXT: .long __ZTv0_n16_N8test13_D1DEv +// CHECK-LP32-NEXT: .long __ZTv0_n20_N9test13_B22DaEv +// CHECK-LP32-NEXT: .long __ZTv0_n24_N8test13_D2DbEv +// CHECK-LP32-NEXT: .long __ZN8test13_B2DcEv +// CHECK-LP32-NEXT: .long __ZTv0_n32_N9test13_B22B2Ev + + +class test14 { +public: + virtual void initWithInt(int a); + static test14 *withInt(int a); +}; + +void test14::initWithInt(int a) { } + +test14 *test14::withInt(int a) { + test14 *me = new test14; + me->initWithInt(a); + return me; +} + + +struct test15_B { + virtual test15_B *foo1() { return 0; } + virtual test15_B *foo2() { return 0; } + virtual test15_B *foo3() { return 0; } + int i; +}; + +struct test15_NV1 { + virtual void fooNV1() { } + int i; +}; + +struct test15_B2 : test15_NV1, virtual test15_B { + virtual test15_B2 *foo1() { return 0; } + virtual test15_B2 *foo2() { return 0; } + int i; +}; + +struct test15_D : test15_NV1, virtual test15_B2 { + virtual test15_D *foo1() { return 0; } +}; + +// CHECK-LP64:__ZTV8test15_D: +// CHECK-LP64-NEXT: .quad 32 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI8test15_D +// CHECK-LP64-NEXT: .quad __ZN10test15_NV16fooNV1Ev +// CHECK-LP64-NEXT: .quad __ZN8test15_D4foo1Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551600 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 18446744073709551600 +// CHECK-LP64-NEXT: .quad __ZTI8test15_D +// CHECK-LP64-NEXT: .quad __ZN10test15_NV16fooNV1Ev +// CHECK-LP64-NEXT: .quad __ZTcv0_n40_v0_n24_N8test15_D4foo1Ev +// CHECK-LP64-NEXT: .quad __ZN9test15_B24foo2Ev +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551600 +// CHECK-LP64-NEXT: .quad 18446744073709551584 +// CHECK-LP64-NEXT: .quad 18446744073709551584 +// CHECK-LP64-NEXT: .quad __ZTI8test15_D +// CHECK-LP64-NEXT: .quad __ZTcv0_n24_v0_n32_N8test15_D4foo1Ev +// CHECK-LP64-NEXT: .quad __ZTcv0_n32_v0_n24_N9test15_B24foo2Ev +// CHECK-LP64-NEXT: .quad __ZN8test15_B4foo3Ev + +// CHECK-LP32:__ZTV8test15_D: +// CHECK-LP32-NEXT: .long 20 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI8test15_D +// CHECK-LP32-NEXT: .long __ZN10test15_NV16fooNV1Ev +// CHECK-LP32-NEXT: .long __ZN8test15_D4foo1Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967288 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 12 +// CHECK-LP32-NEXT: .long 4294967288 +// CHECK-LP32-NEXT: .long __ZTI8test15_D +// CHECK-LP32-NEXT: .long __ZN10test15_NV16fooNV1Ev +// CHECK-LP32-NEXT: .long __ZTcv0_n20_v0_n12_N8test15_D4foo1Ev +// CHECK-LP32-NEXT: .long __ZN9test15_B24foo2Ev +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967284 +// CHECK-LP32-NEXT: .long 4294967276 +// CHECK-LP32-NEXT: .long 4294967276 +// CHECK-LP32-NEXT: .long __ZTI8test15_D +// CHECK-LP32-NEXT: .long __ZTcv0_n12_v0_n16_N8test15_D4foo1Ev +// CHECK-LP32-NEXT: .long __ZTcv0_n16_v0_n12_N9test15_B24foo2Ev +// CHECK-LP32-NEXT: .long __ZN8test15_B4foo3Ev + + + +// CHECK-LP64: __ZTV1B: +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI1B +// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev +// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev + +// CHECK-LP32: __ZTV1B: +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI1B +// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev +// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev + +// CHECK-LP64: __ZTV1A: +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI1A +// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev +// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev +// CHECK-LP64-NEXT: .quad __ZN1A4foo1Ev +// CHECK-LP64-NEXT: .quad __ZN1A4foo2Ev +// CHECK-LP64-NEXT: .quad 18446744073709551600 +// CHECK-LP64-NEXT: .quad __ZTI1A +// CHECK-LP64-NEXT: .quad __ZN1C4bee1Ev +// CHECK-LP64-NEXT: .quad __ZN1C4bee2Ev + +// CHECK-LP32: __ZTV1A: +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI1A +// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev +// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev +// CHECK-LP32-NEXT: .long __ZN1A4foo1Ev +// CHECK-LP32-NEXT: .long __ZN1A4foo2Ev +// CHECK-LP32-NEXT: .long 4294967284 +// CHECK-LP32-NEXT: .long __ZTI1A +// CHECK-LP32-NEXT: .long __ZN1C4bee1Ev +// CHECK-LP32-NEXT: .long __ZN1C4bee2Ev + +// CHECK-LP32:__ZTV1F: +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long __ZTI1F +// CHECK-LP32-NEXT: .long __ZN1D3booEv +// CHECK-LP32-NEXT: .long __ZN1F3fooEv +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32-NEXT: .long 4294967288 +// CHECK-LP32-NEXT: .long __ZTI1F +// CHECK-LP32-NEXT: .long __ZN2D13barEv +// CHECK-LP32-NEXT: .long __ZN2D14bar2Ev +// CHECK-LP32-NEXT: .long __ZN2D14bar3Ev +// CHECK-LP32-NEXT: .long __ZN2D14bar4Ev +// CHECK-LP32-NEXT: .long __ZN2D14bar5Ev + +// CHECK-LP64: __ZTV1F: +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI1F +// CHECK-LP64-NEXT: .quad __ZN1D3booEv +// CHECK-LP64-NEXT: .quad __ZN1F3fooEv +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551600 +// CHECK-LP64-NEXT: .quad __ZTI1F +// CHECK-LP64-NEXT: .quad __ZN2D13barEv +// CHECK-LP64-NEXT: .quad __ZN2D14bar2Ev +// CHECK-LP64-NEXT: .quad __ZN2D14bar3Ev +// CHECK-LP64-NEXT: .quad __ZN2D14bar4Ev +// CHECK-LP64-NEXT: .quad __ZN2D14bar5Ev + +test15_D d15; +test13_D d13; +test11_D d11; +test10_D d10; +test9_D d9; +test8_D d8; + +test5_D d5; +test4_D d4; +test3_D d3; + +test6_D d6; +test7_D d7; diff --git a/test/CodeGenCXX/virtual-base-cast.cpp b/test/CodeGenCXX/virtual-base-cast.cpp new file mode 100644 index 000000000000..a825120ad229 --- /dev/null +++ b/test/CodeGenCXX/virtual-base-cast.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc -emit-llvm-only %s + +struct A { virtual ~A(); }; +struct B : A { virtual ~B(); }; +struct C : virtual B { virtual ~C(); }; + +void f(C *c) { + A* a = c; +} diff --git a/test/CodeGenCXX/virtual-function-calls.cpp b/test/CodeGenCXX/virtual-function-calls.cpp new file mode 100644 index 000000000000..ca5acbabcc99 --- /dev/null +++ b/test/CodeGenCXX/virtual-function-calls.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s + +// PR5021 +struct A { + virtual void f(char); +}; + +void f(A *a) { + // CHECK: call void % + a->f('c'); +} diff --git a/test/CodeGenCXX/vtable-cast-crash.cpp b/test/CodeGenCXX/vtable-cast-crash.cpp new file mode 100644 index 000000000000..a91d9790fe65 --- /dev/null +++ b/test/CodeGenCXX/vtable-cast-crash.cpp @@ -0,0 +1,21 @@ +// RUN: clang-cc -emit-llvm-only %s +struct A +{ +A(); +virtual ~A(); +}; + +struct B: A +{ + B(); + ~B(); +}; + +B::B() +{ +} + +B::~B() +{ +} + diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp new file mode 100644 index 000000000000..426c867a7b6b --- /dev/null +++ b/test/CodeGenCXX/x86_64-arguments.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o %t %s && +struct A { ~A(); }; + +// RUN: grep 'define void @_Z2f11A(.struct.A\* .a)' %t && +void f1(A a) { } + +// RUN: grep 'define void @_Z2f2v(.struct.A\* noalias sret .agg.result)' %t && +A f2() { return A(); } + +// RUN: true diff --git a/test/CodeGenObjC/PR4541.m b/test/CodeGenObjC/PR4541.m new file mode 100644 index 000000000000..9a651162c1e1 --- /dev/null +++ b/test/CodeGenObjC/PR4541.m @@ -0,0 +1,19 @@ +// RUN: clang-cc -o %t -w -g %s + + +@class NSString; +@interface NSAttributedString +- (NSString *)string; +@end +@interface NSMutableAttributedString : NSAttributedString +@end +@class NSImage; +@implementation CYObjectsController ++ (void)initialize { +} ++ (NSAttributedString *)attributedStringWithString:(id)string image:(NSImage *)image { + NSMutableAttributedString *attrStr; +} +@end + + diff --git a/test/CodeGenObjC/PR4894-recursive-debug-crash.m b/test/CodeGenObjC/PR4894-recursive-debug-crash.m new file mode 100644 index 000000000000..c5f901c2680e --- /dev/null +++ b/test/CodeGenObjC/PR4894-recursive-debug-crash.m @@ -0,0 +1,40 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -g -emit-llvm %s -o - | FileCheck %s +// PR4894 +// +// This test is actually just making sure we can generate the debug info for the +// return type from im0 without crashing. +// XFAIL + +@interface I0 { + I0 *_iv0; +} +@end +@protocol P0 @end + +@interface I1 @end +@implementation I1 +- (I0<P0> *) im0 { +// CHECK: @"\01-[I1 im0]" +// CHECK: llvm.dbg.func.start + return 0; +} +@end + +// FIXME: This was another PR4894 test case, which is crashing somewhere +// else. PR5025. +#if 0 +typedef const struct objc_selector { + void *sel_id; + const char *sel_types; +} *SEL; + +@interface I2 ++(id) dictionary; +@end + +@implementation I3; ++(void) initialize { + I2 *a0 = [I2 dictionary]; +} +@end +#endif diff --git a/test/CodeGenObjC/constant-strings.m b/test/CodeGenObjC/constant-strings.m index d4fefd903653..82cd916b5ca8 100644 --- a/test/CodeGenObjC/constant-strings.m +++ b/test/CodeGenObjC/constant-strings.m @@ -1,4 +1,6 @@ -// RUN: clang-cc -fnext-runtime -emit-llvm -o %t %s +// RUN: clang-cc -fnext-runtime -emit-llvm -o %t %s && +// RUN: clang-cc -fgnu-runtime -emit-llvm -o %t %s && grep NXConstantString %t | count 1 && +// RUN: clang-cc -fgnu-runtime -fconstant-string-class=NSConstantString -emit-llvm -o %t %s && grep NSConstantString %t | count 1 id a = @"Hello World!"; diff --git a/test/CodeGenObjC/debug-info-linkagename.m b/test/CodeGenObjC/debug-info-linkagename.m new file mode 100644 index 000000000000..730568954cb0 --- /dev/null +++ b/test/CodeGenObjC/debug-info-linkagename.m @@ -0,0 +1,17 @@ +// RUN: clang-cc -g -S -o %t %s && +// RUN: not grep 001 %t + +@interface F +-(int) bar; +@end + +@implementation F +-(int) bar { + return 42; +} +@end + +extern int f(F *fn) { + return [fn bar]; +} + diff --git a/test/CodeGenObjC/for-in.m b/test/CodeGenObjC/for-in.m new file mode 100644 index 000000000000..434ff796b335 --- /dev/null +++ b/test/CodeGenObjC/for-in.m @@ -0,0 +1,44 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +void p(const char*, ...); + +@interface NSArray ++(NSArray*) arrayWithObjects: (id) first, ...; +-(unsigned) count; +@end +@interface NSString +-(const char*) cString; +@end + +#define S(n) @#n +#define L1(n) S(n+0),S(n+1) +#define L2(n) L1(n+0),L1(n+2) +#define L3(n) L2(n+0),L2(n+4) +#define L4(n) L3(n+0),L3(n+8) +#define L5(n) L4(n+0),L4(n+16) +#define L6(n) L5(n+0),L5(n+32) + +void t0() { + NSArray *array = [NSArray arrayWithObjects: L1(0), (void*)0]; + + p("array.length: %d\n", [array count]); + unsigned index = 0; + for (NSString *i in array) { + p("element %d: %s\n", index++, [i cString]); + } +} + +void t1() { + NSArray *array = [NSArray arrayWithObjects: L6(0), (void*)0]; + + p("array.length: %d\n", [array count]); + unsigned index = 0; + for (NSString *i in array) { + index++; + if (index == 10) + continue; + p("element %d: %s\n", index, [i cString]); + if (index == 55) + break; + } +} diff --git a/test/CodeGenObjC/ivar-layout-64-bitfields.m b/test/CodeGenObjC/ivar-layout-64-bitfields.m new file mode 100644 index 000000000000..cb5611835f62 --- /dev/null +++ b/test/CodeGenObjC/ivar-layout-64-bitfields.m @@ -0,0 +1,40 @@ +// RUN: clang-cc -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s +@interface I +{ + struct { + unsigned int d : 1; + } bitfield; +} +@end + +@implementation I +@end + +@interface J +{ + struct { + unsigned short _reserved : 16; + + _Bool _draggedNodesAreDeletable: 1; + _Bool _draggedOutsideOutlineView : 1; + _Bool _adapterRespondsTo_addRootPaths : 1; + _Bool _adapterRespondsTo_moveDataNodes : 1; + _Bool _adapterRespondsTo_removeRootDataNode : 1; + _Bool _adapterRespondsTo_doubleClickDataNode : 1; + _Bool _adapterRespondsTo_selectDataNode : 1; + _Bool _adapterRespondsTo_textDidEndEditing : 1; + + _Bool _adapterRespondsTo_updateAndSaveRoots : 1; + _Bool _adapterRespondsTo_askToDeleteRootNodes : 1; + _Bool _adapterRespondsTo_contextMenuForSelectedNodes : 1; + _Bool _adapterRespondsTo_pasteboardFilenamesForNodes : 1; + _Bool _adapterRespondsTo_writeItemsToPasteboard : 1; + _Bool _adapterRespondsTo_writeItemsToPasteboardXXXX : 1; + } _flags; +} +@end + +@implementation J +@end + + diff --git a/test/CodeGenObjC/ivar-layout-no-optimize.m b/test/CodeGenObjC/ivar-layout-no-optimize.m new file mode 100644 index 000000000000..d7796bc279e1 --- /dev/null +++ b/test/CodeGenObjC/ivar-layout-no-optimize.m @@ -0,0 +1,18 @@ +// RUN: clang-cc -fobjc-gc -triple x86_64-apple-darwin -O0 -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: true + +@interface NSObject { + id isa; +} +@end + +@interface AllPointers : NSObject { + id foo; + void *__strong bar; NSObject *bletch;} +@end +@implementation AllPointers +@end + +// CHECK-LP64: L_OBJC_CLASS_NAME_6: +// CHECK-LP64-NEXT: .asciz "\004" diff --git a/test/CodeGenObjC/messages.m b/test/CodeGenObjC/messages.m index f9b9be6e11a3..b7f42d126d2b 100644 --- a/test/CodeGenObjC/messages.m +++ b/test/CodeGenObjC/messages.m @@ -2,8 +2,8 @@ // RUN: grep "objc_msgSend" %t | count 6 && // RUN: clang-cc -fgnu-runtime --emit-llvm -o %t %s && // RUN: grep "objc_msg_lookup" %t | count 6 && -// RUN: clang-cc -fgnu-runtime -fobjc-sender-dependent-dispatch --emit-llvm -o %t %s && -// RUN: grep "objc_msg_lookup_sender" %t | count 6 +// RUN: clang-cc -fgnu-runtime -fobjc-nonfragile-abi --emit-llvm -o %t %s && +// RUN: grep "objc_msg_lookup_sender" %t | count 6 && // RUN: true typedef struct { diff --git a/test/CodeGenObjC/objc-assign-ivar.m b/test/CodeGenObjC/objc-assign-ivar.m new file mode 100644 index 000000000000..f79faaf23826 --- /dev/null +++ b/test/CodeGenObjC/objc-assign-ivar.m @@ -0,0 +1,53 @@ +// RUN: clang-cc -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s && +// RUN: grep -F '@objc_assign_ivar' %t | count 14 && +// RUN: true + +typedef struct { + id element; + id elementArray[10]; + __strong id cfElement; + __strong id cfElementArray[10]; +} struct_with_ids_t; + + +@interface NSString @end + +@interface Foo { +@public +// assignments to any/all of these fields should generate objc_assign_ivar + __strong id dict; + __strong id dictArray[3]; + id ivar; + id array[10]; + id nsobject; + NSString *stringArray[10]; + struct_with_ids_t inner; + + Foo *obj[20]; + short idx[5]; +} +@end + +// The test cases +int IvarAssigns; +void *rhs = 0; +#define ASSIGNTEST(expr, global) expr = rhs + +void testIvars() { + Foo *foo; + ASSIGNTEST(foo->ivar, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->dict, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->dictArray[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->array[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->nsobject, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->stringArray[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.element, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.elementArray[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.cfElement, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.cfElementArray[0], IvarAssigns); // objc_assign_ivar + int counter=1; + ASSIGNTEST(foo->obj[5], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->obj[++counter], IvarAssigns); // objc_assign_ivar + foo->idx[++counter] = 15; + ASSIGNTEST(foo->obj[foo->idx[2]], IvarAssigns); // objc_assign_ivar +} diff --git a/test/CodeGenObjC/objc-gc-aggr-assign.m b/test/CodeGenObjC/objc-gc-aggr-assign.m new file mode 100644 index 000000000000..96a9fdf65409 --- /dev/null +++ b/test/CodeGenObjC/objc-gc-aggr-assign.m @@ -0,0 +1,46 @@ +// RUN: clang-cc -fnext-runtime -fobjc-gc -emit-llvm -o %t %s && +// RUN: grep objc_memmove_collectable %t | grep call | count 3 + +static int count; + +typedef struct S { + int ii; +} SS; + +struct type_s { + SS may_recurse; + id id_val; +}; + +@interface NamedObject +{ + struct type_s type_s_ivar; +} +- (void) setSome : (struct type_s) arg; +- (struct type_s) getSome; +@property(assign) struct type_s aggre_prop; +@end + +@implementation NamedObject +- (void) setSome : (struct type_s) arg + { + type_s_ivar = arg; + } +- (struct type_s) getSome + { + return type_s_ivar; + } +@synthesize aggre_prop = type_s_ivar; +@end + +struct type_s some = {{1234}, (id)0}; + +struct type_s get(void) +{ + return some; +} + +void f(const struct type_s *in, struct type_s *out) { + *out = *in; +} + diff --git a/test/CodeGenObjC/objc-read-weak-byref.m b/test/CodeGenObjC/objc-read-weak-byref.m new file mode 100644 index 000000000000..7c297be56679 --- /dev/null +++ b/test/CodeGenObjC/objc-read-weak-byref.m @@ -0,0 +1,26 @@ +// RUN: clang-cc -fblocks -fobjc-gc -triple x86_64-apple-darwin -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -fblocks -fobjc-gc -triple i386-apple-darwin -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +@interface NSObject +- copy; +@end + +int main() { + NSObject *object = 0; + __weak __block NSObject* weak_object = object; + void (^callback) (void) = [^{ + if (weak_object) + [weak_object copy]; + } copy]; + callback(); + return 0; +} + +// CHECK-LP64: call _objc_read_weak +// CHECK-LP64: call _objc_read_weak + +// CHECK-LP32: call L_objc_read_weak +// CHECK-LP32: call L_objc_read_weak diff --git a/test/CodeGenObjC/objc2-assign-global.m b/test/CodeGenObjC/objc2-assign-global.m index ae407619093e..9b6b4151f6a0 100644 --- a/test/CodeGenObjC/objc2-assign-global.m +++ b/test/CodeGenObjC/objc2-assign-global.m @@ -1,8 +1,81 @@ -// RUN: clang-cc -fnext-runtime -fobjc-gc -emit-llvm -o %t %s && -// RUN: grep -F '@objc_assign_global' %t | count 2 && +// RUN: clang-cc -triple x86_64-apple-darwin10 -fnext-runtime -fobjc-gc -emit-llvm -o %t %s && +// RUN: grep -F '@objc_assign_global' %t | count 26 && // RUN: true -id a; + +@class NSObject; +typedef const struct __CFDictionary * CFDictionaryRef; +typedef struct { + id element; + id elementArray[10]; + __strong CFDictionaryRef cfElement; + __strong CFDictionaryRef cfElementArray[10]; +} struct_with_ids_t; + + +// assignments to these should generate objc_assign_global +@interface A +@end + +typedef struct s0 { + A *a[4]; +} T; + +T g0; + +extern id FileExternID; +static id FileStaticID; +id GlobalId; +id GlobalArray[20]; +NSObject *GlobalObject; +NSObject *GlobalObjectArray[20]; +__strong CFDictionaryRef Gdict; +__strong CFDictionaryRef Gdictarray[10]; +struct_with_ids_t GlobalStruct; +struct_with_ids_t GlobalStructArray[10]; + +#define ASSIGNTEST(expr, global) expr = rhs +void *rhs = 0; + int main() { - a = 0; -} + static id staticGlobalId; + static id staticGlobalArray[20]; + static NSObject *staticGlobalObject; + static NSObject *staticGlobalObjectArray[20]; + static __strong CFDictionaryRef staticGdict; + static __strong CFDictionaryRef staticGdictarray[10]; + static struct_with_ids_t staticGlobalStruct; + static struct_with_ids_t staticGlobalStructArray[10]; + extern id ExID; + id localID; + + ASSIGNTEST(GlobalId, GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalObject, GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalObjectArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(Gdict, GlobalAssigns); // objc_assign_global + ASSIGNTEST(Gdictarray[1], GlobalAssigns); // objc_assign_global + + ASSIGNTEST(GlobalStruct.element, GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalStruct.elementArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalStruct.cfElement, GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalStruct.cfElementArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalId, GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalObject, GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalObjectArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGdict, GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGdictarray[1], GlobalAssigns); // objc_assign_global + + ASSIGNTEST(staticGlobalStruct.element, GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalStruct.elementArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalStruct.cfElement, GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalStruct.cfElementArray[0], GlobalAssigns); // objc_assign_global + + ExID = 0; + localID = 0; + FileStaticID = 0; + FileExternID=0; + g0.a[0] = 0; + ((T*) &g0)->a[0] = 0; +} diff --git a/test/CodeGenObjC/objc2-ivar-assign.m b/test/CodeGenObjC/objc2-ivar-assign.m new file mode 100644 index 000000000000..cfdf87f2f12b --- /dev/null +++ b/test/CodeGenObjC/objc2-ivar-assign.m @@ -0,0 +1,41 @@ +// RUN: clang-cc -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s && +// RUN: grep objc_assign_ivar %t | count 6 && +// RUN: true + +@interface I @end + +typedef I TI; +typedef I* TPI; + +typedef id ID; + +@interface MyClass { +} + +@property id property; +@property I* propertyI; + +@property TI* propertyTI; + +@property TPI propertyTPI; + +@property ID propertyID; +@end + +@implementation MyClass + @synthesize property=_property; + @synthesize propertyI; + @synthesize propertyTI=_propertyTI; + @synthesize propertyTPI=_propertyTPI; + @synthesize propertyID = _propertyID; +@end + +int main () { + MyClass *myObj; + myObj.property = 0; + myObj.propertyI = 0; + myObj.propertyTI = 0; + myObj.propertyTPI = 0; + myObj.propertyID = 0; + return 0; +} diff --git a/test/CodeGenObjC/objc2-new-gc-api-strongcast.m b/test/CodeGenObjC/objc2-new-gc-api-strongcast.m new file mode 100644 index 000000000000..6a1aea6a7340 --- /dev/null +++ b/test/CodeGenObjC/objc2-new-gc-api-strongcast.m @@ -0,0 +1,26 @@ +// RUN: clang-cc -triple x86_64-apple-darwin10 -fblocks -fnext-runtime -fobjc-gc -emit-llvm -o %t %s && +// RUN: grep -F '@objc_assign_strongCast' %t | count 4 && +// RUN: true + +@interface DSATextSearch @end + +DSATextSearch **_uniqueIdToIdentifierArray = ((void *)0); +void foo (int _nextId) +{ + _uniqueIdToIdentifierArray[_nextId] = 0; // objc_assign_strongCast +} + +typedef struct { + unsigned long state; + id *itemsPtr; + void (^bp)(); + unsigned long *mutationsPtr; + unsigned long extra[5]; +} NSFastEnumerationState; + +void foo1 (NSFastEnumerationState * state) +{ + state->itemsPtr = 0; + state->bp = ^{}; +} + diff --git a/test/CodeGenObjC/objc2-weak-assign.m b/test/CodeGenObjC/objc2-weak-assign.m index a3740b207e85..635ca38df46c 100644 --- a/test/CodeGenObjC/objc2-weak-assign.m +++ b/test/CodeGenObjC/objc2-weak-assign.m @@ -9,6 +9,10 @@ __weak id* a1[20]; id* __weak a2[30]; id** __weak a3[40]; +void foo (__weak id *param) { + *param = 0; +} + int main() { *x = 0; diff --git a/test/CodeGenObjC/objc2-weak-ivar-debug.m b/test/CodeGenObjC/objc2-weak-ivar-debug.m new file mode 100644 index 000000000000..24a7757b9acf --- /dev/null +++ b/test/CodeGenObjC/objc2-weak-ivar-debug.m @@ -0,0 +1,15 @@ +// RUN: clang-cc -triple x86_64-apple-darwin9 -fobjc-gc -g -emit-llvm -o - %s && +// RUN: clang-cc -triple i386-apple-darwin9 -fobjc-gc -g -emit-llvm -o - %s + +// rdar://7252252 +@interface Loop { +@public + __weak Loop *_loop; +} +@end + +@implementation Loop @end + +void loop(Loop *L) { + L->_loop = 0; +} diff --git a/test/CodeGenObjC/objc2-write-barrier-2.m b/test/CodeGenObjC/objc2-write-barrier-2.m new file mode 100644 index 000000000000..c47224f1c516 --- /dev/null +++ b/test/CodeGenObjC/objc2-write-barrier-2.m @@ -0,0 +1,80 @@ +// RUN: clang-cc -triple x86_64-apple-darwin10 -fnext-runtime -fobjc-gc -emit-llvm -o %t %s && +// RUN: grep -F '@objc_assign_global' %t | count 7 && +// RUN: grep -F '@objc_assign_ivar' %t | count 5 && +// RUN: grep -F '@objc_assign_strongCast' %t | count 8 && +// RUN: true + +extern id **somefunc(void); +extern id *somefunc2(void); + + +// Globals + +id W, *X, **Y; + +void func(id a, id *b, id **c) { + static id w, *x, **y; + W = a; + w = a; + X = b; + x = b; + Y = c; + y = c; +} + +// Instances + +@interface something { + id w, *x, **y; +} +@end + +@implementation something +- (void)amethod { + id badIdea = *somefunc2(); + w = badIdea; + x = &badIdea; + y = &x; +} +@end + +typedef struct { + int junk; + id alfred; +} AStruct; + +void funct2(AStruct *aptr) { + id **ppptr = somefunc(); + aptr->alfred = 0; + **ppptr = aptr->alfred; + *ppptr = somefunc2(); +} + +typedef const struct __CFString * CFStringRef; +@interface DSATextSearch { +__strong CFStringRef *_documentNames; + struct { + id *innerNames; + struct { + id *nestedDeeperNames; + struct I { + id *is1; + id is2[5]; + } arrI [3]; + } inner_most; + } inner; + +} +- filter; +@end +@implementation DSATextSearch +- filter { + int filteredPos = 0; + _documentNames[filteredPos] = 0; // storing into an element of array ivar. objc_assign_strongCast is needed. + inner.innerNames[filteredPos] = 0; + inner.inner_most.nestedDeeperNames[filteredPos] = 0; + inner.inner_most.arrI[3].is1[5] = 0; + inner.inner_most.arrI[3].is2[5] = 0; +} +@end + diff --git a/test/CodeGenObjC/objc2-write-barrier-3.m b/test/CodeGenObjC/objc2-write-barrier-3.m new file mode 100644 index 000000000000..2fb416b79b2f --- /dev/null +++ b/test/CodeGenObjC/objc2-write-barrier-3.m @@ -0,0 +1,47 @@ +// RUN: clang-cc -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s && +// RUN: grep objc_assign_ivar %t | count 3 && +// RUN: grep objc_assign_strongCast %t | count 6 && +// RUN: true + +struct Slice { + void *__strong * items; +}; + +typedef struct Slice Slice; + +@interface ISlice { +@public + void *__strong * IvarItem; +} +@end + +typedef void (^observer_block_t)(id object); +@interface Observer { +@public + observer_block_t block; +} +@end + + +void foo (int i) { + // storing into an array of strong pointer types. + void *__strong* items; + items[i] = 0; + + // storing indirectly into an array of strong pointer types. + void *__strong* *vitems; + *vitems[i] = 0; + + Slice *slice; + slice->items = 0; + // storing into a struct element of an array of strong pointer types. + slice->items[i] = 0; + + ISlice *islice; + islice->IvarItem = 0; + // Storing into an ivar of an array of strong pointer types. + islice->IvarItem[i] = (void*)0; + + Observer *observer; + observer->block = 0; +} diff --git a/test/CodeGenObjC/objc2-write-barrier-4.m b/test/CodeGenObjC/objc2-write-barrier-4.m new file mode 100644 index 000000000000..f96a233787b0 --- /dev/null +++ b/test/CodeGenObjC/objc2-write-barrier-4.m @@ -0,0 +1,28 @@ +// RUN: clang-cc -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s && +// RUN: grep objc_assign_global %t | count 3 && +// RUN: grep objc_assign_strongCast %t | count 2 && +// RUN: true + +@interface A +@end + +typedef struct s0 { + A *a[4]; +} T; + +T g0; + +void f0(id x) { + g0.a[0] = x; +} + +void f1(id x) { + ((T*) &g0)->a[0] = x; +} + +void f2(unsigned idx) +{ + id *keys; + keys[idx] = 0; +} + diff --git a/test/CodeGenObjC/objc2-write-barrier-5.m b/test/CodeGenObjC/objc2-write-barrier-5.m new file mode 100644 index 000000000000..5b8f02cc1e16 --- /dev/null +++ b/test/CodeGenObjC/objc2-write-barrier-5.m @@ -0,0 +1,27 @@ +// RUN: clang-cc -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s && +// RUN: grep objc_assign_ivar %t | count 0 && +// RUN: grep objc_assign_strongCast %t | count 5 && +// RUN: true + +@interface TestUnarchiver +{ + void *allUnarchivedObjects; +} +@end + +@implementation TestUnarchiver + +struct unarchive_list { + int ifield; + id *list; +}; + +- (id)init { + (*((struct unarchive_list *)allUnarchivedObjects)).list = 0; + ((struct unarchive_list *)allUnarchivedObjects)->list = 0; + (**((struct unarchive_list **)allUnarchivedObjects)).list = 0; + (*((struct unarchive_list **)allUnarchivedObjects))->list = 0; + return 0; +} + +@end diff --git a/test/CodeGenObjC/objc2-write-barrier.m b/test/CodeGenObjC/objc2-write-barrier.m new file mode 100644 index 000000000000..53fa10a7a75f --- /dev/null +++ b/test/CodeGenObjC/objc2-write-barrier.m @@ -0,0 +1,114 @@ +// RUN: clang-cc -triple x86_64-apple-darwin10 -fnext-runtime -fobjc-gc -emit-llvm -o %t %s && +// RUN: grep -F '@objc_assign_global' %t | count 21 && +// RUN: grep -F '@objc_assign_ivar' %t | count 11 && +// RUN: true + + +typedef const struct __CFDictionary * CFDictionaryRef; + +// callouts to these are generated with cc -fobjc-gc + +int GlobalAssigns; +int IvarAssigns; +int StrongCastAssigns; + + +// The test case elements; +@class NSObject; +@class NSString; + +typedef struct { + id element; + id elementArray[10]; + __strong CFDictionaryRef cfElement; + __strong CFDictionaryRef cfElementArray[10]; +} struct_with_ids_t; + +@interface Foo { +@public +// assignments to any/all of these fields should generate objc_assign_ivar + __strong CFDictionaryRef dict; + __strong CFDictionaryRef dictArray[3]; + id ivar; + id array[10]; + NSObject *nsobject; + NSString *stringArray[10]; + struct_with_ids_t inner; +} + +@end + +// assignments to these should generate objc_assign_global +id GlobalId; +id GlobalArray[20]; +NSObject *GlobalObject; +NSObject *GlobalObjectArray[20]; +__strong CFDictionaryRef Gdict; +__strong CFDictionaryRef Gdictarray[10]; +struct_with_ids_t GlobalStruct; +struct_with_ids_t GlobalStructArray[10]; + + +// The test cases +void *rhs = 0; + +#define ASSIGNTEST(expr, global) expr = rhs + +int testGlobals() { + // Everything in this function generates assign_global intercepts + int counter = 0; + + static id staticGlobalId; + static id staticGlobalArray[20]; + static NSObject *staticGlobalObject; + static NSObject *staticGlobalObjectArray[20]; + static __strong CFDictionaryRef staticGdict; + static __strong CFDictionaryRef staticGdictarray[10]; + static struct_with_ids_t staticGlobalStruct; + static struct_with_ids_t staticGlobalStructArray[10]; + + ASSIGNTEST(GlobalId, GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalObject, GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalObjectArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(Gdict, GlobalAssigns); // objc_assign_global + ASSIGNTEST(Gdictarray[1], GlobalAssigns); // objc_assign_global + + ASSIGNTEST(GlobalStruct.element, GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalStruct.elementArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalStruct.cfElement, GlobalAssigns); // objc_assign_global + ASSIGNTEST(GlobalStruct.cfElementArray[0], GlobalAssigns); // objc_assign_global + + ASSIGNTEST(staticGlobalId, GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalObject, GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalObjectArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGdict, GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGdictarray[1], GlobalAssigns); // objc_assign_global + + ASSIGNTEST(staticGlobalStruct.element, GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalStruct.elementArray[0], GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalStruct.cfElement, GlobalAssigns); // objc_assign_global + ASSIGNTEST(staticGlobalStruct.cfElementArray[0], GlobalAssigns); // objc_assign_global + + return counter; +} + + +int testIvars() { + Foo *foo; + int counter = 0; + + ASSIGNTEST(foo->ivar, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->dict, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->dictArray[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->array[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->nsobject, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->stringArray[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.element, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.elementArray[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.cfElement, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.cfElementArray[0], IvarAssigns); // objc_assign_ivar + + return counter; +} diff --git a/test/CodeGenObjC/object-incr-decr-1.m b/test/CodeGenObjC/object-incr-decr-1.m new file mode 100644 index 000000000000..53311f7aa18c --- /dev/null +++ b/test/CodeGenObjC/object-incr-decr-1.m @@ -0,0 +1,19 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -fnext-runtime -emit-llvm %s -o %t + +@interface Foo +{ + double d1,d3,d4; +} +@end + +Foo* foo() +{ + Foo *f; + + // Both of these crash clang nicely + ++f; + --f; + f--; + f++; + return f; +} diff --git a/test/CodeGenObjC/overloadable.m b/test/CodeGenObjC/overloadable.m index 972dc4ed5895..7e9cc3d3b36d 100644 --- a/test/CodeGenObjC/overloadable.m +++ b/test/CodeGenObjC/overloadable.m @@ -4,7 +4,7 @@ @class C; // RUN: grep _Z1fP11objc_object %t | count 1 && -void __attribute__((overloadable)) f(C *c) { } +void __attribute__((overloadable)) f(id c) { } // RUN: grep _Z1fP1C %t | count 1 -void __attribute__((overloadable)) f(id c) { } +void __attribute__((overloadable)) f(C *c) { } diff --git a/test/CodeGenObjC/predefined-expr.m b/test/CodeGenObjC/predefined-expr.m new file mode 100644 index 000000000000..b27bb3488a5a --- /dev/null +++ b/test/CodeGenObjC/predefined-expr.m @@ -0,0 +1,90 @@ +// RUN: clang-cc -triple i386-apple-darwin9 %s -emit-llvm -o - | FileCheck %s + +// CHECK: @"__func__.-[Foo instanceTest1]" = private constant [21 x i8] c"-[Foo instanceTest1]\00" +// CHECK: @"__func__.-[Foo instanceTest2:]" = private constant [22 x i8] c"-[Foo instanceTest2:]\00" +// CHECK: @"__func__.-[Foo instanceTest3:withB:]" = private constant [28 x i8] c"-[Foo instanceTest3:withB:]\00" +// CHECK: @"__func__.-[Foo instanceTest4]" = private constant [21 x i8] c"-[Foo instanceTest4]\00" +// CHECK: @"__func__.+[Foo classTest1]" = private constant [18 x i8] c"+[Foo classTest1]\00" +// CHECK: @"__func__.+[Foo classTest2:]" = private constant [19 x i8] c"+[Foo classTest2:]\00" +// CHECK: @"__func__.+[Foo classTest3:withB:]" = private constant [25 x i8] c"+[Foo classTest3:withB:]\00" +// CHECK: @"__func__.+[Foo classTest4]" = private constant [18 x i8] c"+[Foo classTest4]\00" +// CHECK: @"__func__.-[Foo(Category) instanceTestWithCategory]" = private constant [42 x i8] c"-[Foo(Category) instanceTestWithCategory]\00" +// CHECK: @"__func__.+[Foo(Category) classTestWithCategory]" = private constant [39 x i8] c"+[Foo(Category) classTestWithCategory]\00" + +int printf(const char * _Format, ...); + +@interface Foo +@end + +@implementation Foo + +- (void)instanceTest1 { + printf("__func__: %s\n", __func__); + printf("__FUNCTION__: %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__); +} + +- (void)instanceTest2:(int)i { + printf("__func__: %s\n", __func__); + printf("__FUNCTION__: %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__); +} + +- (void)instanceTest3:(int)a withB:(double)b { + printf("__func__: %s\n", __func__); + printf("__FUNCTION__: %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__); +} + +- (int)instanceTest4 { + printf("__func__: %s\n", __func__); + printf("__FUNCTION__: %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__); + return 0; +} + ++ (void)classTest1 { + printf("__func__: %s\n", __func__); + printf("__FUNCTION__: %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__); +} + ++ (void)classTest2:(int)i { + printf("__func__: %s\n", __func__); + printf("__FUNCTION__: %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__); +} + ++ (void)classTest3:(int)a withB:(double)b { + printf("__func__: %s\n", __func__); + printf("__FUNCTION__: %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__); +} + ++ (int)classTest4 { + printf("__func__: %s\n", __func__); + printf("__FUNCTION__: %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__); + return 0; +} + +@end + +@interface Foo (Category) +@end + +@implementation Foo (Category) + +- (void)instanceTestWithCategory { + printf("__func__: %s\n", __func__); + printf("__FUNCTION__: %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__); +} + ++ (void)classTestWithCategory { + printf("__func__: %s\n", __func__); + printf("__FUNCTION__: %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__: %s\n\n", __PRETTY_FUNCTION__); +} + +@end diff --git a/test/CodeGenObjC/property-agrr-getter.m b/test/CodeGenObjC/property-agrr-getter.m index 0a1df123bffe..46205796936f 100644 --- a/test/CodeGenObjC/property-agrr-getter.m +++ b/test/CodeGenObjC/property-agrr-getter.m @@ -9,9 +9,30 @@ typedef struct { @end @implementation A --(s0) f0{} +-(s0) f0{ while (1) {} } - (unsigned) bar { return self.f0.f0; } @end + +typedef struct _NSSize { + float width; + float height; +} NSSize; + + +@interface AnObject +{ + NSSize size; +} + +@property NSSize size; + +@end + +float f () +{ + AnObject* obj; + return (obj.size).width; +} diff --git a/test/CodeGenObjC/property-setter-attr.m b/test/CodeGenObjC/property-setter-attr.m index 390392415d73..5f0edf8271e7 100644 --- a/test/CodeGenObjC/property-setter-attr.m +++ b/test/CodeGenObjC/property-setter-attr.m @@ -1,4 +1,4 @@ -// RUN: clang-cc -emit-llvm -triple=i686-apple-darwin8 -o %t %s +// RUN: clang-cc -emit-llvm -triple=i686-apple-darwin8 -o %t %s && // RUN: grep -e "SiSetOtherThings:" %t @interface A diff --git a/test/CodeGenObjC/protocol-in-extended-class.m b/test/CodeGenObjC/protocol-in-extended-class.m new file mode 100644 index 000000000000..87bda46faeaa --- /dev/null +++ b/test/CodeGenObjC/protocol-in-extended-class.m @@ -0,0 +1,29 @@ +// RUN: clang-cc -triple x86_64-apple-darwin10 -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +@protocol MyProtocol +@end + +@protocol ExtendedProtocol +@end + +@interface ItDoesntWork<MyProtocol> { +} +-(void) Meth; +@end + +@interface ItDoesntWork() <MyProtocol, ExtendedProtocol> +@end + +@implementation ItDoesntWork +-(void) Meth { + ItDoesntWork <MyProtocol, ExtendedProtocol> *p = 0; + } +@end + +// CHECK-LP64: l_OBJC_PROTOCOL_$_ExtendedProtocol: + +// CHECK-LP32: L_OBJC_PROTOCOL_ExtendedProtocol: diff --git a/test/CodeGenObjC/protocols-lazy.m b/test/CodeGenObjC/protocols-lazy.m index e91cc0aea836..a8f79026f780 100644 --- a/test/CodeGenObjC/protocols-lazy.m +++ b/test/CodeGenObjC/protocols-lazy.m @@ -26,7 +26,7 @@ void f1() { id x = @protocol(P3); } // RUN: grep OBJC_PROTOCOL_INSTANCE_METHODS_P4 %t | count 3 && @protocol P4 -im1; @end @interface I0<P4> @end -@implementation I0 -im1 {}; @end +@implementation I0 -im1 { return 0; }; @end // Definition following forward reference. // RUN: grep OBJC_PROTOCOL_P5 %t | count 3 && @@ -42,7 +42,7 @@ void f2() { id x = @protocol(P5); } // This generates a forward // RUN: grep OBJC_PROTOCOL_INSTANCE_METHODS_P6 %t | count 3 && @protocol P6 -im1; @end @interface I1<P6> @end -@implementation I1 -im1 {}; @end +@implementation I1 -im1 { return 0; }; @end void f3() { id x = @protocol(P6); } // RUN: true diff --git a/test/CodeGenObjC/protocols.m b/test/CodeGenObjC/protocols.m new file mode 100644 index 000000000000..4cfb83bf00e0 --- /dev/null +++ b/test/CodeGenObjC/protocols.m @@ -0,0 +1,50 @@ +// RUN: clang-cc -fnext-runtime -emit-llvm %s -o %t + +void p(const char*, ...); + +@interface Root +-(int) conformsTo: (id) x; +@end + +@protocol P0; + +@protocol P1 ++(void) classMethodReq0; +-(void) methodReq0; +@optional ++(void) classMethodOpt1; +-(void) methodOpt1; +@required ++(void) classMethodReq2; +-(void) methodReq2; +@end + +@protocol P2 +//@property(readwrite) int x; +@end + +@protocol P3<P1, P2> +-(id <P1>) print0; +-(void) print1; +@end + +void foo(const id a) { + void *p = @protocol(P3); +} + +int main() { + Protocol *P0 = @protocol(P0); + Protocol *P1 = @protocol(P1); + Protocol *P2 = @protocol(P2); + Protocol *P3 = @protocol(P3); + +#define Pbool(X) p(#X ": %s\n", X ? "yes" : "no"); + Pbool([P0 conformsTo: P1]); + Pbool([P1 conformsTo: P0]); + Pbool([P1 conformsTo: P2]); + Pbool([P2 conformsTo: P1]); + Pbool([P3 conformsTo: P1]); + Pbool([P1 conformsTo: P3]); + + return 0; +} diff --git a/test/CodeGenObjC/variadic-sends.m b/test/CodeGenObjC/variadic-sends.m new file mode 100644 index 000000000000..8697feec5d6d --- /dev/null +++ b/test/CodeGenObjC/variadic-sends.m @@ -0,0 +1,41 @@ +// RUN: clang-cc -triple i386-unknown-unknown -fnext-runtime -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-X86-32 %s && +// RUN: clang-cc -triple x86_64-unknown-unknown -fnext-runtime -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-X86-64 %s + +@interface A +-(void) im0; +-(void) im1: (int) x; +-(void) im2: (int) x, ...; +@end + +void f0(A *a) { + // CHECK-X86-32: call void bitcast (i8* (i8*, %struct.objc_selector*, ...)* @objc_msgSend to void (i8*, %struct.objc_selector*)*) + // CHECK-X86-64: call void bitcast (i8* (i8*, %struct.objc_selector*, ...)* @objc_msgSend to void (i8*, %struct.objc_selector*)*) + [a im0]; +} + +void f1(A *a) { + // CHECK-X86-32: call void bitcast (i8* (i8*, %struct.objc_selector*, ...)* @objc_msgSend to void (i8*, %struct.objc_selector*, i32)*) + // CHECK-X86-64: call void bitcast (i8* (i8*, %struct.objc_selector*, ...)* @objc_msgSend to void (i8*, %struct.objc_selector*, i32)*) + [a im1: 1]; +} + +void f2(A *a) { + // CHECK-X86-32: call void (i8*, %struct.objc_selector*, i32, i32, ...)* bitcast (i8* (i8*, %struct.objc_selector*, ...)* @objc_msgSend to void (i8*, %struct.objc_selector*, i32, i32, ...)*) + // CHECK-X86-64: call void (i8*, %struct.objc_selector*, i32, i32, ...)* bitcast (i8* (i8*, %struct.objc_selector*, ...)* @objc_msgSend to void (i8*, %struct.objc_selector*, i32, i32, ...)*) + [a im2: 1, 2]; +} + +@interface B : A @end +@implementation B : A +-(void) foo { + // CHECK-X86-32: call void bitcast (i8* (%struct._objc_super*, %struct.objc_selector*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, %struct.objc_selector*, i32)*) + // CHECK-X86-64: call void bitcast (i8* (%struct._objc_super*, %struct.objc_selector*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, %struct.objc_selector*, i32)*) + [super im1: 1]; +} +-(void) bar { + // CHECK-X86-32: call void (%struct._objc_super*, %struct.objc_selector*, i32, i32, ...)* bitcast (i8* (%struct._objc_super*, %struct.objc_selector*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, %struct.objc_selector*, i32, i32, ...)*) + // CHECK-X86-64: call void (%struct._objc_super*, %struct.objc_selector*, i32, i32, ...)* bitcast (i8* (%struct._objc_super*, %struct.objc_selector*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, %struct.objc_selector*, i32, i32, ...)*) + [super im2: 1, 2]; +} + +@end diff --git a/test/Coverage/targets.c b/test/Coverage/targets.c index 5a547a53add9..5a87b4dcc554 100644 --- a/test/Coverage/targets.c +++ b/test/Coverage/targets.c @@ -1,18 +1,19 @@ -// RUN: clang-cc -g -triple i686-unknown-unknown -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple armv6-apple-darwin9 -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple armv6-unknown-unknown -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple bfin-unknown-unknown -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple i686-apple-darwin9 -emit-llvm -o %t %s && // RUN: clang-cc -g -triple i686-pc-linux-gnu -emit-llvm -o %t %s && // RUN: clang-cc -g -triple i686-unknown-dragonfly -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple i686-unknown-unknown -emit-llvm -o %t %s && // RUN: clang-cc -g -triple i686-unknown-win32 -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple i686-apple-darwin9 -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple x86_64-unknown-unknown -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple x86_64-pc-linux-gnu -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple x86_64-apple-darwin9 -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple ppc-unknown-unknown -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple ppc-apple-darwin9 -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple ppc64-unknown-unknown -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple ppc64-apple-darwin9 -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple armv6-unknown-unknown -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple armv6-apple-darwin9 -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple sparc-unknown-unknown -emit-llvm -o %t %s && -// RUN: clang-cc -g -triple sparc-unknown-solaris -emit-llvm -o %t %s && // RUN: clang-cc -g -triple pic16-unknown-unknown -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple powerpc-apple-darwin9 -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple powerpc-unknown-unknown -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple powerpc64-apple-darwin9 -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple powerpc64-unknown-unknown -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple sparc-unknown-solaris -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple sparc-unknown-unknown -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple x86_64-apple-darwin9 -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple x86_64-pc-linux-gnu -emit-llvm -o %t %s && +// RUN: clang-cc -g -triple x86_64-unknown-unknown -emit-llvm -o %t %s && // RUN: true diff --git a/test/Driver/arm-darwin-builtin.c b/test/Driver/arm-darwin-builtin.c new file mode 100644 index 000000000000..5da8074ee3a7 --- /dev/null +++ b/test/Driver/arm-darwin-builtin.c @@ -0,0 +1,14 @@ +// FIXME: Disable pending PR4941. +// RUX: clang -ccc-host-triple x86_64-apple-darwin9 -arch arm -### -fsyntax-only %s 2> %t && +// RUX: grep -- "-fno-builtin-strcat" %t && +// RUX: grep -- "-fno-builtin-strcpy" %t && + +// FIXME: Disable pending PR4941. +// RUX: clang -ccc-host-triple x86_64-apple-darwin9 -arch arm -### -fsyntax-only %s -fbuiltin-strcat -fbuiltin-strcpy 2> %t && +// RUX: not grep -- "-fno-builtin-strcat" %t && +// RUX: not grep -- "-fno-builtin-strcpy" %t && + +// RUN: clang -ccc-no-clang -ccc-host-triple x86_64-apple-darwin9 -arch arm -### -fsyntax-only %s -fbuiltin-strcat -fbuiltin-strcpy 2> %t && +// RUN: not grep -- "-fno-builtin-strcat" %t && +// RUN: not grep -- "-fno-builtin-strcpy" %t + diff --git a/test/Driver/ast.c b/test/Driver/ast.c new file mode 100644 index 000000000000..814b597bb19f --- /dev/null +++ b/test/Driver/ast.c @@ -0,0 +1,26 @@ +// RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-phases -emit-ast %s 2> %t && +// RUN: echo 'END' >> %t && +// RUN: FileCheck -check-prefix EMIT-AST-PHASES -input-file %t %s && + +// EMIT-AST-PHASES: 0: input, +// EMIT-AST-PHASES: , c +// EMIT-AST-PHASES: 1: preprocessor, {0}, cpp-output +// EMIT-AST-PHASES: 2: compiler, {1}, ast +// EMIT-AST-PHASES-NOT: 3: +// EMIT-AST-PHASES: END + +// RUN: touch %t.ast && +// RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-phases -c %t.ast 2> %t && +// RUN: echo 'END' >> %t && +// RUN: FileCheck -check-prefix COMPILE-AST-PHASES -input-file %t %s + +// COMPILE-AST-PHASES: 0: input, +// COMPILE-AST-PHASES: , ast +// COMPILE-AST-PHASES: 1: compiler, {0}, assembler +// COMPILE-AST-PHASES: 2: assembler, {1}, object +// COMPILE-AST-PHASES-NOT: 3: +// COMPILE-AST-PHASES: END + +// FIXME: There is a problem with compiling AST's in that the input language is +// not availabe for use by other tools (for example, to automatically add +// -lstdc++). We may need -x [objective-]c++-ast and all that goodness. :( diff --git a/test/Driver/bindings.c b/test/Driver/bindings.c index 3cac22c94be3..393739006bb7 100644 --- a/test/Driver/bindings.c +++ b/test/Driver/bindings.c @@ -30,7 +30,7 @@ // RUN: grep '"clang", inputs: \[".*bindings.c"\], output: (nothing)' %t && // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang -fsyntax-only %s 2> %t && // RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: (nothing)' %t && -// RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -fsyntax-only -x c++ %s 2> %t && +// RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang-cxx -fsyntax-only -x c++ %s 2> %t && // RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: (nothing)' %t && // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-clang-cxx -fsyntax-only -x c++ %s 2> %t && // RUN: grep '"clang", inputs: \[".*bindings.c"\], output: (nothing)' %t && @@ -39,12 +39,12 @@ // RUN: grep '"clang", inputs: \[".*\.i"\], output: (nothing)' %t && // RUN: clang -ccc-host-triple i386-apple-darwin9 -ccc-print-bindings -ccc-clang-archs i386 %s -S -arch ppc 2> %t && // RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && -// RUN: clang -ccc-host-triple i386-apple-darwin9 -ccc-print-bindings -ccc-clang-archs ppc %s -S -arch ppc 2> %t && +// RUN: clang -ccc-host-triple i386-apple-darwin9 -ccc-print-bindings -ccc-clang-archs powerpc %s -S -arch ppc 2> %t && // RUN: grep '"clang", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && // RUN: clang -ccc-host-triple powerpc-unknown-unknown -ccc-print-bindings -ccc-clang-archs "" %s -S 2> %t && // RUN: grep '"clang", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && -// RUN: clang -ccc-host-triple powerpc-unknown-unknown -ccc-print-bindings %s -S 2> %t && +// RUN: clang -ccc-host-triple powerpc-unknown-unknown -ccc-print-bindings -ccc-clang-archs "i386" %s -S 2> %t && // RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && // Darwin bindings diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c index ca60a8d8c6bc..e0b9e3ada6ec 100644 --- a/test/Driver/clang-translation.c +++ b/test/Driver/clang-translation.c @@ -1,4 +1,4 @@ -// RUN: clang -ccc-host-triple i386-unknown-unknown -### -S -O0 -Os %s -o %t.s -fverbose-asm 2> %t.log +// RUN: clang -ccc-host-triple i386-unknown-unknown -### -S -O0 -Os %s -o %t.s -fverbose-asm 2> %t.log && // RUN: grep '"-triple" "i386-unknown-unknown"' %t.log && // RUN: grep '"-S"' %t.log && // RUN: grep '"-disable-free"' %t.log && @@ -7,10 +7,10 @@ // RUN: grep '"--unwind-tables=0"' %t.log && // RUN: grep '"--fmath-errno=1"' %t.log && // RUN: grep '"-Os"' %t.log && -// RUN: grep '"-o" .*clang-translation\.c\.out\.tmp\.s' %t.log && +// RUN: grep '"-o" .*clang-translation.*' %t.log && // RUN: grep '"--asm-verbose"' %t.log && -// RUN: clang -ccc-host-triple i386-apple-darwin9 -### -S %s -o %t.s 2> %t.log +// RUN: clang -ccc-host-triple i386-apple-darwin9 -### -S %s -o %t.s 2> %t.log && // RUN: grep '"--mcpu=yonah"' %t.log && -// RUN: clang -ccc-host-triple x86_64-apple-darwin9 -### -S %s -o %t.s 2> %t.log +// RUN: clang -ccc-host-triple x86_64-apple-darwin9 -### -S %s -o %t.s 2> %t.log && // RUN: grep '"--mcpu=core2"' %t.log && // RUN: true diff --git a/test/Driver/darwin-arm.c b/test/Driver/darwin-arm.c new file mode 100644 index 000000000000..8b4c23d55724 --- /dev/null +++ b/test/Driver/darwin-arm.c @@ -0,0 +1,4 @@ +// RUN: clang -ccc-host-triple i386-apple-darwin9 -arch arm -print-search-dirs | FileCheck %s + +// Check that we look in the relative libexec directory. +// CHECK: {{programs: =.*/../libexec:}} diff --git a/test/Driver/darwin-as.c b/test/Driver/darwin-as.c new file mode 100644 index 000000000000..486dc2e79810 --- /dev/null +++ b/test/Driver/darwin-as.c @@ -0,0 +1,10 @@ +// RUN: clang -ccc-host-triple i386-apple-darwin10 -### -x assembler -c %s -static -dynamic 2>%t && +// RUN: FileCheck -check-prefix=STATIC_AND_DYNAMIC-32 --input-file %t %s && + +// CHECK-STATIC_AND_DYNAMIC-32: as{{(.exe)?}}" "-arch" "i386" "-force_cpusubtype_ALL" "-static" "-o" + +// RUN: clang -ccc-host-triple x86_64-apple-darwin10 -### -x assembler -c %s -static 2>%t && +// RUN: FileCheck -check-prefix=STATIC-64 --input-file %t %s + +// CHECK-STATIC-64: as{{(.exe)?}}" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o" + diff --git a/test/Driver/darwin-cc.c b/test/Driver/darwin-cc.c index ac5d9a922d50..77193cda4441 100644 --- a/test/Driver/darwin-cc.c +++ b/test/Driver/darwin-cc.c @@ -1,4 +1,3 @@ -// RUN: unset MACOSX_DEPLOYMENT_TARGET && // RUN: clang -ccc-no-clang -ccc-host-triple i386-apple-darwin10 -m32 -### -MD -g -fast -Q -dA -mkernel -ansi -aFOO -S -o /tmp/OUTPUTNAME -g0 -gfull -O2 -Werror -pedantic -Wmost -w -std=c99 -trigraphs -v -pg -fFOO -undef -Qn --param a=b -fmudflap -coverage -save-temps -nostdinc -I ARG0 -F ARG1 -I ARG2 -P -MF ARG3 -MG -MP -remap -g3 -H -D ARG4 -U ARG5 -A ARG6 -D ARG7 -U ARG8 -A ARG9 -include ARG10 -pthread %s 2> %t.log && // RUN: grep ' ".*cc1" "-E" "-nostdinc" "-v" "-I" "ARG0" "-F" "ARG1" "-I" "ARG2" "-P" "-MD" "/tmp/OUTPUTNAME.d" "-MF" "ARG3" "-MG" "-MP" "-MQ" "/tmp/OUTPUTNAME" "-remap" "-dD" "-H" "-D__STATIC__" "-D_REENTRANT" "-D" "ARG4" "-U" "ARG5" "-A" "ARG6" "-D" "ARG7" "-U" "ARG8" "-A" "ARG9" "-include" "ARG10" ".*darwin-cc.c" "-D_MUDFLAP" "-include" "mf-runtime.h" "-mmacosx-version-min=10.6.0" "-m32" "-mkernel" "-mtune=core2" "-ansi" "-std=c99" "-trigraphs" "-Werror" "-pedantic" "-Wmost" "-w" "-fast" "-fno-eliminate-unused-debug-symbols" "-fFOO" "-fmudflap" "-O2" "-undef" "-fpch-preprocess" "-o" ".*darwin-cc.i"' %t.log && // RUN: grep ' ".*cc1" "-fpreprocessed" ".*darwin-cc.i" "-O3" "-dumpbase" ".*darwin-cc.c" "-dA" "-mmacosx-version-min=10.6.0" "-m32" "-mkernel" "-mtune=core2" "-ansi" "-aFOO" "-auxbase-strip" "/tmp/OUTPUTNAME" "-g" "-g0" "-g" "-g3" "-O2" "-Werror" "-pedantic" "-Wmost" "-w" "-ansi" "-std=c99" "-trigraphs" "-version" "-p" "-fast" "-fno-eliminate-unused-debug-symbols" "-fFOO" "-fmudflap" "-undef" "-fno-ident" "-o" "/tmp/OUTPUTNAME" "--param" "a=b" "-fno-builtin" "-fno-merge-constants" "-fprofile-arcs" "-ftest-coverage"' %t.log && diff --git a/test/Driver/darwin-ld.c b/test/Driver/darwin-ld.c index 2e6fc57bac59..d81605bbe93d 100644 --- a/test/Driver/darwin-ld.c +++ b/test/Driver/darwin-ld.c @@ -1,8 +1,7 @@ // Check that ld gets arch_multiple. -// RUN: unset MACOSX_DEPLOYMENT_TARGET && // RUN: clang -ccc-host-triple i386-apple-darwin9 -arch i386 -arch x86_64 %s -### -o foo 2> %t.log && -// RUN: grep '".*ld" .*"-arch_multiple" "-final_output" "foo"' %t.log && +// RUN: grep '".*ld.*" .*"-arch_multiple" "-final_output" "foo"' %t.log && // RUN: clang -ccc-host-triple i386-apple-darwin9 -### -filelist FOO -static 2> %t.log && // RUN: grep '"-lcrt0.o" .*"-lgcc_static"' %t.log && @@ -33,8 +32,8 @@ // // Note that at conception, this exactly matches gcc. -// RUN: clang -ccc-host-triple i386-apple-darwin9 -### -A ARG0 -F ARG1 -L ARG2 -Mach -T ARG4 -X -Z -all_load -allowable_client ARG8 -bind_at_load -compatibility_version ARG11 -current_version ARG12 -d -dead_strip -dylib_file ARG14 -dylinker -dylinker_install_name ARG16 -dynamic -dynamiclib -e ARG19 -exported_symbols_list ARG20 -fexceptions -flat_namespace -fnested-functions -fopenmp -force_cpusubtype_ALL -fpie -fprofile-arcs -headerpad_max_install_names -image_base ARG29 -init ARG30 -install_name ARG31 -m ARG33 -miphoneos-version-min=2.0 -mmacosx-version-min=10.3.2 -multi_module -multiply_defined ARG37 -multiply_defined_unused ARG38 -no_dead_strip_inits_and_terms -nodefaultlibs -nofixprebinding -nomultidefs -noprebind -noseglinkedit -nostartfiles -nostdlib -object -pagezero_size ARG54 -pg -prebind -prebind_all_twolevel_modules -preload -r -read_only_relocs ARG55 -s -sectalign ARG57_0 ARG57_1 ARG57_2 -sectcreate ARG58_0 ARG58_1 ARG58_2 -sectobjectsymbols ARG59_0 ARG59_1 -sectorder ARG60_0 ARG60_1 ARG60_2 -seg1addr ARG61 -seg_addr_table ARG62 -seg_addr_table_filename ARG63 -segaddr ARG64_0 ARG64_1 -segcreate ARG65_0 ARG65_1 ARG65_2 -seglinkedit -segprot ARG67_0 ARG67_1 ARG67_2 -segs_read_FOO -segs_read_only_addr ARG69 -segs_read_write_addr ARG70 -shared-libgcc -single_module -static -static-libgcc -sub_library ARG77 -sub_umbrella ARG78 -t -twolevel_namespace -twolevel_namespace_hints -u ARG82 -umbrella ARG83 -undefined ARG84 -unexported_symbols_list ARG85 -w -weak_reference_mismatches ARG87 -whatsloaded -whyload -y -filelist FOO 2> %t.log && -// RUN: grep '".*ld" "-static" "-dylib" "-dylib_compatibility_version" "ARG11" "-dylib_current_version" "ARG12" "-arch" "i386" "-dylib_install_name" "ARG31" "-all_load" "-allowable_client" "ARG8" "-bind_at_load" "-dead_strip" "-no_dead_strip_inits_and_terms" "-dylib_file" "ARG14" "-dynamic" "-exported_symbols_list" "ARG20" "-flat_namespace" "-headerpad_max_install_names" "-image_base" "ARG29" "-init" "ARG30" "-macosx_version_min" "10.3.2" "-iphoneos_version_min" "2.0" "-nomultidefs" "-multi_module" "-single_module" "-multiply_defined" "ARG37" "-multiply_defined_unused" "ARG38" "-pie" "-prebind" "-noprebind" "-nofixprebinding" "-prebind_all_twolevel_modules" "-read_only_relocs" "ARG55" "-sectcreate" "ARG58_0" "ARG58_1" "ARG58_2" "-sectorder" "ARG60_0" "ARG60_1" "ARG60_2" "-seg1addr" "ARG61" "-segprot" "ARG67_0" "ARG67_1" "ARG67_2" "-segaddr" "ARG64_0" "ARG64_1" "-segs_read_only_addr" "ARG69" "-segs_read_write_addr" "ARG70" "-seg_addr_table" "ARG62" "-seg_addr_table_filename" "ARG63" "-sub_library" "ARG77" "-sub_umbrella" "ARG78" "-twolevel_namespace" "-twolevel_namespace_hints" "-umbrella" "ARG83" "-undefined" "ARG84" "-unexported_symbols_list" "ARG85" "-weak_reference_mismatches" "ARG87" "-X" "-y" "-w" "-pagezero_size" "ARG54" "-segs_read_FOO" "-seglinkedit" "-noseglinkedit" "-sectalign" "ARG57_0" "ARG57_1" "ARG57_2" "-sectobjectsymbols" "ARG59_0" "ARG59_1" "-segcreate" "ARG65_0" "ARG65_1" "ARG65_2" "-whyload" "-whatsloaded" "-dylinker_install_name" "ARG16" "-dylinker" "-Mach" "-d" "-s" "-t" "-Z" "-u" "ARG82" "-undefined" "ARG84" "-A" "ARG0" "-e" "ARG19" "-m" "ARG33" "-r" "-object" "-o" "a.out" "-L" "ARG2" "-lgomp" "-L/usr/lib/i686-apple-darwin9/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin9/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin9/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin9/4.2.1/../../../i686-apple-darwin9/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin9/4.2.1/../../.." "-filelist" "FOO" "-lgcov" "-allow_stack_execute" "-T" "ARG4" "-F" "ARG1"' %t.log && +// RUN: clang -ccc-host-triple i386-apple-darwin9 -### -A ARG0 -F ARG1 -L ARG2 -Mach -T ARG4 -X -Z -all_load -allowable_client ARG8 -bind_at_load -compatibility_version ARG11 -current_version ARG12 -d -dead_strip -dylib_file ARG14 -dylinker -dylinker_install_name ARG16 -dynamic -dynamiclib -e ARG19 -exported_symbols_list ARG20 -fexceptions -flat_namespace -fnested-functions -fopenmp -force_cpusubtype_ALL -fpie -fprofile-arcs -headerpad_max_install_names -image_base ARG29 -init ARG30 -install_name ARG31 -m ARG33 -miphoneos-version-min=2.0 -mmacosx-version-min=10.3.2 -multi_module -multiply_defined ARG37 -multiply_defined_unused ARG38 -no_dead_strip_inits_and_terms -nodefaultlibs -nofixprebinding -nomultidefs -noprebind -noseglinkedit -nostartfiles -nostdlib -pagezero_size ARG54 -pg -prebind -prebind_all_twolevel_modules -preload -r -read_only_relocs ARG55 -s -sectalign ARG57_0 ARG57_1 ARG57_2 -sectcreate ARG58_0 ARG58_1 ARG58_2 -sectobjectsymbols ARG59_0 ARG59_1 -sectorder ARG60_0 ARG60_1 ARG60_2 -seg1addr ARG61 -seg_addr_table ARG62 -seg_addr_table_filename ARG63 -segaddr ARG64_0 ARG64_1 -segcreate ARG65_0 ARG65_1 ARG65_2 -seglinkedit -segprot ARG67_0 ARG67_1 ARG67_2 -segs_read_FOO -segs_read_only_addr ARG69 -segs_read_write_addr ARG70 -shared-libgcc -single_module -static -static-libgcc -sub_library ARG77 -sub_umbrella ARG78 -t -twolevel_namespace -twolevel_namespace_hints -u ARG82 -umbrella ARG83 -undefined ARG84 -unexported_symbols_list ARG85 -w -weak_reference_mismatches ARG87 -whatsloaded -whyload -y -filelist FOO 2> %t.log && +// RUN: grep '".*ld.*" "-static" "-dylib" "-dylib_compatibility_version" "ARG11" "-dylib_current_version" "ARG12" "-arch" "i386" "-dylib_install_name" "ARG31" "-all_load" "-allowable_client" "ARG8" "-bind_at_load" "-dead_strip" "-no_dead_strip_inits_and_terms" "-dylib_file" "ARG14" "-dynamic" "-exported_symbols_list" "ARG20" "-flat_namespace" "-headerpad_max_install_names" "-image_base" "ARG29" "-init" "ARG30" "-macosx_version_min" "10.3.2" "-iphoneos_version_min" "2.0" "-nomultidefs" "-multi_module" "-single_module" "-multiply_defined" "ARG37" "-multiply_defined_unused" "ARG38" "-pie" "-prebind" "-noprebind" "-nofixprebinding" "-prebind_all_twolevel_modules" "-read_only_relocs" "ARG55" "-sectcreate" "ARG58_0" "ARG58_1" "ARG58_2" "-sectorder" "ARG60_0" "ARG60_1" "ARG60_2" "-seg1addr" "ARG61" "-segprot" "ARG67_0" "ARG67_1" "ARG67_2" "-segaddr" "ARG64_0" "ARG64_1" "-segs_read_only_addr" "ARG69" "-segs_read_write_addr" "ARG70" "-seg_addr_table" "ARG62" "-seg_addr_table_filename" "ARG63" "-sub_library" "ARG77" "-sub_umbrella" "ARG78" "-twolevel_namespace" "-twolevel_namespace_hints" "-umbrella" "ARG83" "-undefined" "ARG84" "-unexported_symbols_list" "ARG85" "-weak_reference_mismatches" "ARG87" "-X" "-y" "-w" "-pagezero_size" "ARG54" "-segs_read_FOO" "-seglinkedit" "-noseglinkedit" "-sectalign" "ARG57_0" "ARG57_1" "ARG57_2" "-sectobjectsymbols" "ARG59_0" "ARG59_1" "-segcreate" "ARG65_0" "ARG65_1" "ARG65_2" "-whyload" "-whatsloaded" "-dylinker_install_name" "ARG16" "-dylinker" "-Mach" "-d" "-s" "-t" "-Z" "-u" "ARG82" "-undefined" "ARG84" "-A" "ARG0" "-e" "ARG19" "-m" "ARG33" "-r" "-o" "a.out" "-L" "ARG2" "-lgomp" "-L/usr/lib/i686-apple-darwin9/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin9/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin9/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin9/4.2.1/../../../i686-apple-darwin9/4.2.1" "-L/usr/lib/gcc/i686-apple-darwin9/4.2.1/../../.." "-filelist" "FOO" "-lgcov" "-allow_stack_execute" "-T" "ARG4" "-F" "ARG1"' %t.log && // Don't run dsymutil on a fat build of an executable. // RUN: clang -ccc-host-triple i386-apple-darwin9 -### -arch i386 -arch x86_64 -g %s 2> %t.log && diff --git a/test/Driver/default-toolchain.c b/test/Driver/default-toolchain.c index 216394fe97d9..0e8a02679e8d 100644 --- a/test/Driver/default-toolchain.c +++ b/test/Driver/default-toolchain.c @@ -1,8 +1,8 @@ -// RUN: clang -ccc-host-triple i386-unknown-unknown -m64 -v 2> %t +// RUN: clang -ccc-host-triple i386-unknown-unknown -m64 -v 2> %t && // RUN: grep 'Target: x86_64-unknown-unknown' %t && -// RUN: clang -ccc-host-triple i386-apple-darwin9 -arch ppc -m64 -v 2> %t +// RUN: clang -ccc-host-triple i386-apple-darwin9 -arch ppc -m64 -v 2> %t && // RUN: grep 'Target: powerpc64-apple-darwin9' %t && -// RUN: clang -ccc-host-triple i386-apple-darwin9 -arch ppc64 -m32 -v 2> %t +// RUN: clang -ccc-host-triple i386-apple-darwin9 -arch ppc64 -m32 -v 2> %t && // RUN: grep 'Target: powerpc-apple-darwin9' %t diff --git a/test/Driver/dragonfly.c b/test/Driver/dragonfly.c index 5d7b0b0f0045..f0b09f7e239f 100644 --- a/test/Driver/dragonfly.c +++ b/test/Driver/dragonfly.c @@ -1,6 +1,8 @@ // RUN: clang -ccc-host-triple amd64-pc-dragonfly %s -### 2> %t.log && -// RUN: grep 'clang-cc" "-triple" "x86_64-pc-dragonfly"' %t.log && -// RUN: grep 'as" "-o" ".*\.o" ".*\.s' %t.log && -// RUN: grep 'ld" "-dynamic-linker" ".*ld-elf.*" "-o" "a\.out" ".*crt1.o" ".*crti.o" "crtbegin.o" ".*\.o" "-L.*/gcc.*" .* "-lc" "-lgcc" ".*crtend.o" ".*crtn.o"' %t.log && -// RUN: true +// RUN: FileCheck -input-file %t.log %s + +// CHECK: clang-cc{{.*}}" "-triple" "amd64-pc-dragonfly" +// CHECK: as{{.*}}" "-o" "{{.*}}.o" "{{.*}}.s +// CHECK: ld{{.*}}" "-dynamic-linker" "{{.*}}ld-elf.{{.*}}" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-L{{.*}}/gcc{{.*}}" {{.*}} "-lc" "-lgcc" "{{.*}}crtend.o" "{{.*}}crtn.o" + diff --git a/test/Driver/freebsd.c b/test/Driver/freebsd.c index 91258d9e5728..d50c85b749de 100644 --- a/test/Driver/freebsd.c +++ b/test/Driver/freebsd.c @@ -1,7 +1,7 @@ -// RUN: clang -ccc-clang-archs "" -ccc-host-triple ppc64-pc-freebsd8 %s -### 2> %t.log && +// RUN: clang -ccc-clang-archs "" -ccc-host-triple powerpc64-pc-freebsd8 %s -### 2> %t.log && // RUN: cat %t.log && -// RUN: grep 'clang-cc" "-triple" "powerpc64-pc-freebsd8"' %t.log && -// RUN: grep 'as" "-o" ".*\.o" ".*\.s' %t.log && -// RUN: grep 'ld" "--eh-frame-hdr" "-dynamic-linker" ".*ld-elf.*" "-o" "a\.out" ".*crt1.o" ".*crti.o" "crtbegin.o" ".*\.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" ".*crtend.o" ".*crtn.o"' %t.log && -// RUN: true +// RUN: FileCheck -input-file %t.log %s +// CHECK: clang-cc{{.*}}" "-triple" "powerpc64-pc-freebsd8" +// CHECK: as{{.*}}" "-o" "{{.*}}.o" "{{.*}}.s +// CHECK: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "{{.*}}ld-elf{{.*}}" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "{{.*}}crtend.o" "{{.*}}crtn.o" diff --git a/test/Driver/openbsd.c b/test/Driver/openbsd.c index fd0d4fa21cd9..c73ef20d8045 100644 --- a/test/Driver/openbsd.c +++ b/test/Driver/openbsd.c @@ -1,6 +1,6 @@ // RUN: clang -ccc-clang-archs "" -ccc-host-triple i686-pc-openbsd %s -### 2> %t.log && -// RUN: grep 'clang-cc" "-triple" "i386-pc-openbsd"' %t.log && -// RUN: grep 'as" "-o" ".*\.o" ".*\.s' %t.log && -// RUN: grep 'ld" "--eh-frame-hdr" "-dynamic-linker" ".*ld.so" "-o" "a\.out" ".*crt0.o" ".*crtbegin.o" ".*\.o" "-lc" ".*crtend.o"' %t.log && -// RUN: true +// RUN: FileCheck -input-file %t.log %s +// CHECK: clang-cc{{.*}}" "-triple" "i686-pc-openbsd" +// CHECK: as{{.*}}" "-o" "{{.*}}.o" "{{.*}}.s +// CHECK: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-o" "a.out" "{{.*}}crt0.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lgcc" "-lc" "-lgcc" "{{.*}}crtend.o" diff --git a/test/Driver/pth.c b/test/Driver/pth.c index 748053809a7c..5c83aea54ceb 100644 --- a/test/Driver/pth.c +++ b/test/Driver/pth.c @@ -1,8 +1,12 @@ // Test transparent PTH support. // RUN: clang -ccc-pch-is-pth -x c-header %s -o %t.h.pth -### 2> %t.log && -// RUN: grep '".*/clang-cc" .* "-o" ".*\.h\.pth" "-x" "c-header" ".*pth\.c"' %t.log && +// RUN: FileCheck -check-prefix CHECK1 -input-file %t.log %s && + +// CHECK1: "{{.*}}/clang-cc{{.*}}" {{.*}} "-o" "{{.*}}.h.pth" "-x" "c-header" "{{.*}}pth.c" // RUN: touch %t.h.pth && // RUN: clang -ccc-pch-is-pth -E -include %t.h %s -### 2> %t.log && -// RUN: grep '".*/clang-cc" .*"-include-pth" ".*\.h\.pth" .*"-x" "c" ".*pth\.c"' %t.log +// RUN: FileCheck -check-prefix CHECK2 -input-file %t.log %s + +// CHECK2: "{{.*}}/clang-cc{{.*}}" {{.*}}"-include-pth" "{{.*}}.h.pth" {{.*}}"-x" "c" "{{.*}}pth.c" diff --git a/test/Driver/qa_override.c b/test/Driver/qa_override.c index 0ff578c2a814..46e150c74fdc 100644 --- a/test/Driver/qa_override.c +++ b/test/Driver/qa_override.c @@ -1,4 +1,5 @@ -// RUN: env QA_OVERRIDE_GCC3_OPTIONS="+-Os +-Oz +-O +-O3 +-Oignore +a +b +c xb Xa Omagic ^-ccc-print-options " clang x -O2 b -O3 2> %t && +// RUN: env QA_OVERRIDE_GCC3_OPTIONS="#+-Os +-Oz +-O +-O3 +-Oignore +a +b +c xb Xa Omagic ^-ccc-print-options " clang x -O2 b -O3 2> %t && +// RUN: grep '### ' %t | count 0 && // RUN: grep -F 'Option 0 - Name: "<input>", Values: {"x"}' %t && // RUN: grep -F 'Option 1 - Name: "-O", Values: {"ignore"}' %t && // RUN: grep -F 'Option 2 - Name: "-O", Values: {"magic"}' %t && diff --git a/test/Driver/redzone.c b/test/Driver/redzone.c index 8709e71fb366..64729ac27717 100644 --- a/test/Driver/redzone.c +++ b/test/Driver/redzone.c @@ -1,6 +1,6 @@ -// RUN: clang -mno-red-zone %s -S -emit-llvm -o %t.log && -// RUN: grep 'noredzone' %t.log -// RUN: clang -mred-zone %s -S -emit-llvm -o %t.log && +// RUN: clang -ccc-host-triple i386-unknown-unknown -mno-red-zone %s -S -emit-llvm -o %t.log && +// RUN: grep 'noredzone' %t.log && +// RUN: clang -ccc-host-triple i386-unknown-unknown -mred-zone %s -S -emit-llvm -o %t.log && // RUN: grep -v 'noredzone' %t.log int foo() { return 42; } diff --git a/test/Frontend/ast-codegen.c b/test/Frontend/ast-codegen.c new file mode 100644 index 000000000000..1fe74d4fbeb4 --- /dev/null +++ b/test/Frontend/ast-codegen.c @@ -0,0 +1,12 @@ +// RUN: clang -emit-ast -o %t.ast %s && +// RUN: clang -emit-llvm -S -o - %t.ast | FileCheck %s + +// CHECK: module asm "foo" +__asm__("foo"); + +// CHECK: @g0 = common global i32 0, align 4 +int g0; + +// CHECK: define i32 @f0() +int f0() { +} diff --git a/test/Frontend/ast-main.c b/test/Frontend/ast-main.c new file mode 100644 index 000000000000..783140673899 --- /dev/null +++ b/test/Frontend/ast-main.c @@ -0,0 +1,8 @@ +// RUN: clang -emit-llvm -S -o %t1.ll -x c - < %s && +// RUN: clang -emit-ast -o %t.ast %s && +// RUN: clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast && +// RUN: diff %t1.ll %t2.ll + +int main() { + return 0; +} diff --git a/test/Frontend/dependency-gen.c b/test/Frontend/dependency-gen.c index 456ce947f091..4a1611aecff0 100644 --- a/test/Frontend/dependency-gen.c +++ b/test/Frontend/dependency-gen.c @@ -1,6 +1,6 @@ // rdar://6533411 // RUN: clang -MD -MF %t.d -c -x c -o %t.o /dev/null && -// RUN: grep '.*dependency-gen.c.out.tmp.o:' %t.d && +// RUN: grep '.*dependency-gen.*:' %t.d && // RUN: grep '/dev/null' %t.d && // RUN: clang -M -x c /dev/null -o %t.deps && diff --git a/test/Frontend/stdin.c b/test/Frontend/stdin.c index 35fe45d35b40..5b719b2e1344 100644 --- a/test/Frontend/stdin.c +++ b/test/Frontend/stdin.c @@ -1,3 +1,3 @@ -// RUN: clang-cc -E - < /dev/null > %t +// RUN: clang-cc -E - < /dev/null > %t && // RUN: grep '<built-in>' %t diff --git a/test/Index/c-index-api-test.m b/test/Index/c-index-api-test.m new file mode 100644 index 000000000000..20d4d7b45afd --- /dev/null +++ b/test/Index/c-index-api-test.m @@ -0,0 +1,224 @@ +// RUN: clang-cc -triple x86_64-apple-darwin10 -emit-pch -x objective-c %s -o %t.ast && +// RUN: c-index-test %t.ast all | FileCheck %s + +// CHECK: <invalid loc>:0:0: TypedefDecl=__int128_t:0:0 [Context=c-index-api-test.m] +// CHECK: <invalid loc>:0:0: TypedefDecl=__uint128_t:0:0 [Context=c-index-api-test.m] +// CHECK: <invalid loc>:0:0: StructDecl=objc_selector:0:0 [Context=c-index-api-test.m] +// CHECK: <invalid loc>:0:0: TypedefDecl=SEL:0:0 [Context=c-index-api-test.m] +// CHECK: <invalid loc>:0:0: ObjCInterfaceDecl=Protocol:0:0 [Context=c-index-api-test.m] +// CHECK: <invalid loc>:0:0: TypedefDecl=id:0:0 [Context=c-index-api-test.m] +// CHECK: <invalid loc>:0:0: TypedefDecl=Class:0:0 [Context=c-index-api-test.m] +// CHECK: <built-in>:79:16: StructDecl=__va_list_tag:79:16 [Context=c-index-api-test.m] +// CHECK: <built-in>:79:42: FieldDecl=gp_offset:79:42 [Context=__va_list_tag] +// CHECK: <built-in>:79:63: FieldDecl=fp_offset:79:63 [Context=__va_list_tag] +// CHECK: <built-in>:79:81: FieldDecl=overflow_arg_area:79:81 [Context=__va_list_tag] +// CHECK: <built-in>:79:107: FieldDecl=reg_save_area:79:107 [Context=__va_list_tag] +// CHECK: <built-in>:79:123: TypedefDecl=__va_list_tag:79:123 [Context=c-index-api-test.m] +// CHECK: <built-in>:79:159: TypedefDecl=__builtin_va_list:79:159 [Context=c-index-api-test.m] +// + +@interface Foo +{ +} + +- foo; ++ fooC; + +@end + +@interface Bar : Foo +{ +} + +@end + +@interface Foo (FooCat) +- (int) catMethodWithFloat:(float) fArg; +- (float) floatMethod; +@end + +@protocol Proto +- pMethod; +@end + +@protocol SubP <Proto> +- spMethod; +@end + +@interface Baz : Bar <SubP> +{ + int _anIVar; +} + +- (Foo *) bazMethod; + +@end + +enum { + someEnum +}; + +// CHECK: c-index-api-test.m:20:12: ObjCInterfaceDecl=Foo:20:1 [Context=c-index-api-test.m] +// CHECK: c-index-api-test.m:24:1: ObjCInstanceMethodDecl=foo:24:1 [Context=Foo] +// CHECK: c-index-api-test.m:25:1: ObjCClassMethodDecl=fooC:25:1 [Context=Foo] +// CHECK: c-index-api-test.m:29:12: ObjCInterfaceDecl=Bar:29:1 [Context=c-index-api-test.m] +// CHECK: c-index-api-test.m:29:18: ObjCSuperClassRef=Foo:29:1 [Context=Bar] +// CHECK: c-index-api-test.m:35:1: ObjCCategoryDecl=FooCat:35:1 [Context=c-index-api-test.m] +// CHECK: c-index-api-test.m:20:1: ObjCClassRef=Foo:35:1 [Context=FooCat] +// CHECK: c-index-api-test.m:36:1: ObjCInstanceMethodDecl=catMethodWithFloat::36:1 [Context=FooCat] +// CHECK: c-index-api-test.m:37:1: ObjCInstanceMethodDecl=floatMethod:37:1 [Context=FooCat] +// CHECK: c-index-api-test.m:40:1: ObjCProtocolDecl=Proto:40:1 [Context=c-index-api-test.m] +// CHECK: c-index-api-test.m:41:1: ObjCInstanceMethodDecl=pMethod:41:1 [Context=Proto] +// CHECK: c-index-api-test.m:44:1: ObjCProtocolDecl=SubP:44:1 [Context=c-index-api-test.m] +// CHECK: c-index-api-test.m:40:1: ObjCProtocolRef=Proto:40:1 [Context=SubP] +// CHECK: c-index-api-test.m:45:1: ObjCInstanceMethodDecl=spMethod:45:1 [Context=SubP] +// CHECK: c-index-api-test.m:48:12: ObjCInterfaceDecl=Baz:48:1 [Context=c-index-api-test.m] +// CHECK: c-index-api-test.m:48:18: ObjCSuperClassRef=Bar:48:1 [Context=Baz] +// CHECK: c-index-api-test.m:44:1: ObjCProtocolRef=SubP:44:1 [Context=Baz] +// CHECK: c-index-api-test.m:50:9: ObjCIvarDecl=_anIVar:50:9 [Context=Baz] +// CHECK: c-index-api-test.m:53:1: ObjCInstanceMethodDecl=bazMethod:53:1 [Context=Baz] +// CHECK: c-index-api-test.m:57:1: EnumDecl=:57:1 [Context=c-index-api-test.m] +// CHECK: c-index-api-test.m:58:3: EnumConstantDecl=someEnum:58:3 [Context=] + +int main (int argc, const char * argv[]) { + Baz * bee; + id a = [bee foo]; + id <SubP> c = [Foo fooC]; + id <Proto> d; + d = c; + [d pMethod]; + [bee catMethodWithFloat:[bee floatMethod]]; + main(someEnum, (const char **)bee); +} + +// CHECK: c-index-api-test.m:83:5: FunctionDefn=main [Context=c-index-api-test.m] +// CHECK: c-index-api-test.m:83:15: ParmDecl=argc:83:15 [Context=main] +// CHECK: c-index-api-test.m:83:34: ParmDecl=argv:83:34 [Context=main] +// CHECK: c-index-api-test.m:84:8: VarDecl=bee:84:8 [Context=main] +// CHECK: c-index-api-test.m:85:5: VarDecl=a:85:5 [Context=main] +// CHECK: c-index-api-test.m:86:12: VarDecl=c:86:12 [Context=main] +// CHECK: c-index-api-test.m:87:13: VarDecl=d:87:13 [Context=main] +// CHECK: c-index-api-test.m:84:2: ObjCClassRef=Baz:84:8 [Context:Baz] +// CHECK: c-index-api-test.m:84:3: ObjCClassRef=Baz:84:8 [Context:Baz] +// CHECK: c-index-api-test.m:84:4: ObjCClassRef=Baz:84:8 [Context:Baz] +// CHECK: c-index-api-test.m:84:6: VarDecl=bee:84:8 [Context:bee] +// CHECK: c-index-api-test.m:84:8: VarDecl=bee:84:8 [Context:bee] +// CHECK: c-index-api-test.m:84:9: VarDecl=bee:84:8 [Context:bee] +// CHECK: c-index-api-test.m:84:10: VarDecl=bee:84:8 [Context:bee] +// CHECK: <invalid loc>:85:2: TypedefDecl=id:0:0 [Context:id] +// CHECK: <invalid loc>:85:3: TypedefDecl=id:0:0 [Context:id] +// CHECK: c-index-api-test.m:85:5: VarDecl=a:85:5 [Context:a] +// CHECK: c-index-api-test.m:85:6: VarDecl=a:85:5 [Context:a] +// CHECK: c-index-api-test.m:85:7: VarDecl=a:85:5 [Context:a] +// CHECK: c-index-api-test.m:85:8: VarDecl=a:85:5 [Context:a] +// CHECK: c-index-api-test.m:85:9: ObjCSelectorRef=foo:24:1 [Context:a] +// CHECK: c-index-api-test.m:85:10: VarRef=bee:84:8 [Context:a] +// CHECK: c-index-api-test.m:85:11: VarRef=bee:84:8 [Context:a] +// CHECK: c-index-api-test.m:85:12: VarRef=bee:84:8 [Context:a] +// CHECK: c-index-api-test.m:85:13: ObjCSelectorRef=foo:24:1 [Context:a] +// CHECK: c-index-api-test.m:85:14: ObjCSelectorRef=foo:24:1 [Context:a] +// CHECK: c-index-api-test.m:85:15: ObjCSelectorRef=foo:24:1 [Context:a] +// CHECK: c-index-api-test.m:85:16: ObjCSelectorRef=foo:24:1 [Context:a] +// CHECK: c-index-api-test.m:85:17: ObjCSelectorRef=foo:24:1 [Context:a] +// CHECK: <invalid loc>:86:2: TypedefDecl=id:0:0 [Context:id] +// CHECK: <invalid loc>:86:3: TypedefDecl=id:0:0 [Context:id] +// CHECK: c-index-api-test.m:86:5: VarDecl=c:86:12 [Context:c] +// CHECK: c-index-api-test.m:86:6: ObjCProtocolRef=SubP:86:12 [Context:SubP] +// CHECK: c-index-api-test.m:86:7: ObjCProtocolRef=SubP:86:12 [Context:SubP] +// CHECK: c-index-api-test.m:86:8: ObjCProtocolRef=SubP:86:12 [Context:SubP] +// CHECK: c-index-api-test.m:86:9: ObjCProtocolRef=SubP:86:12 [Context:SubP] +// CHECK: c-index-api-test.m:86:10: VarDecl=c:86:12 [Context:c] +// CHECK: c-index-api-test.m:86:12: VarDecl=c:86:12 [Context:c] +// CHECK: c-index-api-test.m:86:13: VarDecl=c:86:12 [Context:c] +// CHECK: c-index-api-test.m:86:14: VarDecl=c:86:12 [Context:c] +// CHECK: c-index-api-test.m:86:15: VarDecl=c:86:12 [Context:c] +// CHECK: c-index-api-test.m:86:16: ObjCSelectorRef=fooC:25:1 [Context:c] +// CHECK: c-index-api-test.m:86:17: ObjCSelectorRef=fooC:25:1 [Context:c] +// CHECK: c-index-api-test.m:86:18: ObjCSelectorRef=fooC:25:1 [Context:c] +// CHECK: c-index-api-test.m:86:19: ObjCSelectorRef=fooC:25:1 [Context:c] +// CHECK: c-index-api-test.m:86:20: ObjCSelectorRef=fooC:25:1 [Context:c] +// CHECK: c-index-api-test.m:86:21: ObjCSelectorRef=fooC:25:1 [Context:c] +// CHECK: c-index-api-test.m:86:22: ObjCSelectorRef=fooC:25:1 [Context:c] +// CHECK: c-index-api-test.m:86:23: ObjCSelectorRef=fooC:25:1 [Context:c] +// CHECK: c-index-api-test.m:86:24: ObjCSelectorRef=fooC:25:1 [Context:c] +// CHECK: c-index-api-test.m:86:25: ObjCSelectorRef=fooC:25:1 [Context:c] +// CHECK: <invalid loc>:87:2: TypedefDecl=id:0:0 [Context:id] +// CHECK: <invalid loc>:87:3: TypedefDecl=id:0:0 [Context:id] +// CHECK: c-index-api-test.m:87:5: VarDecl=d:87:13 [Context:d] +// CHECK: c-index-api-test.m:87:6: ObjCProtocolRef=Proto:87:13 [Context:Proto] +// CHECK: c-index-api-test.m:87:7: ObjCProtocolRef=Proto:87:13 [Context:Proto] +// CHECK: c-index-api-test.m:87:8: ObjCProtocolRef=Proto:87:13 [Context:Proto] +// CHECK: c-index-api-test.m:87:9: ObjCProtocolRef=Proto:87:13 [Context:Proto] +// CHECK: c-index-api-test.m:87:10: ObjCProtocolRef=Proto:87:13 [Context:Proto] +// CHECK: c-index-api-test.m:87:11: VarDecl=d:87:13 [Context:d] +// CHECK: c-index-api-test.m:87:13: VarDecl=d:87:13 [Context:d] +// CHECK: c-index-api-test.m:88:2: VarRef=d:87:13 [Context:main] +// CHECK: c-index-api-test.m:88:6: VarRef=c:86:12 [Context:main] +// CHECK: c-index-api-test.m:89:2: ObjCSelectorRef=pMethod:41:1 [Context:main] +// CHECK: c-index-api-test.m:89:3: VarRef=d:87:13 [Context:main] +// CHECK: c-index-api-test.m:89:4: ObjCSelectorRef=pMethod:41:1 [Context:main] +// CHECK: c-index-api-test.m:89:5: ObjCSelectorRef=pMethod:41:1 [Context:main] +// CHECK: c-index-api-test.m:89:6: ObjCSelectorRef=pMethod:41:1 [Context:main] +// CHECK: c-index-api-test.m:89:7: ObjCSelectorRef=pMethod:41:1 [Context:main] +// CHECK: c-index-api-test.m:89:8: ObjCSelectorRef=pMethod:41:1 [Context:main] +// CHECK: c-index-api-test.m:89:9: ObjCSelectorRef=pMethod:41:1 [Context:main] +// CHECK: c-index-api-test.m:89:10: ObjCSelectorRef=pMethod:41:1 [Context:main] +// CHECK: c-index-api-test.m:89:11: ObjCSelectorRef=pMethod:41:1 [Context:main] +// CHECK: c-index-api-test.m:89:12: ObjCSelectorRef=pMethod:41:1 [Context:main] +// CHECK: c-index-api-test.m:90:2: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:3: VarRef=bee:84:8 [Context:main] +// CHECK: c-index-api-test.m:90:4: VarRef=bee:84:8 [Context:main] +// CHECK: c-index-api-test.m:90:5: VarRef=bee:84:8 [Context:main] +// CHECK: c-index-api-test.m:90:6: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:7: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:8: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:9: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:10: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:11: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:12: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:13: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:14: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:15: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:16: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:17: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:18: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:19: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:20: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:21: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:22: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:23: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:24: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:25: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:90:26: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:27: VarRef=bee:84:8 [Context:main] +// CHECK: c-index-api-test.m:90:28: VarRef=bee:84:8 [Context:main] +// CHECK: c-index-api-test.m:90:29: VarRef=bee:84:8 [Context:main] +// CHECK: c-index-api-test.m:90:30: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:31: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:32: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:33: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:34: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:35: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:36: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:37: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:38: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:39: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:40: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:41: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:42: ObjCSelectorRef=floatMethod:37:1 [Context:main] +// CHECK: c-index-api-test.m:90:43: ObjCSelectorRef=catMethodWithFloat::36:1 [Context:main] +// CHECK: c-index-api-test.m:91:3: FunctionRef=main:83:5 [Context:main] +// CHECK: c-index-api-test.m:91:4: FunctionRef=main:83:5 [Context:main] +// CHECK: c-index-api-test.m:91:5: FunctionRef=main:83:5 [Context:main] +// CHECK: c-index-api-test.m:91:6: FunctionRef=main:83:5 [Context:main] +// CHECK: c-index-api-test.m:91:8: EnumConstantRef=someEnum:58:3 [Context:main] +// CHECK: c-index-api-test.m:91:9: EnumConstantRef=someEnum:58:3 [Context:main] +// CHECK: c-index-api-test.m:91:10: EnumConstantRef=someEnum:58:3 [Context:main] +// CHECK: c-index-api-test.m:91:11: EnumConstantRef=someEnum:58:3 [Context:main] +// CHECK: c-index-api-test.m:91:12: EnumConstantRef=someEnum:58:3 [Context:main] +// CHECK: c-index-api-test.m:91:13: EnumConstantRef=someEnum:58:3 [Context:main] +// CHECK: c-index-api-test.m:91:14: EnumConstantRef=someEnum:58:3 [Context:main] +// CHECK: c-index-api-test.m:91:15: EnumConstantRef=someEnum:58:3 [Context:main] +// CHECK: c-index-api-test.m:91:33: VarRef=bee:84:8 [Context:main] +// CHECK: c-index-api-test.m:91:34: VarRef=bee:84:8 [Context:main] +// CHECK: c-index-api-test.m:91:35: VarRef=bee:84:8 [Context:main] diff --git a/test/Index/comments.c b/test/Index/comments.c index 7ad8fd7e1f49..689ce88e2213 100644 --- a/test/Index/comments.c +++ b/test/Index/comments.c @@ -1,15 +1,4 @@ -// RUN: clang-cc -emit-pch -o %t.ast %s && -// RUN: index-test %t.ast -point-at %s:22:6 | grep "starts here" && -// RUN: index-test %t.ast -point-at %s:22:6 | grep "block comment" && -// RUN: index-test %t.ast -point-at %s:28:6 | grep "BCPL" && -// RUN: index-test %t.ast -point-at %s:28:6 | grep "But" && -// RUN: index-test %t.ast -point-at %s:28:6 | grep "NOT" | count 0 && -// RUN: index-test %t.ast -point-at %s:30:6 | grep "member" - - - - - +// Run lines are sensitive to line numbers and come below the code. //! It all starts here. /*! It's a little odd to continue line this, @@ -27,4 +16,19 @@ void f(int, int); /** But there are other blocks that are part of the comment, too. */ void g(int); -void h(int); ///< This is a member comment.
\ No newline at end of file +void h(int); ///< This is a member comment. + + +// RUN: clang-cc -emit-pch -o %t.ast %s && + +// RUN: index-test %t.ast -point-at %s:11:6 > %t && +// RUN: grep "starts here" %t && +// RUN: grep "block comment" %t && + +// RUN: index-test %t.ast -point-at %s:17:6 > %t && +// RUN: grep "BCPL" %t && +// RUN: grep "But" %t && + +// RUN: index-test %t.ast -point-at %s:19:6 > %t && +// RUN: grep "NOT" %t | count 0 && +// RUN: grep "member" %t diff --git a/test/Index/cxx-operator-overload.cpp b/test/Index/cxx-operator-overload.cpp new file mode 100644 index 000000000000..9bda03ef8dc4 --- /dev/null +++ b/test/Index/cxx-operator-overload.cpp @@ -0,0 +1,28 @@ +// Run lines are sensitive to line numbers and come below the code. +// FIXME: re-enable this when we can serialize more C++ ASTs +class Cls { +public: + Cls operator +(const Cls &RHS); +}; + +static void bar() { + Cls x1, x2, x3; + Cls x4 = x1 + x2 + x3; +} + +Cls Cls::operator +(const Cls &RHS) { while (1) {} } + +// RUN: clang-cc -emit-pch %s -o %t.ast + +// RUNx: index-test %t.ast -point-at %s:10:17 -print-decls > %t && +// RUNx: cat %t | count 2 && +// RUNx: grep ':5:9,' %t && +// RUNx: grep ':13:10,' %t && + +// Yep, we can show references of '+' plus signs that are overloaded, w00t! +// RUNx: index-test %t.ast -point-at %s:5:15 -print-refs > %t && +// RUNx: cat %t | count 2 && +// RUNx: grep ':10:17,' %t && +// RUNx: grep ':10:22,' %t && + +// RUNx: index-test %t.ast -point-at %s:10:14 | grep 'DeclRefExpr x1' diff --git a/test/Index/find-decls.c b/test/Index/find-decls.c new file mode 100644 index 000000000000..50a233d75ba5 --- /dev/null +++ b/test/Index/find-decls.c @@ -0,0 +1,25 @@ +// RUN: clang-cc -fblocks -emit-pch %S/t1.c -o %t1.ast && +// RUN: clang-cc -fblocks -emit-pch %S/t2.c -o %t2.ast && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/t1.c:8:7 -print-decls > %t && +// RUN: cat %t | count 3 && +// RUN: grep 'foo.h:4:6,' %t | count 2 && +// RUN: grep 't2.c:5:6,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/t1.c:5:47 -print-decls > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't1.c:5:12,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/t1.c:6:20 -print-decls > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't1.c:3:19,' %t && + +// field test + +// RUN: index-test %t1.ast %t2.ast -point-at %S/t1.c:21:6 -print-decls > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't1.c:12:7,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/t1.c:22:21 -print-decls > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't1.c:16:7,' %t diff --git a/test/Index/find-defs.c b/test/Index/find-defs.c new file mode 100644 index 000000000000..0e63ae760047 --- /dev/null +++ b/test/Index/find-defs.c @@ -0,0 +1,18 @@ +// RUN: clang-cc -fblocks -emit-pch %S/t1.c -o %t1.ast && +// RUN: clang-cc -fblocks -emit-pch %S/t2.c -o %t2.ast && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/foo.h:1:14 -print-defs > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't2.c:3:5,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/foo.h:3:9 -print-defs > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't1.c:3:6,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/foo.h:4:9 -print-defs > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't2.c:5:6,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/t1.c:8:7 -print-defs > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't2.c:5:6,' %t diff --git a/test/Index/find-refs.c b/test/Index/find-refs.c new file mode 100644 index 000000000000..1b58b3752773 --- /dev/null +++ b/test/Index/find-refs.c @@ -0,0 +1,47 @@ +// RUN: clang-cc -fblocks -emit-pch %S/t1.c -o %t1.ast && +// RUN: clang-cc -fblocks -emit-pch %S/t2.c -o %t2.ast && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/foo.h:1:14 -print-refs > %t && +// RUN: cat %t | count 4 && +// RUN: grep 't1.c:4:19,' %t && +// RUN: grep 't1.c:28:40,' %t && +// RUN: grep 't2.c:6:3,' %t && +// RUN: grep 't2.c:7:12,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/foo.h:3:9 -print-refs > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't2.c:7:3,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/foo.h:4:9 -print-refs > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't1.c:8:3,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/t1.c:3:22 -print-refs > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't1.c:6:17,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/t1.c:4:11 -print-refs > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't1.c:6:5,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/t1.c:5:30 -print-refs > %t && +// RUN: cat %t | count 3 && +// RUN: grep 't1.c:5:27,' %t && +// RUN: grep 't1.c:5:44,' %t && +// RUN: grep 't1.c:6:26,' %t && + +// field test + +// FIXME: References point at the start of MemberExpr, make them point at the field instead. +// RUN: index-test %t1.ast %t2.ast -point-at %S/t1.c:12:7 -print-refs > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't1.c:21:3,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/t1.c:16:7 -print-refs > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't1.c:22:3,' %t && + +// RUN: index-test %t1.ast %t2.ast -point-at %S/foo.h:7:11 -print-refs > %t && +// RUN: cat %t | count 2 && +// RUN: grep 't1.c:25:3,' %t && +// RUN: grep 't2.c:10:3,' %t diff --git a/test/Index/foo.h b/test/Index/foo.h new file mode 100644 index 000000000000..7670c00dfbfe --- /dev/null +++ b/test/Index/foo.h @@ -0,0 +1,8 @@ +extern int global_var; + +void foo_func(int param1); +void bar_func(void); + +struct MyStruct { + int field_var; +}; diff --git a/test/Index/multiple-redecls.c b/test/Index/multiple-redecls.c new file mode 100644 index 000000000000..6f1f75b02f39 --- /dev/null +++ b/test/Index/multiple-redecls.c @@ -0,0 +1,12 @@ +// RUN: clang-cc -emit-pch %s -o %t.ast && +// RUN: index-test %t.ast -point-at %s:8:4 -print-decls | count 2 && +// RUN: index-test %t.ast -point-at %s:8:4 -print-defs | count 1 + +static void foo(int x); + +static void bar(void) { + foo(10); +} + +void foo(int x) { +} diff --git a/test/Index/objc-decls.m b/test/Index/objc-decls.m new file mode 100644 index 000000000000..1a8ab4b5577e --- /dev/null +++ b/test/Index/objc-decls.m @@ -0,0 +1,16 @@ +// RUN: clang-cc -emit-pch %S/t1.m -o %t1.m.ast && +// RUN: clang-cc -emit-pch %S/t2.m -o %t2.m.ast && + +// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/t1.m:12:12 -print-decls > %t && +// RUN: cat %t | count 2 && +// RUN: grep 'objc.h:2:9,' %t | count 2 && + +// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/objc.h:5:13 -print-decls > %t && +// RUN: cat %t | count 3 && +// RUN: grep 'objc.h:5:1,' %t | count 2 && +// RUN: grep 't1.m:15:1,' %t | count 1 && + +// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/objc.h:10:13 -print-decls > %t && +// RUN: cat %t | count 3 && +// RUN: grep 'objc.h:10:1,' %t | count 2 && +// RUN: grep 't2.m:11:1,' %t | count 1 diff --git a/test/Index/objc-message.m b/test/Index/objc-message.m new file mode 100644 index 000000000000..45ce83876cfe --- /dev/null +++ b/test/Index/objc-message.m @@ -0,0 +1,38 @@ +// RUN: clang-cc -emit-pch %S/t1.m -o %t1.m.ast && +// RUN: clang-cc -emit-pch %S/t2.m -o %t2.m.ast && + +// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/objc.h:5:13 -print-refs > %t && +// RUN: cat %t | count 1 && +// RUN: grep 't1.m:6:3,' %t && + +// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/objc.h:6:13 -print-refs > %t && +// RUN: cat %t | count 2 && +// RUN: grep 't1.m:7:3,' %t && +// RUN: grep 't2.m:7:3,' %t && + +// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/objc.h:10:13 -print-refs > %t && +// RUN: cat %t | count 2 && +// RUN: grep 't1.m:6:3,' %t && +// RUN: grep 't2.m:6:3,' %t && + +// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/t1.m:6:15 -print-decls > %t && +// RUN: cat %t | count 6 && +// RUN: grep 'objc.h:5:1,' %t | count 2 && +// RUN: grep 'objc.h:10:1,' %t | count 2 && +// RUN: grep 't1.m:15:1,' %t && +// RUN: grep 't2.m:11:1,' %t && + +// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/t1.m:7:15 -print-decls > %t && +// RUN: cat %t | count 3 && +// RUN: grep 'objc.h:6:1,' %t | count 2 && +// RUN: grep 't1.m:18:1,' %t && + +// RUN: index-test %t2.m.ast %t1.m.ast -point-at %S/t2.m:6:15 -print-decls > %t && +// RUN: cat %t | count 3 && +// RUN: grep 'objc.h:10:1,' %t | count 2 && +// RUN: grep 't2.m:11:1,' %t && + +// RUN: index-test %t2.m.ast %t1.m.ast -point-at %S/t2.m:7:15 -print-decls > %t && +// RUN: cat %t | count 3 && +// RUN: grep 'objc.h:6:1,' %t | count 2 && +// RUN: grep 't1.m:18:1,' %t diff --git a/test/Index/objc.h b/test/Index/objc.h new file mode 100644 index 000000000000..c671addde59f --- /dev/null +++ b/test/Index/objc.h @@ -0,0 +1,11 @@ +@interface Base { + int my_var; +} +-(int) my_var; +-(void) my_method: (int)param; ++(void) my_method: (int)param; +@end + +@interface Sub : Base +-(void) my_method: (int)param; +@end diff --git a/test/Index/resolve-loc.c b/test/Index/resolve-loc.c index d04b79b024ed..cae86f38dd6d 100644 --- a/test/Index/resolve-loc.c +++ b/test/Index/resolve-loc.c @@ -1,16 +1,4 @@ -// RUN: clang-cc -emit-pch %s -o %t.ast && -// RUN: index-test %t.ast -point-at %s:15:8 | grep top_var && -// RUN: index-test %t.ast -point-at %s:17:15 | grep top_func_decl && -// RUN: index-test %t.ast -point-at %s:17:25 | grep param1 && -// RUN: index-test %t.ast -point-at %s:19:17 | grep top_func_def && -// RUN: index-test %t.ast -point-at %s:19:23 | grep param2 && -// RUN: index-test %t.ast -point-at %s:20:10 | grep local_var1 && -// RUN: index-test %t.ast -point-at %s:21:15 | grep for_var && -// RUN: index-test %t.ast -point-at %s:21:43 | grep top_func_def && -// RUN: index-test %t.ast -point-at %s:21:43 | grep '++for_var' && -// RUN: index-test %t.ast -point-at %s:22:9 | grep local_var2 && -// RUN: index-test %t.ast -point-at %s:22:30 | grep local_var2 && -// RUN: index-test %t.ast -point-at %s:22:30 | grep 'for_var + 1' +// Run lines are sensitive to line numbers and come below the code. int top_var; @@ -22,3 +10,28 @@ void top_func_def(int param2) { int local_var2 = for_var + 1; } } + +struct S { + int field_var; +}; + + +// RUN: clang-cc -emit-pch %s -o %t.ast && +// RUN: index-test %t.ast -point-at %s:3:8 | grep top_var && +// RUN: index-test %t.ast -point-at %s:5:15 | grep top_func_decl && +// RUN: index-test %t.ast -point-at %s:5:25 | grep param1 && +// RUN: index-test %t.ast -point-at %s:7:17 | grep top_func_def && +// RUN: index-test %t.ast -point-at %s:7:23 | grep param2 && +// RUN: index-test %t.ast -point-at %s:8:10 | grep local_var1 && +// RUN: index-test %t.ast -point-at %s:9:15 | grep for_var && + +// RUN: index-test %t.ast -point-at %s:9:43 > %t && +// RUN: grep '++for_var' %t && + +// RUN: index-test %t.ast -point-at %s:10:9 | grep local_var2 && + +// RUN: index-test %t.ast -point-at %s:10:30 > %t && +// RUN: grep 'for_var + 1' %t && + +// fields test. +// RUN: index-test %t.ast -point-at %s:15:10 | grep field_var diff --git a/test/Index/t1.c b/test/Index/t1.c new file mode 100644 index 000000000000..45e04881244d --- /dev/null +++ b/test/Index/t1.c @@ -0,0 +1,31 @@ +#include "foo.h" + +void foo_func(int param1) { + int local_var = global_var; + for (int for_var = 100; for_var < 500; ++for_var) { + local_var = param1 + for_var; + } + bar_func(); +} + +struct S1 { + int x; +}; + +struct S2 { + int x; +}; + +void field_test(void) { + struct S1 s1; + s1.x = 0; + ((struct S2 *)0)->x = 0; + + struct MyStruct ms; + ms.field_var = 10; +} + +int (^CP)(int) = ^(int x) { return x * global_var; }; + +// Suppress 'no run line' failure. +// RUN: true diff --git a/test/Index/t1.m b/test/Index/t1.m new file mode 100644 index 000000000000..b2a7a3726d20 --- /dev/null +++ b/test/Index/t1.m @@ -0,0 +1,23 @@ +#include "objc.h" + +static void foo() { + Base *base; + int x = [base my_var]; + [base my_method:x]; + [Base my_method:x]; +} + +@implementation Base +-(int) my_var { + return my_var; +} + +-(void) my_method: (int)param { +} + ++(void) my_method: (int)param { +} +@end + +// Suppress 'no run line' failure. +// RUN: true diff --git a/test/Index/t2.c b/test/Index/t2.c new file mode 100644 index 000000000000..bf52869ec8d9 --- /dev/null +++ b/test/Index/t2.c @@ -0,0 +1,14 @@ +#include "foo.h" + +int global_var = 10; + +void bar_func(void) { + global_var += 100; + foo_func(global_var); + + struct MyStruct *ms; + ms->field_var = 10; +} + +// Suppress 'no run line' failure. +// RUN: true diff --git a/test/Index/t2.m b/test/Index/t2.m new file mode 100644 index 000000000000..00d2f1d92b05 --- /dev/null +++ b/test/Index/t2.m @@ -0,0 +1,16 @@ +#include "objc.h" + +static void foo() { + Sub *sub; + int x = [sub my_var]; + [sub my_method:x]; + [Sub my_method:x]; +} + +@implementation Sub +-(void) my_method: (int)param { +} +@end + +// Suppress 'no run line' failure. +// RUN: true diff --git a/test/Lexer/11-27-2007-FloatLiterals.c b/test/Lexer/11-27-2007-FloatLiterals.c index f3ea7cbaf9f4..ab3aba1a6eaf 100644 --- a/test/Lexer/11-27-2007-FloatLiterals.c +++ b/test/Lexer/11-27-2007-FloatLiterals.c @@ -1,5 +1,9 @@ -// RUN: clang-cc %s -emit-llvm -o - | grep 0x3BFD83C940000000 | count 2 && -// RUN: clang-cc %s -emit-llvm -o - | grep 2.000000e+32 | count 2 +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s + +// CHECK: 0x3BFD83C940000000 +// CHECK: 2.000000e+{{[0]*}}32 +// CHECK: 0x3BFD83C940000000 +// CHECK: 2.000000e+{{[0]*}}32 float F = 1e-19f; double D = 2e32; diff --git a/test/Lexer/comment-escape.c b/test/Lexer/comment-escape.c index c568cd611f1b..c46145715843 100644 --- a/test/Lexer/comment-escape.c +++ b/test/Lexer/comment-escape.c @@ -2,5 +2,5 @@ // rdar://6757323 // foo \ -#define blork 32 +#define blork 32 diff --git a/test/Lexer/dollar-idents.c b/test/Lexer/dollar-idents.c index 7635ea112eb7..f5c33b1f4368 100644 --- a/test/Lexer/dollar-idents.c +++ b/test/Lexer/dollar-idents.c @@ -1,5 +1,5 @@ // RUN: clang-cc -dump-tokens %s 2> %t && -// RUN: grep "identifier '\$A'" %t +// RUN: grep "identifier '\$A'" %t && // RUN: clang-cc -dump-tokens -x assembler-with-cpp %s 2> %t && // RUN: grep "identifier 'A'" %t // PR3808 diff --git a/test/Makefile b/test/Makefile index 271f46fdd6dc..8543d431442b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,7 +2,14 @@ LEVEL = ../../.. include $(LEVEL)/Makefile.common # Test in all immediate subdirectories if unset. -TESTDIRS ?= $(shell echo $(PROJ_SRC_DIR)/*/) +ifdef TESTSUITE +TESTDIRS := $(TESTSUITE:%=$(PROJ_SRC_DIR)/%) +else +TESTDIRS ?= $(PROJ_SRC_DIR) +endif + +# 'lit' wants objdir paths, so it will pick up the lit.site.cfg. +TESTDIRS := $(TESTDIRS:$(PROJ_SRC_DIR)%=$(PROJ_OBJ_DIR)%) ifndef TESTARGS ifdef VERBOSE @@ -12,9 +19,28 @@ TESTARGS = -s endif endif -all:: +ifdef VG + VGARG="--vg" +else + VGARG= +endif + +all:: lit.site.cfg @ echo '--- Running clang tests for $(TARGET_TRIPLE) ---' - @ PATH=$(ToolDir):$(LLVM_SRC_ROOT)/test/Scripts:$$PATH VG=$(VG) ../utils/test/MultiTestRunner.py $(TESTARGS) $(TESTDIRS) + @ $(PYTHON) $(LLVM_SRC_ROOT)/utils/lit/lit.py \ + $(TESTARGS) $(TESTDIRS) $(VGARG) + +FORCE: + +lit.site.cfg: FORCE + @echo "Making Clang 'lit.site.cfg' file..." + @sed -e "s#@LLVM_SOURCE_DIR@#$(LLVM_SRC_ROOT)#g" \ + -e "s#@LLVM_BINARY_DIR@#$(LLVM_OBJ_ROOT)#g" \ + -e "s#@LLVM_TOOLS_DIR@#$(ToolDir)#g" \ + -e "s#@LLVM_LIBS_DIR@#$(LibDir)#g" \ + -e "s#@CLANG_SOURCE_DIR@#$(PROJ_SRC_DIR)/..#g" \ + -e "s#@CLANG_BINARY_DIR@#$(PROJ_OBJ_DIR)/..#g" \ + $(PROJ_SRC_DIR)/lit.site.cfg.in > $@ clean:: @ rm -rf Output/ diff --git a/test/Misc/diag-mapping2.c b/test/Misc/diag-mapping2.c index 7e0d7742a9fe..c5fd7fff81f6 100644 --- a/test/Misc/diag-mapping2.c +++ b/test/Misc/diag-mapping2.c @@ -12,7 +12,10 @@ // RUN: clang-cc %s -Werror=#warnings 2>&1 | grep "error:" && // -Wno-error= overrides -Werror. rdar://3158301 -// RUN: clang-cc %s -Werror -Wno-error=#warnings 2>&1 | grep "warning:" +// RUN: clang-cc %s -Werror -Wno-error=#warnings 2>&1 | grep "warning:" && + +// -Wno-error overrides -Werror. PR4715 +// RUN: clang-cc %s -Werror -Wno-error 2>&1 | grep "warning:" #warning foo diff --git a/test/PCH/cxx-method.cpp b/test/PCH/cxx-method.cpp new file mode 100644 index 000000000000..144406e7bdaf --- /dev/null +++ b/test/PCH/cxx-method.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -emit-pch %s -o %t + +struct S { + void m(int x); +}; + +void S::m(int x) { } diff --git a/test/PCH/libroot/usr/include/reloc.h b/test/PCH/libroot/usr/include/reloc.h new file mode 100644 index 000000000000..04eeacba8ff5 --- /dev/null +++ b/test/PCH/libroot/usr/include/reloc.h @@ -0,0 +1,15 @@ +#ifndef RELOC_H +#define RELOC_H + +#include <reloc2.h> + + + + + + + +// Line number 13 below is important +int x = 2; + +#endif // RELOC_H diff --git a/test/PCH/libroot/usr/include/reloc2.h b/test/PCH/libroot/usr/include/reloc2.h new file mode 100644 index 000000000000..995415ce95bc --- /dev/null +++ b/test/PCH/libroot/usr/include/reloc2.h @@ -0,0 +1,15 @@ +#ifndef RELOC2_H +#define RELOC2_H +#include <stddef.h> + + + + + + + + + +// Line number below is important! +int y = 2; +#endif // RELOC2_H diff --git a/test/PCH/method_pool.h b/test/PCH/method_pool.h index f7af9044d92d..80858360d725 100644 --- a/test/PCH/method_pool.h +++ b/test/PCH/method_pool.h @@ -22,8 +22,7 @@ @end @implementation TestMethodPool1 -+ alloc { -} ++ alloc { return 0; } - (double)instMethod:(int)foo { return foo; diff --git a/test/PCH/objc_exprs.m b/test/PCH/objc_exprs.m index eb1ae434a7e0..48966f36f33a 100644 --- a/test/PCH/objc_exprs.m +++ b/test/PCH/objc_exprs.m @@ -6,7 +6,7 @@ // RUN: clang-cc -fblocks -include-pch %t -fsyntax-only -verify %s // Expressions -int *A1 = (objc_string)0; // expected-warning {{'struct objc_object *'}} +int *A1 = (objc_string)0; // expected-warning {{aka 'id'}} char A2 = (objc_encode){}; // expected-error {{not a compile-time constant}} \ expected-warning {{char [2]}} @@ -15,8 +15,7 @@ int *A3 = (objc_protocol)0; // expected-warning {{aka 'Protocol *'}} // Types. -int *T0 = (objc_id_protocol_ty)0; // expected-error {{not a compile-time constant}} \ - expected-warning {{aka 'id<foo>'}} +int *T0 = (objc_id_protocol_ty)0; // expected-warning {{aka 'id<foo>'}} int *T1 = (objc_interface_ty)0; // expected-warning {{aka 'itf *'}} int *T2 = (objc_qual_interface_ty)0; // expected-warning {{aka 'itf<foo> *'}} diff --git a/test/PCH/pr4489.c b/test/PCH/pr4489.c index 696da5bbb483..7730819e9213 100644 --- a/test/PCH/pr4489.c +++ b/test/PCH/pr4489.c @@ -1,7 +1,8 @@ // RUN: clang -x c-header -o %t.pch %s && // RUN: clang -include %t -x c /dev/null -emit-llvm -S -o - // PR 4489: Crash with PCH - +// PR 4492: Crash with PCH (round two) +// PR 4509: Crash with PCH (round three) typedef struct _IO_FILE FILE; extern int fprintf (struct _IO_FILE *__restrict __stream, __const char *__restrict __format, ...); @@ -17,4 +18,23 @@ int x(void) void y(void) { extern char z; fprintf (0, "a"); +} + +struct y0 { int i; } y0[1] = {}; + +void x0(void) +{ + extern char z0; + fprintf (0, "a"); +} + +void x1(void) +{ + fprintf (0, "asdf"); +} + +void y1(void) +{ + extern char e; + fprintf (0, "asdf"); }
\ No newline at end of file diff --git a/test/PCH/reloc.c b/test/PCH/reloc.c new file mode 100644 index 000000000000..b08187fdb8d8 --- /dev/null +++ b/test/PCH/reloc.c @@ -0,0 +1,14 @@ +// RUN: clang-cc -emit-pch -o %t --relocatable-pch -isysroot %S/libroot %S/libroot/usr/include/reloc.h && +// RUN: clang-cc -include-pch %t -isysroot %S/libroot %s -verify && +// RUN: not clang-cc -include-pch %t %s + +#include <reloc.h> + +int x = 2; // expected-error{{redefinition}} +int y = 5; // expected-error{{redefinition}} + + + + +// expected-note{{previous definition}} +// expected-note{{previous definition}} diff --git a/test/Parser/CompoundStmtScope.c b/test/Parser/CompoundStmtScope.c index 6a404aa3a2c6..90e3d24a32f5 100644 --- a/test/Parser/CompoundStmtScope.c +++ b/test/Parser/CompoundStmtScope.c @@ -1,6 +1,6 @@ // RUN: clang-cc -fsyntax-only -verify %s -int foo() { +void foo() { { typedef float X; } diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c index 6f5622e93932..572ac44d1f40 100644 --- a/test/Parser/MicrosoftExtensions.c +++ b/test/Parser/MicrosoftExtensions.c @@ -9,22 +9,22 @@ __declspec(noalias) __declspec(restrict) void * __cdecl xxx( void * _Memory ); typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR; void * __ptr64 PtrToPtr64(const void *p) { - return((void * __ptr64) (unsigned __int64) (ULONG_PTR)p ); + return((void * __ptr64) (unsigned __int64) (ULONG_PTR)p ); } -__forceinline InterlockedBitTestAndSet (long *Base, long Bit) // expected-warning {{type specifier missing, defaults to 'int'}} +void __forceinline InterlockedBitTestAndSet (long *Base, long Bit) { - __asm { - mov eax, Bit - mov ecx, Base - lock bts [ecx], eax - setc al - }; + __asm { + mov eax, Bit + mov ecx, Base + lock bts [ecx], eax + setc al + }; } void *_alloca(int); void foo() { - __declspec(align(16)) int *buffer = (int *)_alloca(9); + __declspec(align(16)) int *buffer = (int *)_alloca(9); } typedef bool (__stdcall __stdcall *blarg)(int); diff --git a/test/Parser/argument_redef.c b/test/Parser/argument_redef.c index 1a43178a40cd..fd22c465e5c6 100644 --- a/test/Parser/argument_redef.c +++ b/test/Parser/argument_redef.c @@ -1,6 +1,6 @@ /* RUN: clang-cc -fsyntax-only -verify %s */ -int foo(int A) { /* expected-note {{previous definition is here}} */ +void foo(int A) { /* expected-note {{previous definition is here}} */ int A; /* expected-error {{redefinition of 'A'}} */ } diff --git a/test/Parser/bad-control.c b/test/Parser/bad-control.c index 6e59667c3549..0bdd179af215 100644 --- a/test/Parser/bad-control.c +++ b/test/Parser/bad-control.c @@ -1,9 +1,9 @@ /* RUN: clang-cc -fsyntax-only -verify %s */ -int foo() { +void foo() { break; /* expected-error {{'break' statement not in loop or switch statement}} */ } -int foo2() { +void foo2() { continue; /* expected-error {{'continue' statement not in loop statement}} */ } diff --git a/test/Parser/cxx-ambig-paren-expr.cpp b/test/Parser/cxx-ambig-paren-expr.cpp index 1712d849d516..324f6b5f9f88 100644 --- a/test/Parser/cxx-ambig-paren-expr.cpp +++ b/test/Parser/cxx-ambig-paren-expr.cpp @@ -5,9 +5,9 @@ void f() { int x, *px; // Type id. - (T())x; // expected-error {{used type 'T ()'}} - (T())+x; // expected-error {{used type 'T ()'}} - (T())*px; // expected-error {{used type 'T ()'}} + (T())x; // expected-error {{cast from 'int' to 'T ()'}} + (T())+x; // expected-error {{cast from 'int' to 'T ()'}} + (T())*px; // expected-error {{cast from 'int' to 'T ()'}} // Expression. x = (T()); diff --git a/test/Parser/cxx-friend.cpp b/test/Parser/cxx-friend.cpp index ea30ddcbd0a8..14b31af761d3 100644 --- a/test/Parser/cxx-friend.cpp +++ b/test/Parser/cxx-friend.cpp @@ -1,4 +1,4 @@ -// RUN: clang-cc -fsyntax-only %s +// RUN: clang-cc -fsyntax-only -verify %s class C { friend class D; @@ -6,12 +6,27 @@ class C { class A { public: - void f(); + void f(); +}; + +friend int x; // expected-error {{'friend' used outside of class}} + +friend class D {}; // expected-error {{'friend' used outside of class}} + +union U { + int u1; }; class B { // 'A' here should refer to the declaration above. friend class A; - void f(A *a) { a->f(); } + friend C; // expected-error {{must specify 'class' to befriend}} + friend U; // expected-error {{must specify 'union' to befriend}} + friend int; // expected-error {{friends can only be classes or functions}} + + friend void myfunc(); + + void f(A *a) { a->f(); } }; + diff --git a/test/Parser/cxx-member-initializers.cpp b/test/Parser/cxx-member-initializers.cpp new file mode 100644 index 000000000000..bebb5c5e40d1 --- /dev/null +++ b/test/Parser/cxx-member-initializers.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct x { + x() : a(4) ; // expected-error {{expected '{'}} +}; + +struct y { + int a; + y() : a(4) ; // expected-error {{expected '{'}} +}; diff --git a/test/Parser/cxx-template-decl.cpp b/test/Parser/cxx-template-decl.cpp index 695501879098..9309b72a556e 100644 --- a/test/Parser/cxx-template-decl.cpp +++ b/test/Parser/cxx-template-decl.cpp @@ -2,16 +2,17 @@ // Errors export class foo { }; // expected-error {{expected template}} -template x; // expected-error {{C++ requires a type specifier for all declarations}} -export template x; // expected-error {{expected '<' after 'template'}} \ - // expected-note {{exported templates are unsupported}} \ -// expected-error {{C++ requires a type specifier for all declarations}} -// See Sema::ParsedFreeStandingDeclSpec about the double diagnostic. This is -// because ParseNonTypeTemplateParameter starts parsing a DeclSpec. +template x; // expected-error {{C++ requires a type specifier for all declarations}} \ + // expected-error {{does not refer}} +export template x; // expected-error {{expected '<' after 'template'}} +export template<class T> class x0; // expected-note {{exported templates are unsupported}} template < ; // expected-error {{parse error}} expected-error {{declaration does not declare anything}} -template <template X> struct Err1; // expected-error {{expected '<' after 'template'}} -template <template <typename> > struct Err2; // expected-error {{expected 'class' before '>'}} -template <template <typename> Foo> struct Err3; // expected-error {{expected 'class' before 'Foo'}} +template <template X> struct Err1; // expected-error {{expected '<' after 'template'}} \ +// expected-error{{extraneous}} +template <template <typename> > struct Err2; // expected-error {{expected 'class' before '>'}} \ +// expected-error{{extraneous}} +template <template <typename> Foo> struct Err3; // expected-error {{expected 'class' before 'Foo'}} \ +// expected-error{{extraneous}} // Template function declarations template <typename T> void foo(); @@ -53,7 +54,7 @@ template <typename T, typename U> struct B { }; // Template parameter shadowing template<typename T, // expected-note{{template parameter is declared here}} - typename T> // expected-error{{declaration of 'T' shadows template parameter}} + typename T> // expected-error{{declaration of 'T' shadows template parameter}} void shadow1(); template<typename T> // expected-note{{template parameter is declared here}} diff --git a/test/Parser/cxx-using-declaration.cpp b/test/Parser/cxx-using-declaration.cpp index de0e6f162a76..212a7d89f877 100644 --- a/test/Parser/cxx-using-declaration.cpp +++ b/test/Parser/cxx-using-declaration.cpp @@ -1,45 +1,47 @@ -// RUN: clang-cc -fsyntax-only -verify %s
-
-namespace A {
- int VA;
- void FA() {}
- struct SA { int V; };
-}
-
-using A::VA;
-using A::FA;
-using typename A::SA;
-
-void main()
-{
- VA = 1;
- FA();
- SA x; //Still needs handling.
-}
-
-struct B {
- void f(char){};
- void g(char){};
-};
-struct D : B {
- using B::f;
- void f(int);
- void g(int);
-};
-void D::f(int) { f('c'); } // calls B::f(char)
-void D::g(int) { g('c'); } // recursively calls D::g(int)
-
-namespace E {
- template <typename TYPE> int funcE(TYPE arg) { return(arg); }
-}
-
-using E::funcE<int>; // expected-error{{use of template specialization in using directive not allowed}}
-
-namespace F {
- struct X;
-}
-
-using F::X;
-// Should have some errors here. Waiting for implementation.
-void X(int);
-struct X *x;
+// FIXME: Disabled, appears to have undefined behavior, and needs to be updated to match new warnings. +// RUN: true +// RUNX: clang-cc -fsyntax-only -verify %s + +namespace A { + int VA; + void FA() {} + struct SA { int V; }; +} + +using A::VA; +using A::FA; +using typename A::SA; + +void main() +{ + VA = 1; + FA(); + SA x; //Still needs handling. +} + +struct B { + void f(char){}; + void g(char){}; +}; +struct D : B { + using B::f; + void f(int); + void g(int); +}; +void D::f(int) { f('c'); } // calls B::f(char) +void D::g(int) { g('c'); } // recursively calls D::g(int) + +namespace E { + template <typename TYPE> int funcE(TYPE arg) { return(arg); } +} + +using E::funcE<int>; // expected-error{{use of template specialization in using directive not allowed}} + +namespace F { + struct X; +} + +using F::X; +// Should have some errors here. Waiting for implementation. +void X(int); +struct X *x; diff --git a/test/Parser/declarators.c b/test/Parser/declarators.c index 26e8027d1078..da8327a1e834 100644 --- a/test/Parser/declarators.c +++ b/test/Parser/declarators.c @@ -18,7 +18,7 @@ int *A; struct str; -int test2(int *P, int A) { +void test2(int *P, int A) { struct str; // Hard case for array decl, not Array[*]. @@ -26,11 +26,11 @@ int test2(int *P, int A) { } typedef int atype; -int test3(x, - atype /* expected-error {{unexpected type name 'atype': expected identifier}} */ - ) int x, atype; {} +void test3(x, + atype /* expected-error {{unexpected type name 'atype': expected identifier}} */ + ) int x, atype; {} -int test4(x, x) int x; {} /* expected-error {{redefinition of parameter 'x'}} */ +void test4(x, x) int x; {} /* expected-error {{redefinition of parameter 'x'}} */ // PR3031 diff --git a/test/Parser/implicit-casts.c b/test/Parser/implicit-casts.c index e7d20980da47..3e8f599047c4 100644 --- a/test/Parser/implicit-casts.c +++ b/test/Parser/implicit-casts.c @@ -15,6 +15,7 @@ void test2() { int test3() { int a[2]; a[0] = test3; // expected-warning{{incompatible pointer to integer conversion assigning 'int ()', expected 'int'}} + return 0; } short x; void test4(char c) { x += c; } int y; void test5(char c) { y += c; } diff --git a/test/Parser/objc-messaging-neg-1.m b/test/Parser/objc-messaging-neg-1.m index a1ec116fb7b4..0344566aa87a 100644 --- a/test/Parser/objc-messaging-neg-1.m +++ b/test/Parser/objc-messaging-neg-1.m @@ -1,7 +1,6 @@ // RUN: clang-cc -fsyntax-only -verify %s -int main() - { - id a; - [a bla:0 6:7]; // expected-error {{expected ']'}} - } +int main() { + id a; + [a bla:0 6:7]; // expected-error {{expected ']'}} +} diff --git a/test/Parser/pointer_promotion.c b/test/Parser/pointer_promotion.c index 0254828e0f02..3226eabbf53d 100644 --- a/test/Parser/pointer_promotion.c +++ b/test/Parser/pointer_promotion.c @@ -1,6 +1,6 @@ // RUN: clang-cc -fsyntax-only -verify %s -int test() { +void test() { void *vp; int *ip; char *cp; @@ -15,4 +15,3 @@ int test() { if (sint < ip) {} // expected-warning {{comparison between pointer and integer ('int' and 'int *')}} if (ip == cp) {} // expected-warning {{comparison of distinct pointer types ('int *' and 'char *')}} } - diff --git a/test/Parser/pragma-weak.c b/test/Parser/pragma-weak.c index 355a95487b97..dca0f8dd4c15 100644 --- a/test/Parser/pragma-weak.c +++ b/test/Parser/pragma-weak.c @@ -10,7 +10,7 @@ int x; extern int z; /* expected-warning {{expected identifier in '#pragma weak'}}*/ #pragma weak z = = /* expected-warning {{expected identifier in '#pragma weak'}}*/ #pragma weak z = -#pragma weak z = y +/* expected-warning {{weak identifier 'y' never declared}} */ #pragma weak z = y extern int a; /* expected-warning {{extra tokens at end of '#pragma weak'}}*/ #pragma weak a b diff --git a/test/Parser/recovery.c b/test/Parser/recovery.c index 89eac564a329..43d3e2d8a69d 100644 --- a/test/Parser/recovery.c +++ b/test/Parser/recovery.c @@ -8,10 +8,10 @@ float test2241[2] = { // Testcase derived from PR2692 -static char *f (char * (*g) (char **, int), char **p, ...) { - char *s; - va_list v; // expected-error {{identifier}} - s = g (p, __builtin_va_arg(v, int)); // expected-error {{identifier}} +static void f (char * (*g) (char **, int), char **p, ...) { + char *s; + va_list v; // expected-error {{identifier}} + s = g (p, __builtin_va_arg(v, int)); // expected-error {{identifier}} } @@ -20,7 +20,7 @@ static char *f (char * (*g) (char **, int), char **p, ...) { // rdar://6094870 -int test(int a) { +void test(int a) { struct { int i; } x; if (x.hello) // expected-error {{no member named 'hello'}} @@ -61,7 +61,7 @@ struct S A = { }; // rdar://6248081 -int test6248081() { +void test6248081() { [10] // expected-error {{expected expression}} } diff --git a/test/Parser/statements.c b/test/Parser/statements.c index b95c23fb28b0..25e06a27bd13 100644 --- a/test/Parser/statements.c +++ b/test/Parser/statements.c @@ -1,24 +1,24 @@ // RUN: clang-cc -fsyntax-only -verify %s -int test1() { +void test1() { { ; { ;;}} ;; } -int test2() { +void test2() { if (0) { if (1) {} } else { } do { } while (0); while (0) while(0) do ; while(0); - for (0;0;0) + for ((void)0;0;(void)0) for (;;) - for (9;0;2) + for ((void)9;0;(void)2) ; - for (int X = 0; 0; 0); + for (int X = 0; 0; (void)0); } -int test3() { +void test3() { switch (0) { case 4: @@ -30,7 +30,7 @@ int test3() { } } -int test4() { +void test4() { if (0); // expected-warning {{if statement has empty body}} int X; // declaration in a block. diff --git a/test/Parser/top-level-semi-cxx0x.cpp b/test/Parser/top-level-semi-cxx0x.cpp new file mode 100644 index 000000000000..e83fd9e8dbd7 --- /dev/null +++ b/test/Parser/top-level-semi-cxx0x.cpp @@ -0,0 +1,15 @@ +// RUN: clang-cc -fsyntax-only -pedantic -std=c++0x -verify %s + +void foo(); + +void bar() { }; + +void wibble(); + +; + +namespace Blah { + void f() { }; + + void g(); +} diff --git a/test/Preprocessor/assembler-with-cpp.c b/test/Preprocessor/assembler-with-cpp.c index 2e84ed1a6b07..f7706ca676ce 100644 --- a/test/Preprocessor/assembler-with-cpp.c +++ b/test/Preprocessor/assembler-with-cpp.c @@ -40,7 +40,7 @@ // rdar://6709206 // RUN: grep "5: expanded (" %t && #define M4 expanded -#define M5() M4 ## ( +#define M5() M4 ## ( 5: M5() diff --git a/test/Preprocessor/macro-multiline.c b/test/Preprocessor/macro-multiline.c index eb15668ce31f..ba988253b272 100644 --- a/test/Preprocessor/macro-multiline.c +++ b/test/Preprocessor/macro-multiline.c @@ -1,4 +1,4 @@ -// RUN: clang -E %s "-DX=A +// RUN: clang -E %s "-DX=A && // RUN: THIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT" > %t && // RUN: grep "GOOD: A" %t && // RUN: not grep THIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT %t diff --git a/test/Preprocessor/macro_fn_comma_swallow.c b/test/Preprocessor/macro_fn_comma_swallow.c index e985138a5c44..d39d4e7841d5 100644 --- a/test/Preprocessor/macro_fn_comma_swallow.c +++ b/test/Preprocessor/macro_fn_comma_swallow.c @@ -1,7 +1,7 @@ // Test the GNU comma swallowing extension. // RUN: clang-cc %s -E | grep 'foo{A, }' && // RUN: clang-cc %s -E | grep 'fo2{A,}' && -// RUN: clang-cc %s -E | grep '{foo}' +// RUN: clang-cc %s -E | grep '{foo}' && #define X(Y) foo{A, Y} X() diff --git a/test/Preprocessor/macro_paste_mscomment.c b/test/Preprocessor/macro_paste_mscomment.c index b0fc57101c64..d6ead91068cf 100644 --- a/test/Preprocessor/macro_paste_mscomment.c +++ b/test/Preprocessor/macro_paste_mscomment.c @@ -1,5 +1,5 @@ -// RUN: clang-cc -P -E -fms-extensions %s | sed '/^#.\+/d' | tr -d '\n' | -// RUN: grep '^int foo;int bar;int baz;$' | count 1 +// RUN: clang-cc -P -E -fms-extensions %s | sed '/^#.\+/d' | tr -d '\n' > %t && +// RUN: grep '^int foo;int bar;int baz;$' %t | count 1 // This horrible stuff should preprocess into (other than whitespace): // int foo; // int bar; diff --git a/test/Preprocessor/non_fragile_feature.m b/test/Preprocessor/non_fragile_feature.m new file mode 100644 index 000000000000..cb6bc012f1c2 --- /dev/null +++ b/test/Preprocessor/non_fragile_feature.m @@ -0,0 +1,8 @@ +// RUN: clang-cc -fobjc-nonfragile-abi %s +#ifndef __has_feature +#error Should have __has_feature +#endif + +#if !__has_feature(objc_nonfragile_abi) +#error Non-fragile ABI used for compilation but feature macro not set. +#endif diff --git a/test/Preprocessor/non_fragile_feature1.m b/test/Preprocessor/non_fragile_feature1.m new file mode 100644 index 000000000000..59f665b54649 --- /dev/null +++ b/test/Preprocessor/non_fragile_feature1.m @@ -0,0 +1,8 @@ +// RUN: clang-cc -triple i386-unknown-unknown %s +#ifndef __has_feature +#error Should have __has_feature +#endif + +#if __has_feature(objc_nonfragile_abi) +#error Non-fragile ABI not used for compilation but feature macro set. +#endif diff --git a/test/Preprocessor/pushable-diagnostics.c b/test/Preprocessor/pushable-diagnostics.c new file mode 100644 index 000000000000..fe55122d66cd --- /dev/null +++ b/test/Preprocessor/pushable-diagnostics.c @@ -0,0 +1,17 @@ +// RUN: clang-cc -fsyntax-only -verify -pedantic %s + +#pragma clang diagnostic pop // expected-warning{{pragma diagnostic pop could not pop, no matching push}} + +#pragma clang diagnostic puhs // expected-warning{{pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal' 'push', or 'pop'}} + +char a = 'df'; // expected-warning{{multi-character character constant}} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmultichar" + +char b = 'df'; // no warning. +#pragma clang diagnostic pop + +char c = 'df'; // expected-warning{{multi-character character constant}} + +#pragma clang diagnostic pop // expected-warning{{pragma diagnostic pop could not pop, no matching push}} diff --git a/test/Rewriter/id-test-3.m b/test/Rewriter/id-test-3.m index ad1e76decf80..7e4cc51d7357 100644 --- a/test/Rewriter/id-test-3.m +++ b/test/Rewriter/id-test-3.m @@ -10,5 +10,5 @@ @implementation INTF - (id<P>)IMeth { return [(id<P>)self Meth: (id<P>)0]; } -- (id<P>) Meth : (id<P>) Arg {} +- (id<P>) Meth : (id<P>) Arg { return 0; } @end diff --git a/test/Rewriter/method-encoding-1.m b/test/Rewriter/method-encoding-1.m index 25dccbf75084..05df60291e02 100644 --- a/test/Rewriter/method-encoding-1.m +++ b/test/Rewriter/method-encoding-1.m @@ -11,8 +11,8 @@ @end @implementation Intf -- (char *) MyMeth : (double) arg1 : (char *[12]) arg2{} +- (char *) MyMeth : (double) arg1 : (char *[12]) arg2{ return 0; } - (void) MyProtoMeth : (int **) arg1 : (void*) arg2 {} + (void) MyProtoMeth : (int **) arg1 : (void*) arg2 {} -- (id) address:(void *)location with:(unsigned **)arg2{} +- (id) address:(void *)location with:(unsigned **)arg2{ return 0; } @end diff --git a/test/Rewriter/rewrite-foreach-4.m b/test/Rewriter/rewrite-foreach-4.m index 774f9a0b75c8..5c831ea18b20 100644 --- a/test/Rewriter/rewrite-foreach-4.m +++ b/test/Rewriter/rewrite-foreach-4.m @@ -9,7 +9,7 @@ { return 0; } -- (id) allKeys {} +- (id) allKeys { return 0; } @end @interface MyList (BasicTest) diff --git a/test/Rewriter/rewrite-foreach-5.m b/test/Rewriter/rewrite-foreach-5.m index d0d12444a3e7..d03f6ce84df6 100644 --- a/test/Rewriter/rewrite-foreach-5.m +++ b/test/Rewriter/rewrite-foreach-5.m @@ -9,7 +9,7 @@ { return 0; } -- (id) allKeys {} +- (id) allKeys { return 0; } @end @interface MyList (BasicTest) diff --git a/test/Sema/address_spaces.c b/test/Sema/address_spaces.c index b79799f0230c..d9d23edb3cf4 100644 --- a/test/Sema/address_spaces.c +++ b/test/Sema/address_spaces.c @@ -4,7 +4,11 @@ #define _AS2 __attribute__((address_space(2))) #define _AS3 __attribute__((address_space(3))) -void foo(_AS3 float *a) { +void bar(_AS2 int a); // expected-error {{parameter may not be qualified with an address space}} + +void foo(_AS3 float *a, + _AS1 float b) // expected-error {{parameter may not be qualified with an address space}} +{ _AS2 *x;// expected-warning {{type specifier missing, defaults to 'int'}} _AS1 float * _AS2 *B; @@ -15,7 +19,13 @@ void foo(_AS3 float *a) { _AS1 int array[5]; // expected-error {{automatic variable qualified with an address space}} _AS1 int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}} - *a = 5.0f; + __attribute__((address_space(-1))) int *_boundsA; // expected-error {{address space is negative}} + __attribute__((address_space(0xFFFFFF))) int *_boundsB; + __attribute__((address_space(0x1000000))) int *_boundsC; // expected-error {{address space is larger than the maximum supported}} + // chosen specifically to overflow 32 bits and come out reasonable + __attribute__((address_space(4294967500))) int *_boundsD; // expected-error {{address space is larger than the maximum supported}} + + *a = 5.0f + b; } struct _st { @@ -27,6 +37,6 @@ struct _st { __attribute__((address_space(256))) void * * const base = 0; void * get_0(void) { return base[0]; // expected-error {{illegal implicit cast between two pointers with different address spaces}} \ - expected-warning {{returning 'void __attribute__((address_space(256)))*' discards qualifiers, expected 'void *'}} + expected-warning {{returning 'void __attribute__((address_space(256))) *' discards qualifiers, expected 'void *'}} } diff --git a/test/Sema/align-arm-apcs.c b/test/Sema/align-arm-apcs.c new file mode 100644 index 000000000000..924ba9034d8b --- /dev/null +++ b/test/Sema/align-arm-apcs.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -triple arm-unknown-unknown -target-abi=apcs-gnu -fsyntax-only -verify %s + +struct s0 { double f0; int f1; }; +char chk0[__alignof__(struct s0) == 4 ? 1 : -1]; diff --git a/test/Sema/altivec-init.c b/test/Sema/altivec-init.c new file mode 100644 index 000000000000..6185186903b0 --- /dev/null +++ b/test/Sema/altivec-init.c @@ -0,0 +1,16 @@ +// RUN: clang-cc %s -faltivec -verify -pedantic -fsyntax-only -fblocks=0 + +typedef int v4 __attribute((vector_size(16))); +typedef short v8 __attribute((vector_size(16))); + +v8 foo(void) { + v8 a; + v4 b; + a = (v8){4, 2}; // expected-error {{too few elements in vector initialization (expected 8 elements, have 2)}} + b = (v4)(5, 6, 7, 8, 9); // expected-warning {{excess elements in vector initializer}} + b = (v4)(5, 6, 8, 8.0f); + return (v8){0, 1, 2, 3, 1, 2, 3, 4}; + + // FIXME: test that (type)(fn)(args) still works with -faltivec + // FIXME: test that c++ overloaded commas still work -faltivec +} diff --git a/test/Sema/arg-scope-c99.c b/test/Sema/arg-scope-c99.c index b5b1c8a812c1..1d81410b8d01 100644 --- a/test/Sema/arg-scope-c99.c +++ b/test/Sema/arg-scope-c99.c @@ -1,2 +1,2 @@ // RUN: clang-cc -fsyntax-only -std=c99 -verify %s -int bb(int sz, int ar[sz][sz]) { } +void bb(int sz, int ar[sz][sz]) { } diff --git a/test/Sema/arg-scope.c b/test/Sema/arg-scope.c index c1cc7e112f88..d5e59603cfbf 100644 --- a/test/Sema/arg-scope.c +++ b/test/Sema/arg-scope.c @@ -1,5 +1,5 @@ // RUN: clang-cc -fsyntax-only -verify %s -int aa(int b, int x[sizeof b]) {} +void aa(int b, int x[sizeof b]) {} void foo(int i, int A[i]) {} diff --git a/test/Sema/array-constraint.c b/test/Sema/array-constraint.c index 5a09e20ecbff..6407b5daf56a 100644 --- a/test/Sema/array-constraint.c +++ b/test/Sema/array-constraint.c @@ -45,7 +45,7 @@ typedef int TA[I]; // expected-error {{variable length array declaration not all void strFunc(char *); const char staticAry[] = "test"; -int checkStaticAry() { +void checkStaticAry() { strFunc(staticAry); // expected-warning{{passing 'char const [5]' discards qualifiers, expected 'char *'}} } diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c index 50148a83ae13..c78fd29a89c1 100644 --- a/test/Sema/array-init.c +++ b/test/Sema/array-init.c @@ -144,12 +144,11 @@ int xx_sizecheck[(sizeof(xx) / sizeof(char)) == 5? 1 : -1]; static char const yy[5] = "test"; static char const zz[3] = "test"; // expected-warning{{initializer-string for char array is too long}} -void charArrays() -{ - static char const test[] = "test"; - int test_sizecheck[(sizeof(test) / sizeof(char)) == 5? 1 : -1]; - static char const test2[] = { "weird stuff" }; - static char const test3[] = { "test", "excess stuff" }; // expected-warning{{excess elements in char array initializer}} +void charArrays() { + static char const test[] = "test"; + int test_sizecheck[(sizeof(test) / sizeof(char)) == 5? 1 : -1]; + static char const test2[] = { "weird stuff" }; + static char const test3[] = { "test", "excess stuff" }; // expected-warning{{excess elements in char array initializer}} char* cp[] = { "Hello" }; @@ -219,10 +218,10 @@ void varArray() { } // PR2151 -int emptyInit() {struct {} x[] = {6};} //expected-warning{{empty struct extension}} expected-error{{initializer for aggregate with no elements}} +void emptyInit() {struct {} x[] = {6};} //expected-warning{{empty struct extension}} expected-error{{initializer for aggregate with no elements}} -int noNamedInit() { -struct {int:5;} x[] = {6}; //expected-error{{initializer for aggregate with no elements}} +void noNamedInit() { + struct {int:5;} x[] = {6}; //expected-error{{initializer for aggregate with no elements}} } struct {int a; int:5;} noNamedImplicit[] = {1,2,3}; int noNamedImplicitCheck[sizeof(noNamedImplicit) == 3 * sizeof(*noNamedImplicit) ? 1 : -1]; @@ -230,15 +229,15 @@ int noNamedImplicitCheck[sizeof(noNamedImplicit) == 3 * sizeof(*noNamedImplicit) // ptrs are constant struct soft_segment_descriptor { - long ssd_base; + long ssd_base; }; static int dblfault_tss; union uniao { int ola; } xpto[1]; struct soft_segment_descriptor gdt_segs[] = { - {(long) &dblfault_tss}, - { (long)xpto}, + {(long) &dblfault_tss}, + { (long)xpto}, }; static void sppp_ipv6cp_up(); diff --git a/test/Sema/attr-decl-after-definition.c b/test/Sema/attr-decl-after-definition.c new file mode 100644 index 000000000000..c1d1b536fc69 --- /dev/null +++ b/test/Sema/attr-decl-after-definition.c @@ -0,0 +1,19 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void foo(); +void foo() __attribute__((unused)); +void foo() __attribute__((unused)); +void foo(){} // expected-note {{previous definition is here}} +void foo() __attribute__((constructor)); // expected-warning {{must precede definition}} +void foo(); + +int bar; +extern int bar; +int bar; +int bar __attribute__((weak)); +int bar __attribute__((used)); +extern int bar __attribute__((weak)); +int bar = 0; // expected-note {{previous definition is here}} +int bar __attribute__((weak)); // expected-warning {{must precede definition}} +int bar; + diff --git a/test/Sema/attr-deprecated.c b/test/Sema/attr-deprecated.c index 6597bad4b572..e15381e4c6d1 100644 --- a/test/Sema/attr-deprecated.c +++ b/test/Sema/attr-deprecated.c @@ -21,7 +21,7 @@ int a() { // test if attributes propagate to variables extern int var; int w() { - return var; // expected-warning {{'var' is deprecated}} + return var; // expected-warning {{'var' is deprecated}} } int old_fn() __attribute__ ((deprecated)); diff --git a/test/Sema/attr-format_arg.c b/test/Sema/attr-format_arg.c index 6f953155f8c8..0830951acc89 100644 --- a/test/Sema/attr-format_arg.c +++ b/test/Sema/attr-format_arg.c @@ -1,3 +1,5 @@ +// RUN: clang-cc -fsyntax-only -verify %s + #include <stdio.h> const char* f(const char *s) __attribute__((format_arg(1))); diff --git a/test/Sema/attr-malloc.c b/test/Sema/attr-malloc.c new file mode 100644 index 000000000000..1adcf074a499 --- /dev/null +++ b/test/Sema/attr-malloc.c @@ -0,0 +1,25 @@ +// RUN: clang-cc -verify -fsyntax-only %s && +// RUN: clang-cc -emit-llvm -o %t %s && + +#include <stdlib.h> + +int no_vars __attribute((malloc)); // expected-warning {{functions returning a pointer type}} + +void returns_void (void) __attribute((malloc)); // expected-warning {{functions returning a pointer type}} +int returns_int (void) __attribute((malloc)); // expected-warning {{functions returning a pointer type}} +int * returns_intptr(void) __attribute((malloc)); // no-warning +typedef int * iptr; +iptr returns_iptr (void) __attribute((malloc)); // no-warning + +__attribute((malloc)) void *(*f)(); // expected-warning{{'malloc' attribute only applies to functions returning a pointer type}} +__attribute((malloc)) int (*g)(); // expected-warning{{'malloc' attribute only applies to functions returning a pointer type}} + +__attribute((malloc)) +void * xalloc(unsigned n) { return malloc(n); } // no-warning +// RUN: grep 'define noalias .* @xalloc(' %t && + +#define malloc_like __attribute((__malloc__)) +void * xalloc2(unsigned) malloc_like; +void * xalloc2(unsigned n) { return malloc(n); } +// RUN: grep 'define noalias .* @xalloc2(' %t + diff --git a/test/Sema/attr-noreturn.c b/test/Sema/attr-noreturn.c index d1417f093ffb..b83eb94e0582 100644 --- a/test/Sema/attr-noreturn.c +++ b/test/Sema/attr-noreturn.c @@ -4,7 +4,7 @@ static void (*fp0)(void) __attribute__((noreturn)); static void __attribute__((noreturn)) f0(void) { fatal(); -} +} // expected-warning {{function declared 'noreturn' should not return}} // On K&R int f1() __attribute__((noreturn)); @@ -25,3 +25,11 @@ void f4() { return; // expected-warning {{function 'f4' declared 'noreturn' should not return}} } +// PR4685 +extern void f5 (unsigned long) __attribute__ ((__noreturn__)); + +void +f5 (unsigned long size) +{ + +} diff --git a/test/Sema/attr-section.c b/test/Sema/attr-section.c new file mode 100644 index 000000000000..c61ed80cbf7a --- /dev/null +++ b/test/Sema/attr-section.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -verify -fsyntax-only -triple x86_64-apple-darwin9 %s + +int x __attribute__((section( + 42))); // expected-error {{argument to section attribute was not a string literal}} + + +// rdar://4341926 +int y __attribute__((section( + "sadf"))); // expected-error {{mach-o section specifier requires a segment and section separated by a comma}} + diff --git a/test/Sema/attr-weak.c b/test/Sema/attr-weak.c index b79e1e7dfca7..4532cccf98d9 100644 --- a/test/Sema/attr-weak.c +++ b/test/Sema/attr-weak.c @@ -5,9 +5,11 @@ extern int g1 __attribute__((weak_import)); int g2 __attribute__((weak)); int g3 __attribute__((weak_import)); // expected-warning {{'weak_import' attribute cannot be specified on a definition}} int __attribute__((weak_import)) g4(void); -int __attribute__((weak_import)) g5(void) { +void __attribute__((weak_import)) g5(void) { } struct __attribute__((weak)) s0 {}; // expected-warning {{'weak' attribute only applies to variable and function types}} struct __attribute__((weak_import)) s1 {}; // expected-warning {{'weak_import' attribute only applies to variable and function types}} +static int x __attribute__((weak)); // expected-error {{weak declaration of 'x' must be public}} + diff --git a/test/Sema/bitfield-promote-int-16bit.c b/test/Sema/bitfield-promote-int-16bit.c new file mode 100644 index 000000000000..12d47205e87d --- /dev/null +++ b/test/Sema/bitfield-promote-int-16bit.c @@ -0,0 +1,25 @@ +// RUN: clang-cc -fsyntax-only -verify %s -triple pic16-unknown-unknown + +// Check that int-sized unsigned bit-fields promote to unsigned int +// on targets where sizeof(unsigned short) == sizeof(unsigned int) + +enum E { ec1, ec2, ec3 }; +struct S { + enum E e : 16; + unsigned short us : 16; + unsigned long ul1 : 8; + unsigned long ul2 : 16; +} s; + +__typeof(s.e + s.e) x_e; +unsigned x_e; + +__typeof(s.us + s.us) x_us; +unsigned x_us; + +__typeof(s.ul1 + s.ul1) x_ul1; +signed x_ul1; + +__typeof(s.ul2 + s.ul2) x_ul2; +unsigned x_ul2; + diff --git a/test/Sema/bitfield-promote.c b/test/Sema/bitfield-promote.c new file mode 100644 index 000000000000..066f5d78e715 --- /dev/null +++ b/test/Sema/bitfield-promote.c @@ -0,0 +1,34 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct {unsigned x : 2;} x; +__typeof__((x.x+=1)+1) y; +__typeof__(x.x<<1) y; +int y; + + +struct { int x : 8; } x1; +long long y1; +__typeof__(((long long)x1.x + 1)) y1; + + +// Check for extensions: variously sized unsigned bit-fields fitting +// into a signed int promote to signed int. +enum E { ec1, ec2, ec3 }; +struct S { + enum E e : 2; + unsigned short us : 4; + unsigned long long ul1 : 8; + unsigned long long ul2 : 50; +} s; + +__typeof(s.e + s.e) x_e; +int x_e; + +__typeof(s.us + s.us) x_us; +int x_us; + +__typeof(s.ul1 + s.ul1) x_ul1; +int x_ul1; + +__typeof(s.ul2 + s.ul2) x_ul2; +unsigned long long x_ul2; + diff --git a/test/Sema/bitfield.c b/test/Sema/bitfield.c index 655f74121a32..581af6d0c5ea 100644 --- a/test/Sema/bitfield.c +++ b/test/Sema/bitfield.c @@ -21,7 +21,7 @@ struct a { int g : (_Bool)1; // PR4017 - char : 10; // expected-error {{size of anonymous bitfield exceeds size of its type (8 bits)}} + char : 10; // expected-error {{size of anonymous bit-field exceeds size of its type (8 bits)}} unsigned : -2; // expected-error {{anonymous bit-field has negative width (-2)}} float : 12; // expected-error {{anonymous bit-field has non-integral type 'float'}} }; diff --git a/test/Sema/block-args.c b/test/Sema/block-args.c index 27bee77da6c6..3a58735f23a3 100644 --- a/test/Sema/block-args.c +++ b/test/Sema/block-args.c @@ -22,7 +22,7 @@ void test() { ^(int x, ...){return 5;}(arg, arg); // Explicit varargs, ok. } -int main(int argc) { +int main(int argc, char** argv) { ^(int argCount) { argCount = 3; }(argc); diff --git a/test/Sema/block-call.c b/test/Sema/block-call.c index c42b642337ca..893a8f61da8d 100644 --- a/test/Sema/block-call.c +++ b/test/Sema/block-call.c @@ -5,51 +5,47 @@ int (^IFP) (); int (^II) (int); int main() { int (*FPL) (int) = FP; // C doesn't consider this an error. - + // For Blocks, the ASTContext::typesAreBlockCompatible() makes sure this is an error. int (^PFR) (int) = IFP; // OK - PFR = II; // OK - - int (^IFP) () = PFR; // OK - + PFR = II; // OK - const int (^CIC) () = IFP; // expected-error {{incompatible block pointer types initializing 'int (^)()', expected 'int const (^)()'}} + int (^IFP) () = PFR; // OK - const int (^CICC) () = CIC; + const int (^CIC) () = IFP; // expected-error {{incompatible block pointer types initializing 'int (^)()', expected 'int const (^)()'}} - int * const (^IPCC) () = 0; + const int (^CICC) () = CIC; - int * const (^IPCC1) () = IPCC; + int * const (^IPCC) () = 0; - int * (^IPCC2) () = IPCC; // expected-error {{incompatible block pointer types initializing 'int *const (^)()', expected 'int *(^)()'}} + int * const (^IPCC1) () = IPCC; - int (^IPCC3) (const int) = PFR; + int * (^IPCC2) () = IPCC; // expected-error {{incompatible block pointer types initializing 'int *const (^)()', expected 'int *(^)()'}} + int (^IPCC3) (const int) = PFR; - int (^IPCC4) (int, char (^CArg) (double)); + int (^IPCC4) (int, char (^CArg) (double)); + int (^IPCC5) (int, char (^CArg) (double)) = IPCC4; - int (^IPCC5) (int, char (^CArg) (double)) = IPCC4; + int (^IPCC6) (int, char (^CArg) (float)) = IPCC4; // expected-error {{incompatible block pointer types initializing 'int (^)(int, char (^)(double))', expected 'int (^)(int, char (^)(float))'}} - int (^IPCC6) (int, char (^CArg) (float)) = IPCC4; // expected-error {{incompatible block pointer types initializing 'int (^)(int, char (^)(double))', expected 'int (^)(int, char (^)(float))'}} - - IPCC2 = 0; - IPCC2 = 1; // expected-error {{invalid conversion assigning integer 'int', expected block pointer 'int *(^)()'}} - int (^x)() = 0; - int (^y)() = 3; // expected-error {{invalid conversion initializing integer 'int', expected block pointer 'int (^)()'}} - int a = 1; - int (^z)() = a+4; // expected-error {{invalid conversion initializing integer 'int', expected block pointer 'int (^)()'}} + IPCC2 = 0; + IPCC2 = 1; // expected-error {{invalid conversion assigning integer 'int', expected block pointer 'int *(^)()'}} + int (^x)() = 0; + int (^y)() = 3; // expected-error {{invalid conversion initializing integer 'int', expected block pointer 'int (^)()'}} + int a = 1; + int (^z)() = a+4; // expected-error {{invalid conversion initializing integer 'int', expected block pointer 'int (^)()'}} } int blah() { - int (^IFP) (float); - char (^PCP)(double, double, char); + int (^IFP) (float); + char (^PCP)(double, double, char); - IFP(1.0); - IFP (1.0, 2.0); // expected-error {{too many arguments to block call}} + IFP(1.0); + IFP (1.0, 2.0); // expected-error {{too many arguments to block call}} - char ch = PCP(1.0, 2.0, 'a'); - return PCP(1.0, 2.0); // expected-error {{too few arguments to block}} + char ch = PCP(1.0, 2.0, 'a'); + return PCP(1.0, 2.0); // expected-error {{too few arguments to block}} } - diff --git a/test/Sema/block-literal.c b/test/Sema/block-literal.c index 19d476fc294f..9f5022dc6387 100644 --- a/test/Sema/block-literal.c +++ b/test/Sema/block-literal.c @@ -8,40 +8,40 @@ int printf(const char*, ...); typedef void (^T) (void); -void takeclosure(T); +void takeblock(T); int takeintint(int (^C)(int)) { return C(4); } T somefunction() { - if (^{ }) - nothing(); + if (^{ }) + nothing(); - noop = ^{}; + noop = ^{}; - noop = ^{printf("\nClosure\n"); }; + noop = ^{printf("\nClosure\n"); }; - I(^{ }); + I(^{ }); - return ^{printf("\nClosure\n"); }; + return ^{printf("\nClosure\n"); }; } void test2() { - int x = 4; + int x = 4; - takeclosure(^{ printf("%d\n", x); }); + takeblock(^{ printf("%d\n", x); }); while (1) { - takeclosure(^{ - break; // expected-error {{'break' statement not in loop or switch statement}} - continue; // expected-error {{'continue' statement not in loop statement}} - while(1) break; // ok - goto foo; // expected-error {{goto not allowed}} - }); + takeblock(^{ + break; // expected-error {{'break' statement not in loop or switch statement}} + continue; // expected-error {{'continue' statement not in loop statement}} + while(1) break; // ok + goto foo; // expected-error {{goto not allowed}} + }); break; - } + } -foo: - takeclosure(^{ x = 4; }); // expected-error {{variable is not assignable (missing __block type specifier)}} + foo: + takeblock(^{ x = 4; }); // expected-error {{variable is not assignable (missing __block type specifier)}} __block y = 7; // expected-warning {{type specifier missing, defaults to 'int'}} - takeclosure(^{ y = 8; }); + takeblock(^{ y = 8; }); } @@ -59,11 +59,11 @@ void myfunc(int (^block)(int)) {} void myfunc3(const int *x); void test5() { - int a; + int a; - myfunc(^(int abcd) { - myfunc3(&a); - return 1; + myfunc(^(int abcd) { + myfunc3(&a); + return 1; }); } @@ -86,39 +86,3 @@ typedef void (^void_block_t)(void); static const void_block_t myBlock = ^{ }; static const void_block_t myBlock2 = ^ void(void) { }; - -#if 0 -// Old syntax. FIXME: convert/test. -void test_byref() { - int i; - - X = ^{| g |}; // error {{use of undeclared identifier 'g'}} - - X = ^{| i,i,i | }; - - X = ^{|i| i = 0; }; - -} - -// TODO: global closures someday. -void *A = ^{}; -void *B = ^(int){ A = 0; }; - - -// Closures can not take return types at this point. -void test_retvals() { - // Explicit return value. - ^int{}; // error {{closure with explicit return type requires argument list}} - X = ^void(){}; - - // Optional specification of return type. - X = ^char{ return 'x'; }; // error {{closure with explicit return type requires argument list}} - - X = ^/*missing declspec*/ *() { return (void*)0; }; - X = ^void*() { return (void*)0; }; - - //X = ^char(short c){ if (c) return c; else return (int)4; }; - -} - -#endif diff --git a/test/Sema/block-misc.c b/test/Sema/block-misc.c index 294c295c5f8c..8661fd8a5227 100644 --- a/test/Sema/block-misc.c +++ b/test/Sema/block-misc.c @@ -4,37 +4,37 @@ void donotwarn(); int (^IFP) (); int (^II) (int); int test1() { - int (^PFR) (int) = 0; // OK - PFR = II; // OK + int (^PFR) (int) = 0; // OK + PFR = II; // OK - if (PFR == II) // OK + if (PFR == II) // OK donotwarn(); - if (PFR == IFP) // OK + if (PFR == IFP) // OK donotwarn(); if (PFR == (int (^) (int))IFP) // OK donotwarn(); - if (PFR == 0) // OK + if (PFR == 0) // OK donotwarn(); - if (PFR) // OK + if (PFR) // OK donotwarn(); - if (!PFR) // OK + if (!PFR) // OK donotwarn(); - return PFR != IFP; // OK + return PFR != IFP; // OK } int test2(double (^S)()) { double (^I)(int) = (void*) S; - (void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}} + (void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}} void *pv = I; - pv = S; + pv = S; I(1); @@ -44,7 +44,7 @@ int test2(double (^S)()) { int^ x; // expected-error {{block pointer to non-function type is invalid}} int^^ x1; // expected-error {{block pointer to non-function type is invalid}} expected-error {{block pointer to non-function type is invalid}} -int test3() { +void test3() { char *^ y; // expected-error {{block pointer to non-function type is invalid}} } @@ -114,7 +114,7 @@ void test11(int i) { void (^test12f)(void); void test12() { - test12f = ^test12f; // expected-error {{type name requires a specifier or qualifier}} expected-error {{expected expression}} + test12f = ^test12f; // expected-error {{type name requires a specifier or qualifier}} expected-error {{expected expression}} } // rdar://6808730 @@ -144,7 +144,7 @@ void foo(long (^comp)()) { void (^test15f)(void); void test15() { - foo(^{ return LESS; }); // expected-error {{incompatible block pointer types passing 'int (^)(void)', expected 'long (^)()'}} + foo(^{ return LESS; }); // expected-error {{incompatible block pointer types passing 'int (^)(void)', expected 'long (^)()'}} } __block int test16i; // expected-error {{__block attribute not allowed, only allowed on local variables}} @@ -185,3 +185,16 @@ void test18() { void (^const blockA)(void) = ^{ }; blockA = ^{ }; // expected-error {{read-only variable is not assignable}} } + +// rdar://7072507 +int test19() { + goto L0; // expected-error {{illegal goto into protected scope}} + + __block int x; // expected-note {{jump bypasses setup of __block variable}} +L0: + x = 0; + ^(){ ++x; }(); + return x; +} + + diff --git a/test/Sema/block-printf-attribute-1.c b/test/Sema/block-printf-attribute-1.c index ce30b8e855b7..4941ae7bc679 100644 --- a/test/Sema/block-printf-attribute-1.c +++ b/test/Sema/block-printf-attribute-1.c @@ -1,15 +1,12 @@ // RUN: clang-cc %s -fsyntax-only -verify -fblocks -int main() -{ - void (^b) (int arg, const char * format, ...) __attribute__ ((__format__ (__printf__, 1, 3))) = // expected-error {{format argument not a string type}} - ^ __attribute__ ((__format__ (__printf__, 1, 3))) (int arg, const char * format, ...) {}; // expected-error {{format argument not a string type}} +int main() { + void (^b) (int arg, const char * format, ...) __attribute__ ((__format__ (__printf__, 1, 3))) = // expected-error {{format argument not a string type}} + ^ __attribute__ ((__format__ (__printf__, 1, 3))) (int arg, const char * format, ...) {}; // expected-error {{format argument not a string type}} - void (^z) (int arg, const char * format, ...) __attribute__ ((__format__ (__printf__, 2, 3))) = ^ __attribute__ ((__format__ (__printf__, 2, 3))) (int arg, const char * format, ...) {}; - - // FIXME: argument type poking not yet supportted. - z(1, "%s", 1); /* { dg-warning "format \\'\%s\\' expects type \\'char \\*\\'\, but argument 3 has type \\'int\\'" } */ - z(1, "%s", "HELLO"); // OK + void (^z) (int arg, const char * format, ...) __attribute__ ((__format__ (__printf__, 2, 3))) = ^ __attribute__ ((__format__ (__printf__, 2, 3))) (int arg, const char * format, ...) {}; + // FIXME: argument type poking not yet supportted. + z(1, "%s", 1); /* { dg-warning "format \\'\%s\\' expects type \\'char \\*\\'\, but argument 3 has type \\'int\\'" } */ + z(1, "%s", "HELLO"); // OK } - diff --git a/test/Sema/block-return-1.c b/test/Sema/block-return-1.c new file mode 100644 index 000000000000..2da87351e4f5 --- /dev/null +++ b/test/Sema/block-return-1.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -fsyntax-only %s -verify -fblocks + +int j; +void foo() { + ^ (void) { if (j) return 1; }(); // expected-error {{control may reach end of non-void block}} +} diff --git a/test/Sema/block-return-2.c b/test/Sema/block-return-2.c new file mode 100644 index 000000000000..d389f4e4ffcc --- /dev/null +++ b/test/Sema/block-return-2.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -fsyntax-only %s -verify -fblocks + +void foo() { + ^ (void) __attribute__((noreturn)) { }(); // expected-error {{block declared 'noreturn' should not return}} +} diff --git a/test/Sema/block-return-3.c b/test/Sema/block-return-3.c new file mode 100644 index 000000000000..e7e9342e02f4 --- /dev/null +++ b/test/Sema/block-return-3.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -fsyntax-only %s -verify -fblocks + +void foo() { + ^ int (void) { }(); // expected-error {{control reaches end of non-void block}} +} diff --git a/test/Sema/block-return.c b/test/Sema/block-return.c index 87f4040be9d0..98a72731d672 100644 --- a/test/Sema/block-return.c +++ b/test/Sema/block-return.c @@ -31,7 +31,7 @@ CL foo() { return (float)1.0; else if (2) - return (double)2.0; + return (double)2.0; return 1; }; char *(^B)(void) = ^{ @@ -66,7 +66,7 @@ int foo3() { Boolean (*value_equal)(uintptr_t, uintptr_t) = 0; cb.isEqual = ^(const CFBasicHash *table, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key) { - return (Boolean)(uintptr_t)INVOKE_CALLBACK2(value_equal, (uintptr_t)stack_value_or_key1, (uintptr_t)stack_value_or_key2); + return (Boolean)(uintptr_t)INVOKE_CALLBACK2(value_equal, (uintptr_t)stack_value_or_key1, (uintptr_t)stack_value_or_key2); }; } @@ -91,6 +91,8 @@ bptr foo5(int j) { if (j) return ^{ ^{ i=0; }(); }; // expected-error {{returning block that lives on the local stack}} return ^{ i=0; }; // expected-error {{returning block that lives on the local stack}} + return (^{ i=0; }); // expected-error {{returning block that lives on the local stack}} + return (void*)(^{ i=0; }); // expected-error {{returning block that lives on the local stack}} } int (*funcptr3[5])(long); diff --git a/test/Sema/block-sentinel-attribute.c b/test/Sema/block-sentinel-attribute.c index a7d4df108ea7..5628a2c7801f 100644 --- a/test/Sema/block-sentinel-attribute.c +++ b/test/Sema/block-sentinel-attribute.c @@ -2,24 +2,23 @@ void (^e) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (1,1))); -int main() -{ - void (^bbad) (int arg, const char * format) __attribute__ ((__sentinel__)) ; // expected-warning {{sentinel' attribute only supported for variadic blocks}} - void (^b) (int arg, const char * format, ...) __attribute__ ((__sentinel__)) = // expected-note {{block has been explicitly marked sentinel here}} - ^ __attribute__ ((__sentinel__)) (int arg, const char * format, ...) {}; - void (^z) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (2))) = ^ __attribute__ ((__sentinel__ (2))) (int arg, const char * format, ...) {}; // expected-note {{block has been explicitly marked sentinel here}} +int main() { + void (^bbad) (int arg, const char * format) __attribute__ ((__sentinel__)) ; // expected-warning {{sentinel' attribute only supported for variadic blocks}} + void (^b) (int arg, const char * format, ...) __attribute__ ((__sentinel__)) = // expected-note {{block has been explicitly marked sentinel here}} + ^ __attribute__ ((__sentinel__)) (int arg, const char * format, ...) {}; + void (^z) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (2))) = ^ __attribute__ ((__sentinel__ (2))) (int arg, const char * format, ...) {}; // expected-note {{block has been explicitly marked sentinel here}} - void (^y) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (5))) = ^ __attribute__ ((__sentinel__ (5))) (int arg, const char * format, ...) {}; // expected-note {{block has been explicitly marked sentinel here}} + void (^y) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (5))) = ^ __attribute__ ((__sentinel__ (5))) (int arg, const char * format, ...) {}; // expected-note {{block has been explicitly marked sentinel here}} - b(1, "%s", (void*)0); // OK - b(1, "%s", 0); // expected-warning {{missing sentinel in block call}} - z(1, "%s",4 ,1,0); // expected-warning {{missing sentinel in block call}} - z(1, "%s", (void*)0, 1, 0); // OK + b(1, "%s", (void*)0); // OK + b(1, "%s", 0); // expected-warning {{missing sentinel in block call}} + z(1, "%s",4 ,1,0); // expected-warning {{missing sentinel in block call}} + z(1, "%s", (void*)0, 1, 0); // OK - y(1, "%s", 1,2,3,4,5,6,7); // expected-warning {{missing sentinel in block call}} + y(1, "%s", 1,2,3,4,5,6,7); // expected-warning {{missing sentinel in block call}} - y(1, "%s", (void*)0,3,4,5,6,7); // OK + y(1, "%s", (void*)0,3,4,5,6,7); // OK } diff --git a/test/Sema/builtin-prefetch.c b/test/Sema/builtin-prefetch.c index 6b39e75d5257..bf28277acb81 100644 --- a/test/Sema/builtin-prefetch.c +++ b/test/Sema/builtin-prefetch.c @@ -1,6 +1,6 @@ // RUN: clang-cc -fsyntax-only -verify %s -int foo() { +void foo() { int a; __builtin_prefetch(&a); __builtin_prefetch(&a, 1); diff --git a/test/Sema/builtin-unary-fp.c b/test/Sema/builtin-unary-fp.c new file mode 100644 index 000000000000..70c7a297fbe3 --- /dev/null +++ b/test/Sema/builtin-unary-fp.c @@ -0,0 +1,12 @@ +// RUN: clang-cc %s -fsyntax-only -verify -pedantic +void check(int); +void a() { + check(__builtin_isfinite(1.0f)); + check(__builtin_isinf(1.0)); + check(__builtin_isinf_sign(1.0L)); + check(__builtin_isnan(1.0f)); + check(__builtin_isnormal(1.0f)); + check(__builtin_isfinite(1)); // expected-error{{requires argument of floating point type}} + check(__builtin_isinf()); // expected-error{{too few arguments}} + check(__builtin_isnan(1,2)); // expected-error{{too many arguments}} +} diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c index 78b75624ea24..e133d626ee52 100644 --- a/test/Sema/builtins.c +++ b/test/Sema/builtins.c @@ -34,10 +34,40 @@ void test7() { // atomics. -unsigned char test9(short v) { +void test9(short v) { unsigned i, old; old = __sync_fetch_and_add(); // expected-error {{too few arguments to function call}} old = __sync_fetch_and_add(&old); // expected-error {{too few arguments to function call}} old = __sync_fetch_and_add((int**)0, 42i); // expected-warning {{imaginary constants are an extension}} } + + +// rdar://7236819 +void test10(void) __attribute__((noreturn)); + +void test10(void) { + __asm__("int3"); + __builtin_unreachable(); + + // No warning about falling off the end of a noreturn function. +} + +void test11(int X) { + switch (X) { + case __builtin_eh_return_data_regno(0): // constant foldable. + break; + } + + __builtin_eh_return_data_regno(X); // expected-error {{not an integer constant expression}} +} + +// PR5062 +void test12(void) __attribute__((__noreturn__)); +void test12(void) { + __builtin_trap(); // no warning because trap is noreturn. +} + +void test_unknown_builtin(int a, int b) { + __builtin_foo(a, b); // expected-error{{use of unknown builtin}} +} diff --git a/test/Sema/c89-2.c b/test/Sema/c89-2.c index 723bd7c18d88..50c5f4e5a840 100644 --- a/test/Sema/c89-2.c +++ b/test/Sema/c89-2.c @@ -1,7 +1,5 @@ -/* RUN: not clang-cc %s -std=c89 -pedantic-errors +/* RUN: clang-cc %s -std=c89 -pedantic-errors -verify */ -/* We can't put expected-warning lines on #if lines. */ - -#if 1LL /* expected-warning {{long long}} */ +#if 1LL /* expected-error {{long long}} */ #endif diff --git a/test/Sema/c89.c b/test/Sema/c89.c index e7585c31926c..fc50ebed6631 100644 --- a/test/Sema/c89.c +++ b/test/Sema/c89.c @@ -25,7 +25,7 @@ void test3(int i) { int A[i]; /* expected-warning {{variable length array}} */ } -int test4 = 0LL; /* expected-warning {{long long}} */ +int test4 = 0LL; /* expected-warning {{long long}} */ /* PR1999 */ void test5(register); @@ -36,7 +36,7 @@ int *__restrict; /* expected-error {{expected identifier}} */ /* Implicit int, always ok */ -test6() {} +test6() { return 0; } /* PR2012 */ test7; /* expected-warning {{declaration specifier missing, defaulting to 'int'}} */ diff --git a/test/Sema/compare.c b/test/Sema/compare.c index 51f77317385c..87131bb62183 100644 --- a/test/Sema/compare.c +++ b/test/Sema/compare.c @@ -3,11 +3,11 @@ int test(char *C) { // nothing here should warn. return C != ((void*)0); return C != (void*)0; - return C != 0; + return C != 0; + return C != 1; // expected-warning {{comparison between pointer and integer ('char *' and 'int')}} } -int equal(char *a, const char *b) -{ +int equal(char *a, const char *b) { return a == b; } @@ -16,16 +16,21 @@ int arrays(char (*a)[5], char(*b)[10], char(*c)[5]) { return a == b; // expected-warning {{comparison of distinct pointer types}} } -int pointers(int *a) -{ - return a > 0; // expected-warning {{ordered comparison between pointer and integer}} +int pointers(int *a) { + return a > 0; // expected-warning {{ordered comparison between pointer and zero ('int *' and 'int') is an extension}} + return a > 42; // expected-warning {{ordered comparison between pointer and integer ('int *' and 'int')}} return a > (void *)0; // expected-warning {{comparison of distinct pointer types}} } -int function_pointers(int (*a)(int), int (*b)(int)) -{ +int function_pointers(int (*a)(int), int (*b)(int), void (*c)(int)) { return a > b; // expected-warning {{ordered comparison of function pointers}} return function_pointers > function_pointers; // expected-warning {{ordered comparison of function pointers}} + return a > c; // expected-warning {{comparison of distinct pointer types}} return a == (void *) 0; - return a == (void *) 1; // expected-warning {{comparison of distinct pointer types}} + return a == (void *) 1; // expected-warning {{equality comparison between function pointer and void pointer}} +} + +int void_pointers(void* foo) { + return foo == (void*) 0; + return foo == (void*) 1; } diff --git a/test/Sema/complex-int.c b/test/Sema/complex-int.c index 5977b4d1e0cb..6c660899e8a1 100644 --- a/test/Sema/complex-int.c +++ b/test/Sema/complex-int.c @@ -44,9 +44,8 @@ TestPairs(7); TestPairs(8); // rdar://6097730 void test3(_Complex int *x) { *x = ~*x; -} +} void test4(_Complex float *x) { *x = ~*x; -} - +} diff --git a/test/Sema/conditional.c b/test/Sema/conditional.c index 1c7486a6133e..9f48c349c964 100644 --- a/test/Sema/conditional.c +++ b/test/Sema/conditional.c @@ -4,12 +4,10 @@ const char* test1 = 1 ? "i" : 1 == 1 ? "v" : "r"; void _efree(void *ptr); -int _php_stream_free1() -{ - return (1 ? free(0) : _efree(0)); // expected-error {{incompatible type returning 'void', expected 'int'}} +int _php_stream_free1() { + return (1 ? free(0) : _efree(0)); // expected-error {{incompatible type returning 'void', expected 'int'}} } -int _php_stream_free2() -{ - return (1 ? _efree(0) : free(0)); // expected-error {{incompatible type returning 'void', expected 'int'}} +int _php_stream_free2() { + return (1 ? _efree(0) : free(0)); // expected-error {{incompatible type returning 'void', expected 'int'}} } diff --git a/test/Sema/darwin-align-cast.c b/test/Sema/darwin-align-cast.c index 09808b5af2e8..fed898319157 100644 --- a/test/Sema/darwin-align-cast.c +++ b/test/Sema/darwin-align-cast.c @@ -8,10 +8,10 @@ struct cmsghdr {}; #if 0 This code below comes from the following system headers: -sys/socket.h:#define CMSG_SPACE(l) (__DARWIN_ALIGN(sizeof(struct +sys/socket.h:#define CMSG_SPACE(l) (__DARWIN_ALIGN(sizeof(struct cmsghdr)) + __DARWIN_ALIGN(l)) -i386/_param.h:#define __DARWIN_ALIGN(p) ((__darwin_size_t)((char *)(p) +i386/_param.h:#define __DARWIN_ALIGN(p) ((__darwin_size_t)((char *)(p) + __DARWIN_ALIGNBYTES) &~ __DARWIN_ALIGNBYTES) #endif @@ -19,5 +19,6 @@ ssize_t sendFileDescriptor(int fd, void *data, size_t nbytes, int sendfd) { union { char control[(((__darwin_size_t)((char *)(sizeof(struct cmsghdr)) + (sizeof(__darwin_size_t) - 1)) &~ (sizeof(__darwin_size_t) - 1)) + ((__darwin_size_t)((char *)(sizeof(int)) + (sizeof(__darwin_size_t) - 1)) &~ (sizeof(__darwin_size_t) - 1)))]; } control_un; + return 0; } diff --git a/test/Sema/decl-type-merging.c b/test/Sema/decl-type-merging.c index 1b789a142ade..1a8601298e9a 100644 --- a/test/Sema/decl-type-merging.c +++ b/test/Sema/decl-type-merging.c @@ -6,11 +6,11 @@ int testx[(sizeof(x) == sizeof(int) * 10) ? 1 : -1]; int (*a)(int (*x)[10], int (*y)[]); int (*a)(int (*x)[], int (*y)[5]); -int b() { -int x[10], y[5]; -a(&x, &y); -a(&y, &y); // expected-warning {{incompatible pointer}} -a(&x, &x); // expected-warning {{incompatible pointer}} +void b() { + int x[10], y[5]; + a(&x, &y); + a(&y, &y); // expected-warning {{incompatible pointer}} + a(&x, &x); // expected-warning {{incompatible pointer}} } diff --git a/test/Sema/enum.c b/test/Sema/enum.c index adb937551237..31649e0ae9ed 100644 --- a/test/Sema/enum.c +++ b/test/Sema/enum.c @@ -43,7 +43,7 @@ void test4() { ; (_Bool)ve2; // expected-error {{arithmetic or pointer type is required}} - for (; ;ve2) + for (; ;ve2) // expected-warning {{expression result unused}} ; (void)ve2; ve2; // expected-warning {{expression result unused}} diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c index 3fd1437da880..69a2320397fd 100644 --- a/test/Sema/exprs.c +++ b/test/Sema/exprs.c @@ -60,9 +60,9 @@ int test8(void) { struct f { int x : 4; float y[]; }; int test9(struct f *P) { int R; - R = __alignof(P->x); // expected-error {{invalid application of '__alignof' to bitfield}} + R = __alignof(P->x); // expected-error {{invalid application of '__alignof' to bit-field}} R = __alignof(P->y); // ok. - R = sizeof(P->x); // expected-error {{invalid application of 'sizeof' to bitfield}} + R = sizeof(P->x); // expected-error {{invalid application of 'sizeof' to bit-field}} return R; } @@ -94,15 +94,12 @@ void test13( P = ^(){}; // expected-error {{blocks support disabled - compile with -fblocks}} } - -// rdar://6326239 - Vector comparisons are not fully trusted yet, until the -// backend is known to work, just unconditionally reject them. void test14() { typedef long long __m64 __attribute__((__vector_size__(8))); typedef short __v4hi __attribute__((__vector_size__(8))); + // Ok. __v4hi a; - __m64 mask = (__m64)((__v4hi)a > // expected-error {{comparison of vector types ('__v4hi' and '__v4hi') not supported yet}} - (__v4hi)a); + __m64 mask = (__m64)((__v4hi)a > (__v4hi)a); } diff --git a/test/Sema/floating-point-compare.c b/test/Sema/floating-point-compare.c index 763a8f4b86b4..9888105518d9 100644 --- a/test/Sema/floating-point-compare.c +++ b/test/Sema/floating-point-compare.c @@ -13,11 +13,11 @@ int f3(float x) { } int f4(float x) { - return x == 0.0; // no-warning {{comparing}} + return x == 0.0; // no-warning {{comparing}} } int f5(float x) { - return x == __builtin_inf(); // no-warning + return x == __builtin_inf(); // no-warning } int f7(float x) { diff --git a/test/Sema/format-attr-pr4470.c b/test/Sema/format-attr-pr4470.c index cba3adf1d6de..c03c573b7274 100644 --- a/test/Sema/format-attr-pr4470.c +++ b/test/Sema/format-attr-pr4470.c @@ -1,6 +1,7 @@ // RUN: clang-cc -fsyntax-only -verify -Wformat=2 %s #include <stdio.h> +#include <stdarg.h> const char *foo(const char *format) __attribute__((format_arg(1))); diff --git a/test/Sema/format-attribute-printf0.c b/test/Sema/format-attribute-printf0.c new file mode 100644 index 000000000000..fa7eafd52fb8 --- /dev/null +++ b/test/Sema/format-attribute-printf0.c @@ -0,0 +1,26 @@ +//RUN: clang-cc -fsyntax-only -verify %s + +#include <stdarg.h> + +// same as format(printf(...))... +void a2(const char *a, ...) __attribute__((format(printf0, 1,2))); // no-error +void b2(const char *a, ...) __attribute__((format(printf0, 1,1))); // expected-error {{'format' attribute parameter 3 is out of bounds}} +void c2(const char *a, ...) __attribute__((format(printf0, 0,2))); // expected-error {{'format' attribute parameter 2 is out of bounds}} +void d2(const char *a, int c) __attribute__((format(printf0, 1,2))); // expected-error {{format attribute requires variadic function}} +void e2(char *str, int c, ...) __attribute__((format(printf0, 2,3))); // expected-error {{format argument not a string type}} + +// FreeBSD usage +#define __printf0like(fmt,va) __attribute__((__format__(__printf0__,fmt,va))) +void null(int i, const char *a, ...) __printf0like(2,0); // no-error +void null(int i, const char *a, ...) { + if (a) + (void)0/* vprintf(...) would go here */; +} + +void callnull(void){ + null(0, 0); // no error + null(0, (char*)0); // no error + null(0, (void*)0); // no error + null(0, (int*)0); // expected-warning {{incompatible pointer types}} +} + diff --git a/test/Sema/freemain.c b/test/Sema/freemain.c new file mode 100644 index 000000000000..a2364df259bf --- /dev/null +++ b/test/Sema/freemain.c @@ -0,0 +1,9 @@ +// RUN: clang-cc -fsyntax-only -verify -ffreestanding %s + +// Tests that -ffreestanding disables all special treatment of main(). + +void* allocate(long size); + +void* main(void* context, long size) { + if (context) return allocate(size); +} // expected-warning {{control may reach end of non-void function}} diff --git a/test/Sema/function-pointer-sentinel-attribute.c b/test/Sema/function-pointer-sentinel-attribute.c index 0de02fa5363c..6d3fb1718076 100644 --- a/test/Sema/function-pointer-sentinel-attribute.c +++ b/test/Sema/function-pointer-sentinel-attribute.c @@ -2,22 +2,19 @@ void (*e) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (1,1))); -int main() -{ - void (*b) (int arg, const char * format, ...) __attribute__ ((__sentinel__)); // expected-note {{function has been explicitly marked sentinel here}} - void (*z) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (2))); // expected-note {{function has been explicitly marked sentinel here}} +int main() { + void (*b) (int arg, const char * format, ...) __attribute__ ((__sentinel__)); // expected-note {{function has been explicitly marked sentinel here}} + void (*z) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (2))); // expected-note {{function has been explicitly marked sentinel here}} - void (*y) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (5))); // expected-note {{function has been explicitly marked sentinel here}} + void (*y) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (5))); // expected-note {{function has been explicitly marked sentinel here}} - b(1, "%s", (void*)0); // OK - b(1, "%s", 0); // expected-warning {{missing sentinel in function call}} - z(1, "%s",4 ,1,0); // expected-warning {{missing sentinel in function call}} - z(1, "%s", (void*)0, 1, 0); // OK + b(1, "%s", (void*)0); // OK + b(1, "%s", 0); // expected-warning {{missing sentinel in function call}} + z(1, "%s",4 ,1,0); // expected-warning {{missing sentinel in function call}} + z(1, "%s", (void*)0, 1, 0); // OK - y(1, "%s", 1,2,3,4,5,6,7); // expected-warning {{missing sentinel in function call}} - - y(1, "%s", (void*)0,3,4,5,6,7); // OK + y(1, "%s", 1,2,3,4,5,6,7); // expected-warning {{missing sentinel in function call}} + y(1, "%s", (void*)0,3,4,5,6,7); // OK } - diff --git a/test/Sema/function-sentinel-attr.c b/test/Sema/function-sentinel-attr.c index 66304796127f..b33b4a063ce2 100644 --- a/test/Sema/function-sentinel-attr.c +++ b/test/Sema/function-sentinel-attr.c @@ -18,7 +18,7 @@ int main () foo1(1, 0) ; // expected-warning {{missing sentinel in function call}} foo5(1, NULL, 2); // OK foo5(1,2,NULL, 1); // OK - foo5(1, NULL, 2, 1); // expected-warning {{missing sentinel in function call}} + foo5(1, NULL, 2, 1); // expected-warning {{missing sentinel in function call}} foo6(1,2,3,4,5,6,7); // expected-warning {{missing sentinel in function call}} foo6(1,NULL,3,4,5,6,7); // OK diff --git a/test/Sema/function.c b/test/Sema/function.c index c9d8630c47f6..e7a37f1a2fc1 100644 --- a/test/Sema/function.c +++ b/test/Sema/function.c @@ -87,3 +87,5 @@ unknown_type t19(int* P) { // expected-error {{unknown type name 'unknown_type P = P+1; // no warning. } +// missing ',' before '...' +void t20(int i...) { } // expected-error {{requires a comma}} diff --git a/test/Sema/heinous-extensions-on.c b/test/Sema/heinous-extensions-on.c index 480b1b41e906..a56f1f6f625c 100644 --- a/test/Sema/heinous-extensions-on.c +++ b/test/Sema/heinous-extensions-on.c @@ -1,10 +1,9 @@ // RUN: clang-cc %s -verify -fheinous-gnu-extensions -int foo() { - int a; - // PR3788 - asm("nop" : : "m"((int)(a))); // expected-warning {{cast in a inline asm context requiring an l-value}} - // PR3794 - asm("nop" : "=r"((unsigned)a)); // expected-warning {{cast in a inline asm context requiring an l-value}} +void foo() { + int a; + // PR3788 + asm("nop" : : "m"((int)(a))); // expected-warning {{cast in a inline asm context requiring an l-value}} + // PR3794 + asm("nop" : "=r"((unsigned)a)); // expected-warning {{cast in a inline asm context requiring an l-value}} } - diff --git a/test/Sema/implicit-builtin-redecl.c b/test/Sema/implicit-builtin-redecl.c index cd99b5455318..36513bafb050 100644 --- a/test/Sema/implicit-builtin-redecl.c +++ b/test/Sema/implicit-builtin-redecl.c @@ -12,3 +12,15 @@ void *calloc(int, int, int); // expected-warning{{incompatible redeclaration of void f1(void) { calloc(0, 0, 0); } + +void f2() { + int index = 1; +} + +static int index; + +int f3() { + return index << 2; +} + +typedef int rindex;
\ No newline at end of file diff --git a/test/Sema/implicit-int.c b/test/Sema/implicit-int.c index 04b27a8f0ea9..5190bdbf934b 100644 --- a/test/Sema/implicit-int.c +++ b/test/Sema/implicit-int.c @@ -1,6 +1,7 @@ // RUN: clang-cc -fsyntax-only %s -verify -pedantic foo() { // expected-warning {{type specifier missing, defaults to 'int'}} + return 0; } y; // expected-warning {{type specifier missing, defaults to 'int'}} @@ -11,19 +12,19 @@ void f((x)); // expected-warning {{type specifier missing, defaults to 'int'}} // PR3702 #define PAD(ms10) { \ - register i; \ + register i; \ } -#define ILPAD() PAD((NROW - tt.tt_row) * 10) /* 1 ms per char */ +#define ILPAD() PAD((NROW - tt.tt_row) * 10) /* 1 ms per char */ void h19_insline(n) // expected-warning {{parameter 'n' was not declared, defaulting to type 'int'}} { - ILPAD(); // expected-warning {{type specifier missing, defaults to 'int'}} + ILPAD(); // expected-warning {{type specifier missing, defaults to 'int'}} } struct foo { - __extension__ __attribute__((packed)) x : 4; // expected-warning {{type specifier missing, defaults to 'int'}} + __extension__ __attribute__((packed)) x : 4; }; diff --git a/test/Sema/incomplete-call.c b/test/Sema/incomplete-call.c index aedfe50bbfdd..15d97683c5a0 100644 --- a/test/Sema/incomplete-call.c +++ b/test/Sema/incomplete-call.c @@ -2,12 +2,12 @@ struct foo; // expected-note 3 {{forward declaration of 'struct foo'}} -struct foo a(); +struct foo a(); // expected-note {{'a' declared here}} void b(struct foo); void c(); void func() { - a(); // expected-error{{return type of called function ('struct foo') is incomplete}} + a(); // expected-error{{calling 'a' with incomplete return type 'struct foo'}} b(*(struct foo*)0); // expected-error{{argument type 'struct foo' is incomplete}} c(*(struct foo*)0); // expected-error{{argument type 'struct foo' is incomplete}} } diff --git a/test/Sema/incomplete-decl.c b/test/Sema/incomplete-decl.c index eb93e8e38031..6a6ba753f3fe 100644 --- a/test/Sema/incomplete-decl.c +++ b/test/Sema/incomplete-decl.c @@ -1,12 +1,13 @@ // RUN: clang-cc -fsyntax-only -verify %s -struct foo; // expected-note 4 {{forward declaration of 'struct foo'}} +struct foo; // expected-note 5 {{forward declaration of 'struct foo'}} void b; // expected-error {{variable has incomplete type 'void'}} struct foo f; // expected-error{{tentative definition has type 'struct foo' that is never completed}} static void c; // expected-error {{variable has incomplete type 'void'}} -static struct foo g; // expected-error {{variable has incomplete type 'struct foo'}} +static struct foo g; // expected-warning {{tentative definition of variable with internal linkage has incomplete non-array type 'struct foo'}} \ + expected-error{{tentative definition has type 'struct foo' that is never completed}} extern void d; extern struct foo e; diff --git a/test/Sema/pragma-pack-4.c b/test/Sema/pragma-pack-4.c new file mode 100644 index 000000000000..f6f107da742b --- /dev/null +++ b/test/Sema/pragma-pack-4.c @@ -0,0 +1,19 @@ +// RUN: clang-cc -triple i686-apple-darwin9 %s -fsyntax-only -verify && +// RUN: clang-cc -triple x86_64-apple-darwin9 %s -fsyntax-only -verify + +// rdar://problem/7095436 +#pragma pack(4) + +struct s0 { + long long a __attribute__((aligned(8))); + long long b __attribute__((aligned(8))); + unsigned int c __attribute__((aligned(8))); + int d[12]; +}; + +struct s1 { + int a[15]; + struct s0 b; +}; + +int arr0[((sizeof(struct s1) % 64) == 0) ? 1 : -1]; diff --git a/test/Sema/pragma-unused.c b/test/Sema/pragma-unused.c index fe8bf8608bc3..8b9498962646 100644 --- a/test/Sema/pragma-unused.c +++ b/test/Sema/pragma-unused.c @@ -16,7 +16,7 @@ void f2(void) { } void f3(void) { - #pragma unused(x) // expected-error{{use of undeclared identifier 'x'}} + #pragma unused(x) // expected-warning{{undeclared variable 'x' used as an argument for '#pragma unused'}} } void f4(void) { @@ -26,7 +26,7 @@ void f4(void) { int k; void f5(void) { - #pragma unused(k) // expected-warning{{only local variables can be arguments to '#pragma unused' - ignored}} + #pragma unused(k) // expected-warning{{only local variables can be arguments to '#pragma unused'}} } void f6(void) { @@ -36,3 +36,8 @@ void f6(void) { } } +void f7() { + int y; + #pragma unused(undeclared, undefined, y) // expected-warning{{undeclared variable 'undeclared' used as an argument for '#pragma unused'}} expected-warning{{undeclared variable 'undefined' used as an argument for '#pragma unused'}} +} + diff --git a/test/Sema/predefined-function.c b/test/Sema/predefined-function.c index e8ccb3636b8e..c8d17f0078e6 100644 --- a/test/Sema/predefined-function.c +++ b/test/Sema/predefined-function.c @@ -8,31 +8,30 @@ int eli(float b); // expected-note {{previous declaration is here}} int b(int c) {return 1;} int foo(); -int foo() -{ - int eli(int (int)); // expected-error {{conflicting types for 'eli'}} - eli(b); // expected-error{{incompatible type passing}} - return 0; +int foo() { + int eli(int (int)); // expected-error {{conflicting types for 'eli'}} + eli(b); // expected-error{{incompatible type passing}} + return 0; } int bar(); int bar(int i) // expected-note {{previous definition is here}} { - return 0; + return 0; } int bar() // expected-error {{redefinition of 'bar'}} { - return 0; + return 0; } int foobar(int); // note {{previous declaration is here}} int foobar() // error {{conflicting types for 'foobar'}} { - return 0; + return 0; } int wibble(); // expected-note {{previous declaration is here}} float wibble() // expected-error {{conflicting types for 'wibble'}} { - return 0.0f; + return 0.0f; } diff --git a/test/Sema/promote-int-16bit.c b/test/Sema/promote-int-16bit.c new file mode 100644 index 000000000000..fbd1215d90d2 --- /dev/null +++ b/test/Sema/promote-int-16bit.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -fsyntax-only -verify %s -triple pic16-unknown-unknown + +// Check that unsigned short promotes to unsigned int on targets where +// sizeof(unsigned short) == sizeof(unsigned int) +__typeof(1+(unsigned short)1) x; +unsigned x; diff --git a/test/Sema/redefinition.c b/test/Sema/redefinition.c index 26c90c8e6d4f..9339bb935f6c 100644 --- a/test/Sema/redefinition.c +++ b/test/Sema/redefinition.c @@ -1,7 +1,7 @@ // RUN: clang-cc %s -fsyntax-only -verify -int f(int a) { } // expected-note {{previous definition is here}} +int f(int a) { return 0; } // expected-note {{previous definition is here}} int f(int); -int f(int a) { } // expected-error {{redefinition of 'f'}} +int f(int a) { return 0; } // expected-error {{redefinition of 'f'}} // <rdar://problem/6097326> int foo(x) { diff --git a/test/Sema/return-noreturn.c b/test/Sema/return-noreturn.c new file mode 100644 index 000000000000..e2452f407f4f --- /dev/null +++ b/test/Sema/return-noreturn.c @@ -0,0 +1,29 @@ +// RUN: clang-cc %s -fsyntax-only -verify -fblocks -Wmissing-noreturn + +int j; +void test1() { // expected-warning {{function could be attribute 'noreturn'}} + ^ (void) { while (1) { } }(); // expected-warning {{block could be attribute 'noreturn'}} + ^ (void) { if (j) while (1) { } }(); + while (1) { } +} + +void test2() { + if (j) while (1) { } +} + +__attribute__((__noreturn__)) +void test2_positive() { + if (j) while (1) { } +} // expected-warning{{function declared 'noreturn' should not return}} + + +// This test case illustrates that we don't warn about the missing return +// because the function is marked noreturn and there is an infinite loop. +extern int foo_test_3(); +__attribute__((__noreturn__)) void* test3(int arg) { + while (1) foo_test_3(); +} + +__attribute__((__noreturn__)) void* test3_positive(int arg) { + while (0) foo_test_3(); +} // expected-warning{{function declared 'noreturn' should not return}} diff --git a/test/Sema/return.c b/test/Sema/return.c index d96cede68a61..64def306ebc8 100644 --- a/test/Sema/return.c +++ b/test/Sema/return.c @@ -1,4 +1,4 @@ -// RUN: clang-cc %s -fsyntax-only -verify +// RUN: clang-cc %s -fsyntax-only -verify -fblocks // clang emits the following warning by default. // With GCC, -pedantic, -Wreturn-type or -Wall are required to produce the @@ -10,3 +10,211 @@ int t14() { void t15() { return 1; // expected-warning {{void function 't15' should not return a value}} } + +int unknown(); + +void test0() { +} + +int test1() { +} // expected-warning {{control reaches end of non-void function}} + +int test2() { + a: goto a; +} + +int test3() { + goto a; + a: ; +} // expected-warning {{control reaches end of non-void function}} + + +void halt() { + a: goto a; +} + +void halt2() __attribute__((noreturn)); + +int test4() { + halt2(); +} + +int test5() { + halt2(), (void)1; +} + +int test6() { + 1, halt2(); +} + +int j; +int unknown_nohalt() { + return j; +} + +int test7() { + unknown(); +} // expected-warning {{control reaches end of non-void function}} + +int test8() { + (void)(1 + unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int halt3() __attribute__((noreturn)); + +int test9() { + (void)(halt3() + unknown()); +} + +int test10() { + (void)(unknown() || halt3()); +} // expected-warning {{control may reach end of non-void function}} + +int test11() { + (void)(unknown() && halt3()); +} // expected-warning {{control may reach end of non-void function}} + +int test12() { + (void)(halt3() || unknown()); +} + +int test13() { + (void)(halt3() && unknown()); +} + +int test14() { + (void)(1 || unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int test15() { + (void)(0 || unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int test16() { + (void)(0 && unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int test17() { + (void)(1 && unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int test18() { + (void)(unknown_nohalt() && halt3()); +} // expected-warning {{control may reach end of non-void function}} + +int test19() { + (void)(unknown_nohalt() && unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int test20() { + int i; + if (i) + return 0; + else if (0) + return 2; +} // expected-warning {{control may reach end of non-void function}} + +int test21() { + int i; + if (i) + return 0; + else if (1) + return 2; +} + +int test22() { + int i; + switch (i) default: ; +} // expected-warning {{control reaches end of non-void function}} + +int test23() { + int i; + switch (i) { + case 0: + return 0; + case 2: + return 2; + } +} // expected-warning {{control may reach end of non-void function}} + +int test24() { + int i; + switch (i) { + case 0: + return 0; + case 2: + return 2; + default: + return -1; + } +} + +int test25() { + 1 ? halt3() : unknown(); +} + +int test26() { + 0 ? halt3() : unknown(); +} // expected-warning {{control reaches end of non-void function}} + +int j; +void (*fptr)() __attribute__((noreturn)); +int test27() { + switch (j) { + case 1: + do { } while (1); + break; + case 2: + for (;;) ; + break; + case 3: + for (;1;) ; + for (;0;) { + goto done; + } + return 1; + case 4: + while (0) { goto done; } + return 1; + case 5: + while (1) { return 1; } + break; + case 6: + fptr(); + break; + default: + return 1; + } + done: ; +} + +// PR4624 +void test28() __attribute__((noreturn)); +void test28(x) { while (1) { } } + +void exit(int); +int test29() { + exit(1); +} + +#include <setjmp.h> +jmp_buf test30_j; +int test30() { + if (j) + longjmp(test30_j, 1); + else + _longjmp(test30_j, 1); +} + +typedef void test31_t(int status); +void test31(test31_t *callback __attribute__((noreturn))); + +void test32() { + ^ (void) { while (1) { } }(); + ^ (void) { if (j) while (1) { } }(); + while (1) { } +} + +void test33() { + if (j) while (1) { } +} diff --git a/test/Sema/shift.c b/test/Sema/shift.c index 5acbe12ac33e..2516d1b86107 100644 --- a/test/Sema/shift.c +++ b/test/Sema/shift.c @@ -1,6 +1,40 @@ -// RUN: clang-cc -fsyntax-only %s +// RUN: clang-cc -Wall -fsyntax-only -verify %s + +#include <limits.h> + +enum { + X = 1 << 0, + Y = 1 << 1, + Z = 1 << 2 +}; void test() { char c; - c <<= 14; + + c = 0 << 0; + c = 0 << 1; + c = 1 << 0; + c = 1 << -0; + c = 1 >> -0; + c = 1 << -1; // expected-warning {{shift count is negative}} + c = 1 >> -1; // expected-warning {{shift count is negative}} + c = 1 << c; + c <<= 0; + c >>= 0; + c <<= 1; + c >>= 1; + c <<= -1; // expected-warning {{shift count is negative}} + c >>= -1; // expected-warning {{shift count is negative}} + c <<= 999999; // expected-warning {{shift count >= width of type}} + c >>= 999999; // expected-warning {{shift count >= width of type}} + c <<= CHAR_BIT; // expected-warning {{shift count >= width of type}} + c >>= CHAR_BIT; // expected-warning {{shift count >= width of type}} + c <<= CHAR_BIT+1; // expected-warning {{shift count >= width of type}} + c >>= CHAR_BIT+1; // expected-warning {{shift count >= width of type}} + (void)((long)c << CHAR_BIT); } + +#define a 0 +#define ashift 8 +enum { b = (a << ashift) }; + diff --git a/test/Sema/static-init.c b/test/Sema/static-init.c index cd495568ca3f..510f3ab099af 100644 --- a/test/Sema/static-init.c +++ b/test/Sema/static-init.c @@ -11,11 +11,11 @@ _Bool t = &t; union bar { - int i; + int i; }; struct foo { - unsigned ptr; + unsigned ptr; }; union bar u[1]; diff --git a/test/Sema/struct-decl.c b/test/Sema/struct-decl.c index 2c0945f9f86b..a5a299bf09b2 100644 --- a/test/Sema/struct-decl.c +++ b/test/Sema/struct-decl.c @@ -1,26 +1,26 @@ // RUN: clang-cc -fsyntax-only -verify %s // PR3459 struct bar { - char n[1]; + char n[1]; }; struct foo { - char name[(int)&((struct bar *)0)->n]; - char name2[(int)&((struct bar *)0)->n - 1]; //expected-error{{array size is negative}} + char name[(int)&((struct bar *)0)->n]; + char name2[(int)&((struct bar *)0)->n - 1]; //expected-error{{array size is negative}} }; // PR3430 struct s { - struct st { - int v; - } *ts; + struct st { + int v; + } *ts; }; struct st; int foo() { - struct st *f; - return f->v + f[0].v; + struct st *f; + return f->v + f[0].v; } // PR3642, PR3671 @@ -29,8 +29,8 @@ struct pppoe_tag { char tag_data[]; }; struct datatag { - struct pppoe_tag hdr; //expected-warning{{field 'hdr' with variable sized type 'struct pppoe_tag' not at the end of a struct or class is a GNU extension}} - char data; + struct pppoe_tag hdr; //expected-warning{{field 'hdr' with variable sized type 'struct pppoe_tag' not at the end of a struct or class is a GNU extension}} + char data; }; diff --git a/test/Sema/tentative-decls.c b/test/Sema/tentative-decls.c index e3c893c77718..c94af1160b89 100644 --- a/test/Sema/tentative-decls.c +++ b/test/Sema/tentative-decls.c @@ -2,7 +2,7 @@ // PR3310 struct a x1; // expected-note 2{{forward declaration of 'struct a'}} -static struct a x2; // expected-error{{variable has incomplete type 'struct a'}} +static struct a x2; // expected-warning{{tentative definition of variable with internal linkage has incomplete non-array type 'struct a'}} struct a x3[10]; // expected-error{{array has incomplete element type 'struct a'}} struct a {int x;}; static struct a x2_okay; diff --git a/test/Sema/transparent-union-pointer.c b/test/Sema/transparent-union-pointer.c index ea761f17e7d6..a58bd42f821f 100644 --- a/test/Sema/transparent-union-pointer.c +++ b/test/Sema/transparent-union-pointer.c @@ -1,14 +1,14 @@ // RUN: clang-cc %s -fsyntax-only -verify typedef union { - union wait *__uptr; - int *__iptr; + union wait *__uptr; + int *__iptr; } __WAIT_STATUS __attribute__ ((__transparent_union__)); extern int wait (__WAIT_STATUS __stat_loc); void fastcgi_cleanup() { - int status = 0; - wait(&status); + int status = 0; + wait(&status); } diff --git a/test/Sema/type-spec-struct-union.c b/test/Sema/type-spec-struct-union.c index 2b68b7877318..003efb14620b 100644 --- a/test/Sema/type-spec-struct-union.c +++ b/test/Sema/type-spec-struct-union.c @@ -57,7 +57,7 @@ struct bar_baz { } mode; int nowrap; }; -int +void wizbiz_quxPoof(z) z_foop z; { diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c index 9c231e960a2a..acf488706f7e 100644 --- a/test/Sema/unused-expr.c +++ b/test/Sema/unused-expr.c @@ -25,7 +25,7 @@ void bar(volatile int *VP, int *P, int A, __real__ VC; // We know this can't change errno because of -fno-math-errno. - sqrt(A); // expected-warning {{expression result unused}} + sqrt(A); // expected-warning {{ignoring return value of function declared with const attribute}} } extern void t1(); @@ -43,4 +43,56 @@ void nowarn(unsigned char* a, unsigned char* b) { unsigned char c = 1; *a |= c, *b += c; + + + // PR4633 + int y, x; + ((void)0), y = x; +} + +void t4(int a) { + int b = 0; + + if (a) + b == 1; // expected-warning{{expression result unused}} + else + b == 2; // expected-warning{{expression result unused}} + + while (1) + b == 3; // expected-warning{{expression result unused}} + + do + b == 4; // expected-warning{{expression result unused}} + while (1); + + for (;;) + b == 5; // expected-warning{{expression result unused}} + + for (b == 1;;) {} // expected-warning{{expression result unused}} + for (;b == 1;) {} + for (;;b == 1) {} // expected-warning{{expression result unused}} } + +// rdar://7186119 +int t5f(void) __attribute__((warn_unused_result)); +void t5() { + t5f(); // expected-warning {{ignoring return value of function declared with warn_unused_result}} +} + + +int fn1() __attribute__ ((warn_unused_result)); +int fn2() __attribute__ ((pure)); +int fn3() __attribute__ ((const)); +// rdar://6587766 +int t6() { + if (fn1() < 0 || fn2(2,1) < 0 || fn3(2) < 0) // no warnings + return -1; + + fn1(); // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}} + fn2(92, 21); // expected-warning {{ignoring return value of function declared with pure attribute}} + fn3(42); // expected-warning {{ignoring return value of function declared with const attribute}} + return 0; +} + +int t7 __attribute__ ((warn_unused_result)); // expected-warning {{warning: 'warn_unused_result' attribute only applies to function types}} + diff --git a/test/Sema/va_arg_x86_64.c b/test/Sema/va_arg_x86_64.c index 680abb714b91..61ac97b7d451 100644 --- a/test/Sema/va_arg_x86_64.c +++ b/test/Sema/va_arg_x86_64.c @@ -8,9 +8,8 @@ char* foo(char *fmt, __builtin_va_list ap) // PR2692 typedef __builtin_va_list va_list; -static char *f (char * (*g) (char **, int), char **p, ...) { - char *s; - va_list v; - s = g (p, __builtin_va_arg(v, int)); +static void f (char * (*g) (char **, int), char **p, ...) { + char *s; + va_list v; + s = g (p, __builtin_va_arg(v, int)); } - diff --git a/test/Sema/vector-cast.c b/test/Sema/vector-cast.c index 9460cac6d187..8c607aad073e 100644 --- a/test/Sema/vector-cast.c +++ b/test/Sema/vector-cast.c @@ -20,7 +20,7 @@ void f() type 't1' and scalar type 'char *'}} v1 = (t1)(long long)10; v1 = (t1)(short)10; // -expected-error {{invalid conversion between vector \ -type 't1' and integer type 'int' of different size}} +type 't1' and integer type 'short' of different size}} long long r1 = (long long)v1; short r2 = (short)v1; // -expected-error {{invalid conversion between vector \ diff --git a/test/Sema/warn-char-subscripts.c b/test/Sema/warn-char-subscripts.c new file mode 100644 index 000000000000..c6fd78cc1f74 --- /dev/null +++ b/test/Sema/warn-char-subscripts.c @@ -0,0 +1,64 @@ +// RUN: clang-cc -Wchar-subscripts -fsyntax-only -verify %s + +void t1() { + int array[1] = { 0 }; + char subscript = 0; + int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}} +} + +void t2() { + int array[1] = { 0 }; + char subscript = 0; + int val = subscript[array]; // expected-warning{{array subscript is of type 'char'}} +} + +void t3() { + int *array = 0; + char subscript = 0; + int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}} +} + +void t4() { + int *array = 0; + char subscript = 0; + int val = subscript[array]; // expected-warning{{array subscript is of type 'char'}} +} + +char returnsChar(); +void t5() { + int *array = 0; + int val = array[returnsChar()]; // expected-warning{{array subscript is of type 'char'}} +} + +void t6() { + int array[1] = { 0 }; + signed char subscript = 0; + int val = array[subscript]; // no warning for explicit signed char +} + +void t7() { + int array[1] = { 0 }; + unsigned char subscript = 0; + int val = array[subscript]; // no warning for unsigned char +} + +typedef char CharTy; +void t8() { + int array[1] = { 0 }; + CharTy subscript = 0; + int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}} +} + +typedef signed char SignedCharTy; +void t9() { + int array[1] = { 0 }; + SignedCharTy subscript = 0; + int val = array[subscript]; // no warning for explicit signed char +} + +typedef unsigned char UnsignedCharTy; +void t10() { + int array[1] = { 0 }; + UnsignedCharTy subscript = 0; + int val = array[subscript]; // no warning for unsigned char +} diff --git a/test/Sema/warn-unused-variables.c b/test/Sema/warn-unused-variables.c new file mode 100644 index 000000000000..fd225436be82 --- /dev/null +++ b/test/Sema/warn-unused-variables.c @@ -0,0 +1,19 @@ +// RUN: clang-cc -fsyntax-only -Wunused-variable -verify %s + +struct s0 { + unsigned int i; +}; + +int proto(int a, int b); + +void f0(void) { + int a __attribute__((unused)), + b; // expected-warning{{unused}} + return; +} + +void f1(void) { + int i; + (void)sizeof(i); + return; +} diff --git a/test/Sema/x86-intrinsics-headers.c b/test/Sema/x86-intrinsics-headers.c new file mode 100644 index 000000000000..dd7dd5caf017 --- /dev/null +++ b/test/Sema/x86-intrinsics-headers.c @@ -0,0 +1,24 @@ +// RUN: clang -fsyntax-only %s && +// RUN: clang -fsyntax-only -fno-lax-vector-conversions %s && +// RUN: clang -fsyntax-only -x c++ %s + +#if defined(i386) || defined(__x86_64__) + +# if defined(__MMX__) +#include <emmintrin.h> +#include <mm_malloc.h> +# endif + +# if defined(__SSE__) +#include <xmmintrin.h> +# endif + +# if defined(__SSE3__) +#include <pmmintrin.h> +# endif + +# if defined(__SSSE3__) +#include <tmmintrin.h> +# endif + +#endif diff --git a/test/SemaCXX/PR5086-ambig-resolution-enum.cpp b/test/SemaCXX/PR5086-ambig-resolution-enum.cpp new file mode 100644 index 000000000000..838bc6f3c716 --- /dev/null +++ b/test/SemaCXX/PR5086-ambig-resolution-enum.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +class C { +public: + enum E { e1=0 }; + const char * fun1(int , enum E) const; + int fun1(unsigned, const char *) const; +}; + +void foo(const C& rc) { + enum {BUFLEN = 128 }; + const char *p = rc.fun1(BUFLEN - 2, C::e1); +} diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp index dc764da5322b..e14304a26fe3 100644 --- a/test/SemaCXX/abstract.cpp +++ b/test/SemaCXX/abstract.cpp @@ -9,7 +9,7 @@ #endif class C { - virtual void f() = 0; // expected-note {{pure virtual function 'f'}} + virtual void f() = 0; // expected-note {{pure virtual function 'f'}} }; static_assert(__is_abstract(C), "C has a pure virtual function"); @@ -20,7 +20,7 @@ class D : C { static_assert(__is_abstract(D), "D inherits from an abstract class"); class E : D { - virtual void f(); + virtual void f(); }; static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f"); @@ -38,8 +38,8 @@ struct S { void t3(const C&); void f() { - C(); // expected-error {{allocation of an object of abstract type 'C'}} - t3(C()); // expected-error {{allocation of an object of abstract type 'C'}} + C(); // expected-error {{allocation of an object of abstract type 'C'}} + t3(C()); // expected-error {{allocation of an object of abstract type 'C'}} } C e1[2]; // expected-error {{variable type 'C' is an abstract class}} @@ -54,17 +54,17 @@ typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract c void t6(Func); class F { - F a() { } // expected-error {{return type 'F' is an abstract class}} + F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}} - class D { - void f(F c); // expected-error {{parameter type 'F' is an abstract class}} - }; + class D { + void f(F c); // expected-error {{parameter type 'F' is an abstract class}} + }; - union U { - void u(F c); // expected-error {{parameter type 'F' is an abstract class}} - }; + union U { + void u(F c); // expected-error {{parameter type 'F' is an abstract class}} + }; - virtual void f() = 0; // expected-note {{pure virtual function 'f'}} + virtual void f() = 0; // expected-note {{pure virtual function 'f'}} }; class Abstract; @@ -72,50 +72,47 @@ class Abstract; void t7(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}} void t8() { - void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}} + void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}} } namespace N { - void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}} +void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}} } class Abstract { - virtual void f() = 0; // expected-note {{pure virtual function 'f'}} + virtual void f() = 0; // expected-note {{pure virtual function 'f'}} }; // <rdar://problem/6854087> class foo { public: - virtual foo *getFoo() = 0; + virtual foo *getFoo() = 0; }; class bar : public foo { public: - virtual bar *getFoo(); + virtual bar *getFoo(); }; bar x; // <rdar://problem/6902298> -class A -{ +class A { public: - virtual void release() = 0; - virtual void release(int count) = 0; - virtual void retain() = 0; + virtual void release() = 0; + virtual void release(int count) = 0; + virtual void retain() = 0; }; -class B : public A -{ +class B : public A { public: - virtual void release(); - virtual void release(int count); - virtual void retain(); + virtual void release(); + virtual void release(int count); + virtual void retain(); }; -void foo(void) -{ - B b; +void foo(void) { + B b; } struct K { diff --git a/test/SemaCXX/access-control-check.cpp b/test/SemaCXX/access-control-check.cpp new file mode 100644 index 000000000000..fb124a932a12 --- /dev/null +++ b/test/SemaCXX/access-control-check.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -fsyntax-only -faccess-control -verify %s + +class M { + int iM; +}; + +class P { + int iP; + int PPR(); +}; + +class N : M,P { + N() {} + // FIXME. No access violation is reported in method call or member access. + int PR() { return iP + PPR(); } +}; diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp index 9c9f0e19ef3c..80ea02bafd41 100644 --- a/test/SemaCXX/addr-of-overloaded-function.cpp +++ b/test/SemaCXX/addr-of-overloaded-function.cpp @@ -23,7 +23,34 @@ int g1(char); int g2(int); int g2(double); +template<typename T> T g3(T); +int g3(int); +int g3(char); + void g_test() { g(g1); g(g2); // expected-error{{call to 'g' is ambiguous; candidates are:}} + g(g3); } + +template<typename T> T h1(T); +template<typename R, typename A1> R h1(A1); +int h1(char); + +void ha(int (*fp)(int)); +void hb(int (*fp)(double)); + +void h_test() { + ha(h1); + hb(h1); +} + +struct A { }; +void f(void (*)(A *)); + +struct B +{ + void g() { f(d); } + void d(void *); + static void d(A *); +}; diff --git a/test/SemaCXX/ambig-user-defined-conversions.cpp b/test/SemaCXX/ambig-user-defined-conversions.cpp new file mode 100644 index 000000000000..94598f0e8ef2 --- /dev/null +++ b/test/SemaCXX/ambig-user-defined-conversions.cpp @@ -0,0 +1,52 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// Test1 +struct BASE { + operator int &(); // expected-note {{candidate function}} +}; +struct BASE1 { + operator int &(); // expected-note {{candidate function}} +}; + +struct B : public BASE, BASE1 { + +}; + +extern B f(); + +B b1; +void func(const int ci, const char cc); // expected-note {{candidate function}} +void func(const char ci, const B b); // expected-note {{candidate function}} +void func(const B b, const int ci); // expected-note {{candidate function}} + +const int Test1() { + func(b1, f()); // expected-error {{call to 'func' is ambiguous}} + return f(); // expected-error {{conversion from 'struct B' to 'int const' is ambiguous}} +} + + +// Test2 +struct E; +struct A { + A (E&); +}; + +struct E { + operator A (); +}; + +struct C { + C (E&); +}; + +void f1(A); // expected-note {{candidate function}} +void f1(C); // expected-note {{candidate function}} + +void Test2() +{ + E b; + f1(b); // expected-error {{call to 'f1' is ambiguous}} + // ambiguous because b -> C via constructor and + // b → A via constructor or conversion function. +} + diff --git a/test/SemaCXX/ambiguous-builtin-unary-operator.cpp b/test/SemaCXX/ambiguous-builtin-unary-operator.cpp new file mode 100644 index 000000000000..042546af6902 --- /dev/null +++ b/test/SemaCXX/ambiguous-builtin-unary-operator.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +struct A { + operator int&(); +}; + +struct B { + operator long&(); +}; + +struct C : B, A { }; + +void test(C c) { + ++c; // expected-error {{use of overloaded operator '++' is ambiguous}}\ + // expected-note 4 {{built-in candidate operator ++ (}} +} + + diff --git a/test/SemaCXX/arrow-operator.cpp b/test/SemaCXX/arrow-operator.cpp new file mode 100644 index 000000000000..9c46e96afc0b --- /dev/null +++ b/test/SemaCXX/arrow-operator.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct T { + void f(); +}; + +struct A { + T* operator->(); // expected-note{{candidate function}} +}; + +struct B { + T* operator->(); // expected-note{{candidate function}} +}; + +struct C : A, B { +}; + +struct D : A { }; + +void f(C &c, D& d) { + c->f(); // expected-error{{use of overloaded operator '->' is ambiguous}} + d->f(); +}
\ No newline at end of file diff --git a/test/SemaCXX/attr-after-definition.cpp b/test/SemaCXX/attr-after-definition.cpp new file mode 100644 index 000000000000..2ef5acfbc0f1 --- /dev/null +++ b/test/SemaCXX/attr-after-definition.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct X { }; +struct Y { }; + +bool f0(X) { return true; } // expected-note{{definition}} +bool f1(X) { return true; } + +__attribute__ ((__visibility__("hidden"))) bool f0(X); // expected-warning{{attribute}} +__attribute__ ((__visibility__("hidden"))) bool f1(Y); diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp new file mode 100644 index 000000000000..54f8b5b57fcd --- /dev/null +++ b/test/SemaCXX/attr-deprecated.cpp @@ -0,0 +1,66 @@ +// RUN: clang-cc %s -verify -fsyntax-only +class A { + void f() __attribute__((deprecated)); + void g(A* a); + void h(A* a) __attribute__((deprecated)); + + int b __attribute__((deprecated)); +}; + +void A::g(A* a) +{ + f(); // expected-warning{{'f' is deprecated}} + a->f(); // expected-warning{{'f' is deprecated}} + + (void)b; // expected-warning{{'b' is deprecated}} + (void)a->b; // expected-warning{{'b' is deprecated}} +} + +void A::h(A* a) +{ + f(); + a->f(); + + (void)b; + (void)a->b; +} + +struct B { + virtual void f() __attribute__((deprecated)); + void g(); +}; + +void B::g() { + f(); + B::f(); // expected-warning{{'f' is deprecated}} +} + +struct C : B { + virtual void f(); + void g(); +}; + +void C::g() { + f(); + C::f(); + B::f(); // expected-warning{{'f' is deprecated}} +} + +void f(B* b, C *c) { + b->f(); + b->B::f(); // expected-warning{{'f' is deprecated}} + + c->f(); + c->C::f(); + c->B::f(); // expected-warning{{'f' is deprecated}} +} + +struct D { + virtual void f() __attribute__((deprecated)); +}; + +void D::f() { } + +void f(D* d) { + d->f(); +} diff --git a/test/SemaCXX/attr-format.cpp b/test/SemaCXX/attr-format.cpp new file mode 100644 index 000000000000..369099a84800 --- /dev/null +++ b/test/SemaCXX/attr-format.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct S { + static void f(const char*, ...) __attribute__((format(printf, 1, 2))); + + // GCC has a hidden 'this' argument in member functions which is why + // the format argument is argument 2 here. + void g(const char*, ...) __attribute__((format(printf, 2, 3))); +}; diff --git a/test/SemaCXX/auto-cxx0x.cpp b/test/SemaCXX/auto-cxx0x.cpp index 33156ef23d2e..aa92bbe4f1f1 100644 --- a/test/SemaCXX/auto-cxx0x.cpp +++ b/test/SemaCXX/auto-cxx0x.cpp @@ -1,5 +1,5 @@ // RUN: clang-cc -fsyntax-only -verify %s -std=c++0x void f() { - auto int a; // expected-error{{cannot combine with previous 'auto' declaration specifier}} + auto int a; // expected-error{{cannot combine with previous 'auto' declaration specifier}} // expected-error{{declaration of variable 'a' with type 'auto' requires an initializer}} int auto b; // expected-error{{cannot combine with previous 'int' declaration specifier}} } diff --git a/test/SemaCXX/builtin-ptrtomember-ambig.cpp b/test/SemaCXX/builtin-ptrtomember-ambig.cpp new file mode 100644 index 000000000000..7e20af35394b --- /dev/null +++ b/test/SemaCXX/builtin-ptrtomember-ambig.cpp @@ -0,0 +1,24 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +struct A {}; + +struct R { + operator const A*(); +}; + + +struct B : R { + operator A*(); +}; + +struct C : B { + +}; + + +void foo(C c, int A::* pmf) { + // FIXME. Why so many built-in candidates? + int i = c->*pmf; // expected-error {{use of overloaded operator '->*' is ambiguous}} \ + // expected-note 40 {{built-in candidate operator ->* ('struct A}} +} + diff --git a/test/SemaCXX/builtin-ptrtomember-overload-1.cpp b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp new file mode 100644 index 000000000000..27ca6dc77897 --- /dev/null +++ b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp @@ -0,0 +1,46 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +struct A {}; +struct E {}; + +struct R { + operator A*(); + operator E*(); // expected-note{{candidate function}} +}; + + +struct S { + operator A*(); + operator E*(); // expected-note{{candidate function}} +}; + +struct B : R { + operator A*(); +}; + +struct C : B { + +}; + +void foo(C c, int A::* pmf) { + int i = c->*pmf; +} + +struct B1 : R, S { + operator A*(); +}; + +struct C1 : B1 { + +}; + +void foo1(C1 c1, int A::* pmf) { + int i = c1->*pmf; + c1->*pmf = 10; +} + +void foo1(C1 c1, int E::* pmf) { + // FIXME. Error reporting needs much improvement here. + int i = c1->*pmf; // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct C1'}} \ + // expected-note {{because of ambiguity in conversion of 'struct C1' to 'struct E *'}} +} diff --git a/test/SemaCXX/builtin-ptrtomember-overload.cpp b/test/SemaCXX/builtin-ptrtomember-overload.cpp new file mode 100644 index 000000000000..718e981805aa --- /dev/null +++ b/test/SemaCXX/builtin-ptrtomember-overload.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +struct A {}; + +struct B { + operator A*(); +}; + +struct C : B { + +}; + + +void foo(C c, B b, int A::* pmf) { + int j = c->*pmf; + int i = b->*pmf; +} + diff --git a/test/SemaCXX/c99.cpp b/test/SemaCXX/c99.cpp new file mode 100644 index 000000000000..b0ee056ef379 --- /dev/null +++ b/test/SemaCXX/c99.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void f0(int i) { + char array[i]; // expected-error{{variable length arrays}} +} + +void f1(int i[static 5]) { // expected-error{{C99}} +} diff --git a/test/SemaCXX/cast-conversion.cpp b/test/SemaCXX/cast-conversion.cpp new file mode 100644 index 000000000000..cbc24aef28d5 --- /dev/null +++ b/test/SemaCXX/cast-conversion.cpp @@ -0,0 +1,21 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +struct R { + R(int); +}; + +struct A { + A(R); +}; + +struct B { + B(A); +}; + +int main () { + B(10); // expected-error {{functional-style cast from 'int' to 'struct B' is not allowed}} + (B)10; // expected-error {{C-style cast from 'int' to 'struct B' is not allowed}} + static_cast<B>(10); // expected-error {{static_cast from 'int' to 'struct B' is not allowed}} \\ + // expected-warning {{expression result unused}} +} + diff --git a/test/SemaCXX/cast-explicit-ctor.cpp b/test/SemaCXX/cast-explicit-ctor.cpp new file mode 100644 index 000000000000..62134ae658db --- /dev/null +++ b/test/SemaCXX/cast-explicit-ctor.cpp @@ -0,0 +1,6 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct B { explicit B(bool); }; +void f() { + (void)(B)true; + (void)B(true); +} diff --git a/test/SemaCXX/class-base-member-init.cpp b/test/SemaCXX/class-base-member-init.cpp index c38c3d3337e7..2092847bc02d 100644 --- a/test/SemaCXX/class-base-member-init.cpp +++ b/test/SemaCXX/class-base-member-init.cpp @@ -7,9 +7,9 @@ public: struct D : S { D() : b1(0), b2(1), b1(0), S(), S() {} // expected-error {{multiple initializations given for non-static member 'b1'}} \ - // expected-note {{previous initialization is here}} \ - // expected-error {{multiple initializations given for base 'class S'}} \ - // expected-note {{previous initialization is here}} + // expected-note {{previous initialization is here}} \ + // expected-error {{multiple initializations given for base 'class S'}} \ + // expected-note {{previous initialization is here}} int b1; int b2; diff --git a/test/SemaCXX/class-layout.cpp b/test/SemaCXX/class-layout.cpp new file mode 100644 index 000000000000..56f41bfbdb93 --- /dev/null +++ b/test/SemaCXX/class-layout.cpp @@ -0,0 +1,49 @@ +// RUN: clang-cc -triple x86_64-unknown-unknown %s -fsyntax-only -verify + +#define SA(n, p) int a##n[(p) ? 1 : -1] + +struct A { + int a; + char b; +}; + +SA(0, sizeof(A) == 8); + +struct B : A { + char c; +}; + +SA(1, sizeof(B) == 12); + +struct C { +// Make fields private so C won't be a POD type. +private: + int a; + char b; +}; + +SA(2, sizeof(C) == 8); + +struct D : C { + char c; +}; + +SA(3, sizeof(D) == 8); + +struct __attribute__((packed)) E { + char b; + int a; +}; + +SA(4, sizeof(E) == 5); + +struct __attribute__((packed)) F : E { + char d; +}; + +SA(5, sizeof(F) == 6); + +struct G { G(); }; +struct H : G { }; + +SA(6, sizeof(H) == 1); diff --git a/test/SemaCXX/class-names.cpp b/test/SemaCXX/class-names.cpp index a5569c0c767b..da9014574d2c 100644 --- a/test/SemaCXX/class-names.cpp +++ b/test/SemaCXX/class-names.cpp @@ -5,7 +5,7 @@ C c; void D(int); -class D {}; // expected-note {{previous use is here}} +class D {}; void foo() { @@ -13,7 +13,7 @@ void foo() class D d; } -class D; +class D; // expected-note {{previous use is here}} enum D; // expected-error {{use of 'D' with tag type that does not match previous declaration}} diff --git a/test/SemaCXX/composite-pointer-type.cpp b/test/SemaCXX/composite-pointer-type.cpp index b4a5c884f755..ebc40c14b743 100644 --- a/test/SemaCXX/composite-pointer-type.cpp +++ b/test/SemaCXX/composite-pointer-type.cpp @@ -25,3 +25,11 @@ void f1(volatile Base *b, Derived1 *d1, const Derived2 *d2) { if (d1 == d2) // expected-error{{comparison of distinct}} return; } + +// PR4691 +int ptrcmp1(void *a, int *b) { + return a < b; +} +int ptrcmp2(long *a, int *b) { + return a < b; // expected-error{{distinct}} +}
\ No newline at end of file diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp index 3f4d7159a0f8..fea3324b5fd5 100644 --- a/test/SemaCXX/conditional-expr.cpp +++ b/test/SemaCXX/conditional-expr.cpp @@ -170,11 +170,13 @@ void test() i1 ? &MixedFields::ci : &MixedFieldsDerived::i; const volatile int (MixedFields::*mp2) = i1 ? &MixedFields::ci : &MixedFields::cvi; - i1 ? &MixedFields::ci : &MixedFields::vi; // expected-error {{incompatible operand types}} + (void)(i1 ? &MixedFields::ci : &MixedFields::vi); // Conversion of primitives does not result in an lvalue. &(i1 ? i1 : d1); // expected-error {{address expression must be an lvalue or a function designator}} - + (void)&(i1 ? flds.b1 : flds.i1); // expected-error {{address of bit-field requested}} + (void)&(i1 ? flds.i1 : flds.b1); // expected-error {{address of bit-field requested}} + // Note the thing that this does not test: since DR446, various situations // *must* create a separate temporary copy of class objects. This can only // be properly tested at runtime, though. diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp index a180d907f1b7..b86a27d66d98 100644 --- a/test/SemaCXX/constructor-initializer.cpp +++ b/test/SemaCXX/constructor-initializer.cpp @@ -1,7 +1,8 @@ -// RUN: clang-cc -fsyntax-only -verify %s +// RUN: clang-cc -Wreorder -fsyntax-only -verify %s class A { int m; A() : A::m(17) { } // expected-error {{member initializer 'm' does not name a non-static data member or base class}} + A(int); }; class B : public A { @@ -26,7 +27,7 @@ public: class E : public D, public B { public: - E() : B(), D() { } // expected-error{{base class initializer 'B' names both a direct base class and an inherited virtual base class}} + E() : B(), D() { } // expected-error{{base class initializer 'class B' names both a direct base class and an inherited virtual base class}} }; @@ -64,7 +65,7 @@ struct S : Y, virtual X { }; struct Z : S { - Z() : S(), X(), E() {} // expected-error {{type 'class E' is not a direct or virtual base of 'Z'}} + Z() : X(), S(), E() {} // expected-error {{type 'class E' is not a direct or virtual base of 'Z'}} }; class U { @@ -85,11 +86,39 @@ struct Derived : Base, Base1, virtual V { struct Current : Derived { int Derived; - Current() : Derived(1), ::Derived(), + Current() : Derived(1), ::Derived(), // expected-warning {{member 'Derived' will be initialized after}} \ + // expected-note {{base '::Derived'}} \ + // expected-warning {{base class '::Derived' will be initialized after}} ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}} Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}} - Derived::V(), + Derived::V(), // expected-note {{base 'Derived::V'}} ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} INT::NonExisting() {} // expected-error {{expected a class or namespace}} \ - // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} + // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} +}; + + // FIXME. This is bad message! +struct M { // expected-note {{candidate function}} \ + // expected-note {{candidate function}} + M(int i, int j); // expected-note {{candidate function}} \ + // // expected-note {{candidate function}} +}; + +struct N : M { + N() : M(1), // expected-error {{no matching constructor for initialization of 'M'}} + m1(100) { } // expected-error {{no matching constructor for initialization of 'm1'}} + M m1; +}; + +struct P : M { // expected-error {{default constructor for 'struct M' is missing in initialization of base class}} + P() { } + M m; // expected-error {{default constructor for 'struct M' is missing in initialization of member}} +}; + +struct Q { + Q() : f1(1,2), // expected-error {{Too many arguments for member initializer 'f1'}} + pf(0.0) { } // expected-error {{incompatible type passing 'double', expected 'float *'}} + float f1; + + float *pf; }; diff --git a/test/SemaCXX/constructor.cpp b/test/SemaCXX/constructor.cpp index 8f289a2b1e96..5ce595cdcece 100644 --- a/test/SemaCXX/constructor.cpp +++ b/test/SemaCXX/constructor.cpp @@ -58,3 +58,29 @@ void y() { a z; z.b(x); } } + +namespace A { + struct S { + S(); + S(int); + void f1(); + void f2(); + operator int (); + ~S(); + }; +} + +A::S::S() {} + +void A::S::f1() {} + +struct S {}; + +A::S::S(int) {} + +void A::S::f2() {} + +A::S::operator int() { return 1; } + +A::S::~S() {} + diff --git a/test/SemaCXX/conversion-delete-expr.cpp b/test/SemaCXX/conversion-delete-expr.cpp new file mode 100644 index 000000000000..708289c362dc --- /dev/null +++ b/test/SemaCXX/conversion-delete-expr.cpp @@ -0,0 +1,109 @@ +// RUN: clang-cc -fsyntax-only -verify -std=c++0x %s + +// Test1 +struct B { + operator char *(); // expected-note {{candidate function}} +}; + +struct D : B { + operator int *(); // expected-note {{candidate function}} +}; + +void f (D d) +{ + delete d; // expected-error {{ambiguous conversion of delete expression of type 'struct D' to a pointer}} +} + +// Test2 +struct B1 { + operator int *(); +}; + +struct D1 : B1 { + operator int *(); +}; + +void f1 (D1 d) +{ + delete d; +} + +// Test3 +struct B2 { + operator const int *(); // expected-note {{candidate function}} +}; + +struct D2 : B2 { + operator int *(); // expected-note {{candidate function}} +}; + +void f2 (D2 d) +{ + delete d; // expected-error {{ambiguous conversion of delete expression of type 'struct D2' to a pointer}} +} + +// Test4 +struct B3 { + operator const int *(); // expected-note {{candidate function}} +}; + +struct A3 { + operator const int *(); // expected-note {{candidate function}} +}; + +struct D3 : A3, B3 { +}; + +void f3 (D3 d) +{ + delete d; // expected-error {{mbiguous conversion of delete expression of type 'struct D3' to a pointer}} +} + +// Test5 +struct X { + operator int(); + operator int*(); +}; + +void f4(X x) { delete x; delete x; } + +// Test6 +struct X1 { + operator int(); + operator int*(); + template<typename T> operator T*() const; // converts to any pointer! +}; + +void f5(X1 x) { delete x; } // OK. In selecting a conversion to pointer function, template convesions are skipped. + +// Test7 +struct Base { + operator int*(); +}; + +struct Derived : Base { + // not the same function as Base's non-const operator int() + operator int*() const; +}; + +void foo6(const Derived cd, Derived d) { + // overload resolution selects Derived::operator int*() const; + delete cd; + delete d; +} + +// Test8 +struct BB { + template<typename T> operator T*() const; +}; + +struct DD : BB { + template<typename T> operator T*() const; // hides base conversion + operator int *() const; +}; + +void foo7 (DD d) +{ + // OK. In selecting a conversion to pointer function, template convesions are skipped. + delete d; +} diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp index 1ca1e689eab0..6182678e3113 100644 --- a/test/SemaCXX/conversion-function.cpp +++ b/test/SemaCXX/conversion-function.cpp @@ -64,3 +64,32 @@ struct Flip { operator Flop() const; }; Flop flop = Flip(); // expected-error {{cannot initialize 'flop' with an rvalue of type 'struct Flip'}} + +// This tests that we don't add the second conversion declaration to the list of user conversions +struct C { + operator const char *() const; +}; + +C::operator const char*() const { return 0; } + +void f(const C& c) { + const char* v = c; +} + +// Test. Conversion in base class is visible in derived class. +class XB { +public: + operator int(); // expected-note {{candidate function}} +}; + +class Yb : public XB { +public: + operator char(); // expected-note {{candidate function}} +}; + +void f(Yb& a) { + if (a) { } // expected-error {{conversion from 'class Yb' to 'bool' is ambiguous}} + int i = a; // OK. calls XB::operator int(); + char ch = a; // OK. calls Yb::operator char(); +} + diff --git a/test/SemaCXX/copy-assignment.cpp b/test/SemaCXX/copy-assignment.cpp index 6e5012f5a7a1..413e4d193367 100644 --- a/test/SemaCXX/copy-assignment.cpp +++ b/test/SemaCXX/copy-assignment.cpp @@ -11,7 +11,7 @@ struct ConvertibleToConstA { }; struct B { - B& operator=(B&); + B& operator=(B&); // expected-note 4 {{candidate function}} }; struct ConvertibleToB { diff --git a/test/SemaCXX/copy-constructor-error.cpp b/test/SemaCXX/copy-constructor-error.cpp new file mode 100644 index 000000000000..2e42fcc3b1cd --- /dev/null +++ b/test/SemaCXX/copy-constructor-error.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct S { // expected-note {{candidate function}} + S (S); // expected-error {{copy constructor must pass its first argument by reference}} \\ + // expected-note {{candidate function}} +}; + +S f(); + +void g() { + S a( f() ); // expected-error {{call to constructor of 'a' is ambiguous}} +} + diff --git a/test/SemaCXX/cstyle-cast.cpp b/test/SemaCXX/cstyle-cast.cpp new file mode 100644 index 000000000000..9c47df927e7b --- /dev/null +++ b/test/SemaCXX/cstyle-cast.cpp @@ -0,0 +1,231 @@ +// RUN: clang-cc -fsyntax-only -verify -faccess-control %s + +struct A {}; + +// ----------- const_cast -------------- + +typedef char c; +typedef c *cp; +typedef cp *cpp; +typedef cpp *cppp; +typedef cppp &cpppr; +typedef const cppp &cpppcr; +typedef const char cc; +typedef cc *ccp; +typedef volatile ccp ccvp; +typedef ccvp *ccvpp; +typedef const volatile ccvpp ccvpcvp; +typedef ccvpcvp *ccvpcvpp; +typedef int iar[100]; +typedef iar &iarr; +typedef int (*f)(int); + +void t_cc() +{ + ccvpcvpp var = 0; + // Cast away deep consts and volatiles. + char ***var2 = (cppp)(var); + char ***const &var3 = var2; + // Const reference to reference. + char ***&var4 = (cpppr)(var3); + // Drop reference. Intentionally without qualifier change. + char *** var5 = (cppp)(var4); + const int ar[100] = {0}; + // Array decay. Intentionally without qualifier change. + int *pi = (int*)(ar); + f fp = 0; + // Don't misidentify fn** as a function pointer. + f *fpp = (f*)(&fp); + int const A::* const A::*icapcap = 0; + int A::* A::* iapap = (int A::* A::*)(icapcap); +} + +// ----------- static_cast ------------- + +struct B : public A {}; // Single public base. +struct C1 : public virtual B {}; // Single virtual base. +struct C2 : public virtual B {}; +struct D : public C1, public C2 {}; // Diamond +struct E : private A {}; // Single private base. +struct F : public C1 {}; // Single path to B with virtual. +struct G1 : public B {}; +struct G2 : public B {}; +struct H : public G1, public G2 {}; // Ambiguous path to B. + +enum Enum { En1, En2 }; +enum Onom { On1, On2 }; + +struct Co1 { operator int(); }; +struct Co2 { Co2(int); }; +struct Co3 { }; +struct Co4 { Co4(Co3); operator Co3(); }; + +// Explicit implicits +void t_529_2() +{ + int i = 1; + (void)(float)(i); + double d = 1.0; + (void)(float)(d); + (void)(int)(d); + (void)(char)(i); + (void)(unsigned long)(i); + (void)(int)(En1); + (void)(double)(En1); + (void)(int&)(i); + (void)(const int&)(i); + + int ar[1]; + (void)(const int*)(ar); + (void)(void (*)())(t_529_2); + + (void)(void*)(0); + (void)(void*)((int*)0); + (void)(volatile const void*)((const int*)0); + (void)(A*)((B*)0); + (void)(A&)(*((B*)0)); + (void)(const B*)((C1*)0); + (void)(B&)(*((C1*)0)); + (void)(A*)((D*)0); + (void)(const A&)(*((D*)0)); + (void)(int B::*)((int A::*)0); + (void)(void (B::*)())((void (A::*)())0); + (void)(A*)((E*)0); // C-style cast ignores access control + (void)(void*)((const int*)0); // const_cast appended + + (void)(int)(Co1()); + (void)(Co2)(1); + (void)(Co3)((Co4)(Co3())); + + // Bad code below + //(void)(A*)((H*)0); // {{static_cast from 'struct H *' to 'struct A *' is not allowed}} +} + +// Anything to void +void t_529_4() +{ + (void)(1); + (void)(t_529_4); +} + +// Static downcasts +void t_529_5_8() +{ + (void)(B*)((A*)0); + (void)(B&)(*((A*)0)); + (void)(const G1*)((A*)0); + (void)(const G1&)(*((A*)0)); + (void)(B*)((const A*)0); // const_cast appended + (void)(B&)(*((const A*)0)); // const_cast appended + (void)(E*)((A*)0); // access control ignored + (void)(E&)(*((A*)0)); // access control ignored + + // Bad code below + + (void)(C1*)((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct C1 *' via virtual base 'struct B'}} + (void)(C1&)(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct C1 &' via virtual base 'struct B'}} + (void)(D*)((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct D *' via virtual base 'struct B'}} + (void)(D&)(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct D &' via virtual base 'struct B'}} + (void)(H*)((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + (void)(H&)(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + + // TODO: Test DR427. This requires user-defined conversions, though. +} + +// Enum conversions +void t_529_7() +{ + (void)(Enum)(1); + (void)(Enum)(1.0); + (void)(Onom)(En1); + + // Bad code below + + (void)(Enum)((int*)0); // expected-error {{C-style cast from 'int *' to 'enum Enum' is not allowed}} +} + +// Void pointer to object pointer +void t_529_10() +{ + (void)(int*)((void*)0); + (void)(const A*)((void*)0); + (void)(int*)((const void*)0); // const_cast appended +} + +// Member pointer upcast. +void t_529_9() +{ + (void)(int A::*)((int B::*)0); + + // Bad code below + (void)(int A::*)((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'struct H'}} + (void)(int A::*)((int F::*)0); // expected-error {{conversion from pointer to member of class 'struct F'}} +} + +// -------- reinterpret_cast ----------- + +enum test { testval = 1 }; +struct structure { int m; }; +typedef void (*fnptr)(); + +// Test conversion between pointer and integral types, as in p3 and p4. +void integral_conversion() +{ + void *vp = (void*)(testval); + long l = (long)(vp); + (void)(float*)(l); + fnptr fnp = (fnptr)(l); + (void)(char)(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}} + (void)(long)(fnp); +} + +void pointer_conversion() +{ + int *p1 = 0; + float *p2 = (float*)(p1); + structure *p3 = (structure*)(p2); + typedef int **ppint; + ppint *deep = (ppint*)(p3); + (void)(fnptr*)(deep); +} + +void constness() +{ + int ***const ipppc = 0; + int const *icp = (int const*)(ipppc); + (void)(int*)(icp); // const_cast appended + int const *const **icpcpp = (int const* const**)(ipppc); // const_cast appended + int *ip = (int*)(icpcpp); + (void)(int const*)(ip); + (void)(int const* const* const*)(ipppc); +} + +void fnptrs() +{ + typedef int (*fnptr2)(int); + fnptr fp = 0; + (void)(fnptr2)(fp); + void *vp = (void*)(fp); + (void)(fnptr)(vp); +} + +void refs() +{ + long l = 0; + char &c = (char&)(l); + // Bad: from rvalue + (void)(int&)(&c); // expected-error {{C-style cast from rvalue to reference type 'int &'}} +} + +void memptrs() +{ + const int structure::*psi = 0; + (void)(const float structure::*)(psi); + (void)(int structure::*)(psi); // const_cast appended + + void (structure::*psf)() = 0; + (void)(int (structure::*)())(psf); + + (void)(void (structure::*)())(psi); // expected-error {{C-style cast from 'int const struct structure::*' to 'void (struct structure::*)()' is not allowed}} + (void)(int structure::*)(psf); // expected-error {{C-style cast from 'void (struct structure::*)()' to 'int struct structure::*' is not allowed}} +} diff --git a/test/SemaCXX/dcl_ambig_res.cpp b/test/SemaCXX/dcl_ambig_res.cpp index 57bf4095afd0..495a6e6e42c8 100644 --- a/test/SemaCXX/dcl_ambig_res.cpp +++ b/test/SemaCXX/dcl_ambig_res.cpp @@ -50,7 +50,7 @@ void foo5() void foo6() { (void)(int(1)); //expression - (void)(int())1; // expected-error{{used type}} + (void)(int())1; // expected-error{{to 'int ()'}} } // [dcl.ambig.res]p7: @@ -64,3 +64,10 @@ void foo7() { void h7(int *(C7[10])) { } // expected-note{{previous}} void h7(int *(*_fp)(C7 _parm[10])) { } // expected-error{{redefinition}} + +struct S5 { + static bool const value = false; +}; +int foo8() { + int v(int(S5::value)); // expected-warning{{disambiguated}} expected-error{{parameter declarator cannot be qualified}} +} diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp index 10c15ccc9061..20b787a22526 100644 --- a/test/SemaCXX/dcl_init_aggr.cpp +++ b/test/SemaCXX/dcl_init_aggr.cpp @@ -40,8 +40,8 @@ char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-error{{excess elements in ar struct TooFew { int a; char* b; int c; }; TooFew too_few = { 1, "asdf" }; // okay -struct NoDefaultConstructor { // expected-note 5 {{candidate function}} - NoDefaultConstructor(int); // expected-note 5 {{candidate function}} +struct NoDefaultConstructor { // expected-note 3 {{candidate function}} + NoDefaultConstructor(int); // expected-note 3 {{candidate function}} }; struct TooFewError { int a; @@ -53,7 +53,7 @@ TooFewError too_few_error = { 1 }; // expected-error{{no matching constructor}} TooFewError too_few_okay2[2] = { 1, 1 }; TooFewError too_few_error2[2] = { 1 }; // expected-error{{no matching constructor}} -NoDefaultConstructor too_few_error3[3] = { }; // expected-error 3 {{no matching constructor}} +NoDefaultConstructor too_few_error3[3] = { }; // expected-error {{no matching constructor}} // C++ [dcl.init.aggr]p8 struct Empty { }; diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp index 05e25e9bb868..8d34a9ee7df9 100644 --- a/test/SemaCXX/decl-expr-ambiguity.cpp +++ b/test/SemaCXX/decl-expr-ambiguity.cpp @@ -12,14 +12,14 @@ void f() { __typeof(int)(a,5)<<a; // expected-error {{function-style cast to a builtin type can only take one argument}} void(a), ++a; // expected-warning {{expression result unused}} if (int(a)+1) {} - for (int(a)+1;;) {} + for (int(a)+1;;) {} // expected-warning {{expression result unused}} a = sizeof(int()+1); a = sizeof(int(1)); typeof(int()+1) a2; // expected-error {{extension used}} (int(1)); // expected-warning {{expression result unused}} // type-id - (int())1; // expected-error {{used type 'int ()' where arithmetic or pointer type is required}} + (int())1; // expected-error {{C-style cast from 'int' to 'int ()' is not allowed}} // Declarations. int fd(T(a)); // expected-warning {{parentheses were disambiguated as a function declarator}} diff --git a/test/SemaCXX/decl-init-ref.cpp b/test/SemaCXX/decl-init-ref.cpp new file mode 100644 index 000000000000..d7db647cd11a --- /dev/null +++ b/test/SemaCXX/decl-init-ref.cpp @@ -0,0 +1,26 @@ +// RUN: clang-cc -fsyntax-only -verify -std=c++0x %s + +struct A {}; + +struct BASE { + operator A(); // expected-note {{candidate function}} +}; + +struct BASE1 { + operator A(); // expected-note {{candidate function}} +}; + +class B : public BASE , public BASE1 +{ + public: + B(); +} b; + +extern B f(); + +const int& ri = (void)0; // expected-error {{invalid initialization of reference of type 'int const &' from expression of type 'void'}} + +int main() { + const A& rca = f(); // expected-error {{rvalue reference cannot bind to lvalue due to multiple conversion functions}} + A& ra = f(); // expected-error {{non-const lvalue reference to type 'struct A' cannot be initialized with a temporary of type 'class B'}} +} diff --git a/test/SemaCXX/decltype-crash.cpp b/test/SemaCXX/decltype-crash.cpp new file mode 100644 index 000000000000..b56a7f602987 --- /dev/null +++ b/test/SemaCXX/decltype-crash.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +int& a(); + +void f() { + decltype(a()) c; // expected-error {{no matching function for call to 'decltype'}} +} diff --git a/test/SemaCXX/decltype-this.cpp b/test/SemaCXX/decltype-this.cpp new file mode 100644 index 000000000000..fc001063c510 --- /dev/null +++ b/test/SemaCXX/decltype-this.cpp @@ -0,0 +1,15 @@ +// RUN: clang-cc -fsyntax-only -verify -std=c++0x %t +template<typename T, typename U> struct is_same { + static const bool value = false; +}; + +template<typename T> struct is_same<T, T> { + static const bool value = true; +}; + +struct S { + void f() { static_assert(is_same<decltype(this), S*>::value, ""); } + void g() const { static_assert(is_same<decltype(this), const S*>::value, ""); } + void h() volatile { static_assert(is_same<decltype(this), volatile S*>::value, ""); } + void i() const volatile { static_assert(is_same<decltype(this), const volatile S*>::value, ""); } +}; diff --git a/test/SemaCXX/default-argument-temporaries.cpp b/test/SemaCXX/default-argument-temporaries.cpp new file mode 100644 index 000000000000..232351dcff3d --- /dev/null +++ b/test/SemaCXX/default-argument-temporaries.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct B { B(void* = 0); }; + +struct A { + A(B b = B()) { } +}; + +void f() { + (void)B(); + (void)A(); +} diff --git a/test/SemaCXX/default-assignment-operator.cpp b/test/SemaCXX/default-assignment-operator.cpp index 090ba3c3ca80..e627fefdef6d 100644 --- a/test/SemaCXX/default-assignment-operator.cpp +++ b/test/SemaCXX/default-assignment-operator.cpp @@ -26,7 +26,7 @@ Z z2; // Test1 void f(X x, const X cx) { - x = cx; // expected-note {{synthesized method is first required here}} + x = cx; // expected-note {{synthesized method is first required here}} x = cx; z1 = z2; } @@ -36,8 +36,7 @@ class T {}; T t1; T t2; -void g() -{ +void g() { t1 = t2; } @@ -51,8 +50,7 @@ public: class W : V {}; W w1, w2; -void h() -{ +void h() { w1 = w2; } @@ -67,8 +65,22 @@ public: class D1 : B1 {}; D1 d1, d2; -void i() -{ - d1 = d2; +void i() { + d1 = d2; +} + +// Test5 + +class E1 { // expected-error{{cannot define the implicit default assignment operator for 'class E1', because non-static const member 'a' can't use default assignment operator}} +public: + const int a; // expected-note{{declared at}} + E1() : a(0) {} + +}; + +E1 e1, e2; + +void j() { + e1 = e2; // expected-note{{synthesized method is first required here}} } diff --git a/test/SemaCXX/default-constructor-initializers.cpp b/test/SemaCXX/default-constructor-initializers.cpp index 24c53839622c..6cbb978dbb99 100644 --- a/test/SemaCXX/default-constructor-initializers.cpp +++ b/test/SemaCXX/default-constructor-initializers.cpp @@ -11,16 +11,16 @@ struct X2 : X1 { // expected-note {{'struct X2' declared here}} \ struct X3 : public X2 { }; -X3 x3; // expected-error {{cannot define the implicit default constructor for 'struct X3', because member 'struct X2' does not have any default constructor}} +X3 x3; // expected-error {{cannot define the implicit default constructor for 'struct X3', because base class 'struct X2' does not have any default constructor}} struct X4 { - X2 x2; + X2 x2; // expected-note {{member is declared here}} X2 & rx2; // expected-note {{declared at}} }; -X4 x4; // expected-error {{cannot define the implicit default constructor for 'struct X4', because base class 'struct X2' does not have any default constructor}} \ - // expected-error {{cannot define the implicit default constructor for 'struct X4', because reference member rx2 cannot be default-initialized}} +X4 x4; // expected-error {{cannot define the implicit default constructor for 'struct X4', because member's type 'struct X2' does not have any default constructor}} \ + // expected-error {{cannot define the implicit default constructor for 'struct X4', because reference member 'rx2' cannot be default-initialized}} struct Y1 { // has no implicit default constructor @@ -46,11 +46,11 @@ Y4 y4; struct Z1 { - int& z; // expected-note {{declared at}} - const int c1; // expected-note {{declared at}} - volatile int v1; + int& z; // expected-note {{declared at}} + const int c1; // expected-note {{declared at}} + volatile int v1; }; -Z1 z1; // expected-error {{cannot define the implicit default constructor for 'struct Z1', because reference member z cannot be default-initialized}} \ - // expected-error {{cannot define the implicit default constructor for 'struct Z1', because const member c1 cannot be default-initialized}} +Z1 z1; // expected-error {{cannot define the implicit default constructor for 'struct Z1', because reference member 'z' cannot be default-initialized}} \ + // expected-error {{cannot define the implicit default constructor for 'struct Z1', because const member 'c1' cannot be default-initialized}} diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp index edbd6b3e206a..183452070da4 100644 --- a/test/SemaCXX/default2.cpp +++ b/test/SemaCXX/default2.cpp @@ -24,20 +24,8 @@ int f1(int i, int i, int j) { // expected-error {{redefinition of parameter 'i'} int x; void g(int x, int y = x); // expected-error {{default argument references parameter 'x'}} -void h() -{ - int i; - extern void h2(int x = sizeof(i)); // expected-error {{default argument references local variable 'i' of enclosing function}} -} - void g2(int x, int y, int z = x + y); // expected-error {{default argument references parameter 'x'}} expected-error {{default argument references parameter 'y'}} -void nondecl(int (*f)(int x = 5)) // {expected-error {{default arguments can only be specified}}} -{ - void (*f2)(int = 17) // {expected-error {{default arguments can only be specified}}} - = (void (*)(int = 42))f; // {expected-error {{default arguments can only be specified}}} -} - class X { void f(X* x = this); // expected-error{{invalid use of 'this' outside of a nonstatic member function}} @@ -82,10 +70,6 @@ struct Y { }; static int b; - - int (*f)(int = 17); // expected-error{{default arguments can only be specified for parameters in a function declaration}} - - void mem8(int (*fp)(int) = (int (*)(int = 17))0); // expected-error{{default arguments can only be specified for parameters in a function declaration}} }; int Y::mem3(int i = b) { return i; } // OK; use X::b @@ -127,3 +111,9 @@ class C2 { static void g(int = f()); // expected-error{{use of default argument to function 'f' that is declared later in class 'C2'}} static int f(int = 10); // expected-note{{default argument declared here}} }; + +// Make sure we actually parse the default argument for an inline definition +class XX { + void A(int length = -1 ) { } + void B() { A(); } +}; diff --git a/test/SemaCXX/deleted-function.cpp b/test/SemaCXX/deleted-function.cpp index 8064ed349b08..637b2b1b2d5c 100644 --- a/test/SemaCXX/deleted-function.cpp +++ b/test/SemaCXX/deleted-function.cpp @@ -18,7 +18,7 @@ void ov(double) = delete; // expected-note {{candidate function has been explici struct WithDel { WithDel() = delete; // expected-note {{candidate function has been explicitly deleted}} void fn() = delete; // expected-note {{function has been explicitly marked deleted here}} - operator int() = delete; + operator int() = delete; void operator +(int) = delete; int i = delete; // expected-error {{only functions can have deleted definitions}} diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp index f544db0b1b6e..790a401ae99c 100644 --- a/test/SemaCXX/destructor.cpp +++ b/test/SemaCXX/destructor.cpp @@ -40,8 +40,9 @@ struct F { ~F(); // expected-error {{destructor cannot be redeclared}} }; -~; // expected-error {{expected class name}} -~undef(); // expected-error {{expected class name}} +~; // expected-error {{expected the class name after '~' to name a destructor}} +~undef(); // expected-error {{expected the class name after '~' to name a destructor}} +~operator+(int, int); // expected-error {{expected the class name after '~' to name a destructor}} ~F(){} // expected-error {{destructor must be a non-static member function}} struct G { @@ -54,3 +55,9 @@ G::~G() { } struct H { ~H(void) { } }; + +struct X {}; + +struct Y { + ~X(); // expected-error {{expected the class name after '~' to name the enclosing class}} +}; diff --git a/test/SemaCXX/direct-initializer.cpp b/test/SemaCXX/direct-initializer.cpp index 149b65c8d71d..a9e2b2bb6e45 100644 --- a/test/SemaCXX/direct-initializer.cpp +++ b/test/SemaCXX/direct-initializer.cpp @@ -34,3 +34,17 @@ void g() { Z z; // expected-error{{no matching constructor for initialization of 'z'}} } + +struct Base { + operator int*() const; +}; + +struct Derived : Base { + operator int*(); +}; + +void foo(const Derived cd, Derived d) { + int *pi = cd; // expected-error {{incompatible type initializing 'struct Derived const', expected 'int *'}} + int *ppi = d; + +} diff --git a/test/SemaCXX/empty-class-layout.cpp b/test/SemaCXX/empty-class-layout.cpp new file mode 100644 index 000000000000..8b54ea1c66f2 --- /dev/null +++ b/test/SemaCXX/empty-class-layout.cpp @@ -0,0 +1,68 @@ +// RUN: clang-cc -triple x86_64-unknown-unknown %s -fsyntax-only -verify + +#define SA(n, p) int a##n[(p) ? 1 : -1] + +struct A { int a; }; +SA(0, sizeof(A) == 4); + +struct B { }; +SA(1, sizeof(B) == 1); + +struct C : A, B { }; +SA(2, sizeof(C) == 4); + +struct D { }; +struct E : D { }; +struct F : E { }; + +struct G : E, F { }; +SA(3, sizeof(G) == 2); + +struct Empty { Empty(); }; + +struct I : Empty { + Empty e; +}; +SA(4, sizeof(I) == 2); + +struct J : Empty { + Empty e[2]; +}; +SA(5, sizeof(J) == 3); + +template<int N> struct Derived : Empty, Derived<N - 1> { +}; +template<> struct Derived<0> : Empty { }; + +struct S1 : virtual Derived<10> { + Empty e; +}; +SA(6, sizeof(S1) == 24); + +struct S2 : virtual Derived<10> { + Empty e[2]; +}; +SA(7, sizeof(S2) == 24); + +struct S3 { + Empty e; +}; + +struct S4 : Empty, S3 { +}; +SA(8, sizeof(S4) == 2); + +struct S5 : S3, Empty {}; +SA(9, sizeof(S5) == 2); + +struct S6 : S5 { }; +SA(10, sizeof(S6) == 2); + +struct S7 : Empty { + void *v; +}; +SA(11, sizeof(S7) == 8); + +struct S8 : Empty, A { +}; +SA(12, sizeof(S8) == 4); diff --git a/test/SemaCXX/enum.cpp b/test/SemaCXX/enum.cpp index 9668c84693d3..db256812ab80 100644 --- a/test/SemaCXX/enum.cpp +++ b/test/SemaCXX/enum.cpp @@ -14,14 +14,13 @@ void f() { // <rdar://problem/6502934> typedef enum Foo { - A = 0, - B = 1 + A = 0, + B = 1 } Foo; - - + void bar() { - Foo myvar = A; - myvar = B; + Foo myvar = A; + myvar = B; } /// PR3688 @@ -32,7 +31,7 @@ struct s1 { enum e1 { YES, NO }; static enum e1 badfunc(struct s1 *q) { - return q->bar(); // expected-error{{return type of called function ('enum s1::e1') is incomplete}} + return q->bar(); // expected-error{{calling function with incomplete return type 'enum s1::e1'}} } enum e2; // expected-error{{ISO C++ forbids forward references to 'enum' types}} diff --git a/test/SemaCXX/exception-spec.cpp b/test/SemaCXX/exception-spec.cpp index 5eba26e70c6f..9b2a07d79654 100644 --- a/test/SemaCXX/exception-spec.cpp +++ b/test/SemaCXX/exception-spec.cpp @@ -24,7 +24,7 @@ void (**j)() throw(int); // expected-error {{not allowed beyond a single}} // Pointer to function returning pointer to pointer to function with spec void (**(*h())())() throw(int); // expected-error {{not allowed beyond a single}} -struct Incomplete; +struct Incomplete; // expected-note 3 {{forward declaration}} // Exception spec must not have incomplete types, or pointers to them, except // void. @@ -61,3 +61,127 @@ void r7() throw(float); // expected-error {{exception specification in declarati // Top-level const doesn't matter. void r8() throw(int); void r8() throw(const int); + +// Multiple appearances don't matter. +void r9() throw(int, int); +void r9() throw(int, int); + +struct A +{ +}; + +struct B1 : A +{ +}; + +struct B2 : A +{ +}; + +struct D : B1, B2 +{ +}; + +struct P : private A +{ +}; + +struct Base +{ + virtual void f1() throw(); + virtual void f2(); + virtual void f3() throw(...); + virtual void f4() throw(int, float); + + virtual void f5() throw(int, float); + virtual void f6() throw(A); + virtual void f7() throw(A, int, float); + virtual void f8(); + + virtual void g1() throw(); // expected-note {{overridden virtual function is here}} + virtual void g2() throw(int); // expected-note {{overridden virtual function is here}} + virtual void g3() throw(A); // expected-note {{overridden virtual function is here}} + virtual void g4() throw(B1); // expected-note {{overridden virtual function is here}} + virtual void g5() throw(A); // expected-note {{overridden virtual function is here}} +}; +struct Derived : Base +{ + virtual void f1() throw(); + virtual void f2() throw(...); + virtual void f3(); + virtual void f4() throw(float, int); + + virtual void f5() throw(float); + virtual void f6() throw(B1); + virtual void f7() throw(B1, B2, int); + virtual void f8() throw(B2, B2, int, float, char, double, bool); + + virtual void g1() throw(int); // expected-error {{exception specification of overriding function is more lax}} + virtual void g2(); // expected-error {{exception specification of overriding function is more lax}} + virtual void g3() throw(D); // expected-error {{exception specification of overriding function is more lax}} + virtual void g4() throw(A); // expected-error {{exception specification of overriding function is more lax}} + virtual void g5() throw(P); // expected-error {{exception specification of overriding function is more lax}} +}; + +// Some functions to play with below. +void s1() throw(); +void s2() throw(int); +void s3() throw(A); +void s4() throw(B1); +void s5() throw(D); +void s6(); +void s7() throw(int, float); +void (*s8())() throw(B1); // s8 returns a pointer to function with spec +void s9(void (*)() throw(B1)); // s9 takes pointer to function with spec + +void fnptrs() +{ + // Assignment and initialization of function pointers. + void (*t1)() throw() = &s1; // valid + t1 = &s2; // expected-error {{not superset}} expected-error {{incompatible type}} + t1 = &s3; // expected-error {{not superset}} expected-error {{incompatible type}} + void (&t2)() throw() = s2; // expected-error {{not superset}} + void (*t3)() throw(int) = &s2; // valid + void (*t4)() throw(A) = &s1; // valid + t4 = &s3; // valid + t4 = &s4; // valid + t4 = &s5; // expected-error {{not superset}} expected-error {{incompatible type}} + void (*t5)() = &s1; // valid + t5 = &s2; // valid + t5 = &s6; // valid + t5 = &s7; // valid + t1 = t3; // expected-error {{not superset}} expected-error {{incompatible type}} + t3 = t1; // valid + void (*t6)() throw(B1); + t6 = t4; // expected-error {{not superset}} expected-error {{incompatible type}} + t4 = t6; // valid + t5 = t1; // valid + t1 = t5; // expected-error {{not superset}} expected-error {{incompatible type}} + + // return types and arguments must match exactly, no inheritance allowed + void (*(*t7)())() throw(B1) = &s8; // valid + void (*(*t8)())() throw(A) = &s8; // expected-error {{return types differ}} expected-error {{incompatible type}} + void (*(*t9)())() throw(D) = &s8; // expected-error {{return types differ}} expected-error {{incompatible type}} + void (*t10)(void (*)() throw(B1)) = &s9; // valid expected-warning{{disambiguated}} + void (*t11)(void (*)() throw(A)) = &s9; // expected-error {{argument types differ}} expected-error {{incompatible type}} expected-warning{{disambiguated}} + void (*t12)(void (*)() throw(D)) = &s9; // expected-error {{argument types differ}} expected-error {{incompatible type}} expected-warning{{disambiguated}} +} + +// Member function stuff + +struct Str1 { void f() throw(int); }; // expected-note {{previous declaration}} +void Str1::f() // expected-error {{does not match previous declaration}} +{ +} + +void mfnptr() +{ + void (Str1::*pfn1)() throw(int) = &Str1::f; // valid + void (Str1::*pfn2)() = &Str1::f; // valid + void (Str1::*pfn3)() throw() = &Str1::f; // expected-error {{not superset}} expected-error {{incompatible type}} +} + +// Don't suppress errors in template instantiation. +template <typename T> struct TEx; // expected-note {{template is declared here}} + +void tf() throw(TEx<int>); // expected-error {{implicit instantiation of undefined template}} diff --git a/test/SemaCXX/friend-class-nodecl.cpp b/test/SemaCXX/friend-class-nodecl.cpp new file mode 100644 index 000000000000..de12eaf741c5 --- /dev/null +++ b/test/SemaCXX/friend-class-nodecl.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -ast-print %s -o %t && +// RUN: not grep '^ *class B' %t + +// Tests that the tag decls in friend declarations aren't added to the +// declaring class's decl chain. + +class A { + friend class B; +}; + diff --git a/test/SemaCXX/function-overloaded-redecl.cpp b/test/SemaCXX/function-overloaded-redecl.cpp new file mode 100644 index 000000000000..4d8e57c1b9fe --- /dev/null +++ b/test/SemaCXX/function-overloaded-redecl.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +typedef const int cInt; + +void f (int); +void f (const int); // redecl + +void f (int) { } // expected-note {{previous definition is here}} +void f (cInt) { } // expected-error {{redefinition of 'f'}} + diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp index 0be7ddb53ae8..142dba7b13f7 100644 --- a/test/SemaCXX/functional-cast.cpp +++ b/test/SemaCXX/functional-cast.cpp @@ -1,4 +1,6 @@ -// RUN: clang-cc -fsyntax-only -verify %s +// RUN: clang-cc -fsyntax-only -verify -faccess-control %s + +// ------------ not interpreted as C-style cast ------------ struct SimpleValueInit { int i; @@ -25,3 +27,293 @@ void test_cxx_function_cast_multi() { (void)NoValueInit(0, 0, 0); // expected-error{{no matching constructor for initialization}} (void)int(1, 2); // expected-error{{function-style cast to a builtin type can only take one argument}} } + + +// ------------------ everything else -------------------- + +struct A {}; + +// ----------- const_cast -------------- + +typedef char c; +typedef c *cp; +typedef cp *cpp; +typedef cpp *cppp; +typedef cppp &cpppr; +typedef const cppp &cpppcr; +typedef const char cc; +typedef cc *ccp; +typedef volatile ccp ccvp; +typedef ccvp *ccvpp; +typedef const volatile ccvpp ccvpcvp; +typedef ccvpcvp *ccvpcvpp; +typedef int iar[100]; +typedef iar &iarr; +typedef int (*f)(int); + +void t_cc() +{ + ccvpcvpp var = 0; + // Cast away deep consts and volatiles. + char ***var2 = cppp(var); + char ***const &var3 = var2; + // Const reference to reference. + char ***&var4 = cpppr(var3); + // Drop reference. Intentionally without qualifier change. + char *** var5 = cppp(var4); + const int ar[100] = {0}; + // Array decay. Intentionally without qualifier change. + typedef int *intp; + int *pi = intp(ar); + f fp = 0; + // Don't misidentify fn** as a function pointer. + typedef f *fp_t; + f *fpp = fp_t(&fp); + int const A::* const A::*icapcap = 0; + typedef int A::* A::*iapap_t; + iapap_t iapap = iapap_t(icapcap); +} + +// ----------- static_cast ------------- + +struct B : public A {}; // Single public base. +struct C1 : public virtual B {}; // Single virtual base. +struct C2 : public virtual B {}; +struct D : public C1, public C2 {}; // Diamond +struct E : private A {}; // Single private base. +struct F : public C1 {}; // Single path to B with virtual. +struct G1 : public B {}; +struct G2 : public B {}; +struct H : public G1, public G2 {}; // Ambiguous path to B. + +enum Enum { En1, En2 }; +enum Onom { On1, On2 }; + +struct Co1 { operator int(); }; +struct Co2 { Co2(int); }; +struct Co3 { }; +struct Co4 { Co4(Co3); operator Co3(); }; + +// Explicit implicits +void t_529_2() +{ + int i = 1; + (void)float(i); + double d = 1.0; + (void)float(d); + (void)int(d); + (void)char(i); + typedef unsigned long ulong; + (void)ulong(i); + (void)int(En1); + (void)double(En1); + typedef int &intr; + (void)intr(i); + typedef const int &cintr; + (void)cintr(i); + + int ar[1]; + typedef const int *cintp; + (void)cintp(ar); + typedef void (*pfvv)(); + (void)pfvv(t_529_2); + + typedef void *voidp; + (void)voidp(0); + (void)voidp((int*)0); + typedef volatile const void *vcvoidp; + (void)vcvoidp((const int*)0); + typedef A *Ap; + (void)Ap((B*)0); + typedef A &Ar; + (void)Ar(*((B*)0)); + typedef const B *cBp; + (void)cBp((C1*)0); + typedef B &Br; + (void)Br(*((C1*)0)); + (void)Ap((D*)0); + typedef const A &cAr; + (void)cAr(*((D*)0)); + typedef int B::*Bmp; + (void)Bmp((int A::*)0); + typedef void (B::*Bmfp)(); + (void)Bmfp((void (A::*)())0); + (void)Ap((E*)0); // functional-style cast ignores access control + (void)voidp((const int*)0); // const_cast appended + + (void)int(Co1()); + (void)Co2(1); + (void)Co3((Co4)(Co3())); + + // Bad code below + //(void)(A*)((H*)0); // {{static_cast from 'struct H *' to 'struct A *' is not allowed}} +} + +// Anything to void +void t_529_4() +{ + void(1); + (void(t_529_4)); +} + +// Static downcasts +void t_529_5_8() +{ + typedef B *Bp; + (void)Bp((A*)0); + typedef B &Br; + (void)Br(*((A*)0)); + typedef const G1 *cG1p; + (void)cG1p((A*)0); + typedef const G1 &cG1r; + (void)cG1r(*((A*)0)); + (void)Bp((const A*)0); // const_cast appended + (void)Br(*((const A*)0)); // const_cast appended + typedef E *Ep; + (void)Ep((A*)0); // access control ignored + typedef E &Er; + (void)Er(*((A*)0)); // access control ignored + + // Bad code below + + typedef C1 *C1p; + (void)C1p((A*)0); // expected-error {{cannot cast 'struct A *' to 'C1p' (aka 'struct C1 *') via virtual base 'struct B'}} + typedef C1 &C1r; + (void)C1r(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'C1r' (aka 'struct C1 &') via virtual base 'struct B'}} + typedef D *Dp; + (void)Dp((A*)0); // expected-error {{cannot cast 'struct A *' to 'Dp' (aka 'struct D *') via virtual base 'struct B'}} + typedef D &Dr; + (void)Dr(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'Dr' (aka 'struct D &') via virtual base 'struct B'}} + typedef H *Hp; + (void)Hp((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + typedef H &Hr; + (void)Hr(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + + // TODO: Test DR427. This requires user-defined conversions, though. +} + +// Enum conversions +void t_529_7() +{ + (void)Enum(1); + (void)Enum(1.0); + (void)Onom(En1); + + // Bad code below + + (void)Enum((int*)0); // expected-error {{functional-style cast from 'int *' to 'enum Enum' is not allowed}} +} + +// Void pointer to object pointer +void t_529_10() +{ + typedef int *intp; + (void)intp((void*)0); + typedef const A *cAp; + (void)cAp((void*)0); + (void)intp((const void*)0); // const_cast appended +} + +// Member pointer upcast. +void t_529_9() +{ + typedef int A::*Amp; + (void)Amp((int B::*)0); + + // Bad code below + (void)Amp((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'struct H'}} + (void)Amp((int F::*)0); // expected-error {{conversion from pointer to member of class 'struct F'}} +} + +// -------- reinterpret_cast ----------- + +enum test { testval = 1 }; +struct structure { int m; }; +typedef void (*fnptr)(); + +// Test conversion between pointer and integral types, as in p3 and p4. +void integral_conversion() +{ + typedef void *voidp; + void *vp = voidp(testval); + long l = long(vp); + typedef float *floatp; + (void)floatp(l); + fnptr fnp = fnptr(l); + (void)char(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}} + (void)long(fnp); +} + +void pointer_conversion() +{ + int *p1 = 0; + typedef float *floatp; + float *p2 = floatp(p1); + typedef structure *structurep; + structure *p3 = structurep(p2); + typedef int **ppint; + typedef ppint *pppint; + ppint *deep = pppint(p3); + typedef fnptr fnptrp; + (void)fnptrp(deep); +} + +void constness() +{ + int ***const ipppc = 0; + typedef int const *icp_t; + int const *icp = icp_t(ipppc); + typedef int *intp; + (void)intp(icp); // const_cast appended + typedef int const *const ** intcpcpp; + intcpcpp icpcpp = intcpcpp(ipppc); // const_cast appended + int *ip = intp(icpcpp); + (void)icp_t(ip); + typedef int const *const *const *intcpcpcp; + (void)intcpcpcp(ipppc); +} + +void fnptrs() +{ + typedef int (*fnptr2)(int); + fnptr fp = 0; + (void)fnptr2(fp); + typedef void *voidp; + void *vp = voidp(fp); + (void)fnptr(vp); +} + +void refs() +{ + long l = 0; + typedef char &charr; + char &c = charr(l); + // Bad: from rvalue + typedef int &intr; + (void)intr(&c); // expected-error {{functional-style cast from rvalue to reference type 'intr' (aka 'int &')}} +} + +void memptrs() +{ + const int structure::*psi = 0; + typedef const float structure::*structurecfmp; + (void)structurecfmp(psi); + typedef int structure::*structureimp; + (void)structureimp(psi); // const_cast appended + + void (structure::*psf)() = 0; + typedef int (structure::*structureimfp)(); + (void)structureimfp(psf); + + typedef void (structure::*structurevmfp)(); + (void)structurevmfp(psi); // expected-error {{functional-style cast from 'int const struct structure::*' to 'structurevmfp' (aka 'void (struct structure::*)()') is not allowed}} + (void)structureimp(psf); // expected-error {{functional-style cast from 'void (struct structure::*)()' to 'structureimp' (aka 'int struct structure::*') is not allowed}} +} + +// ---------------- misc ------------------ + +void crash_on_invalid_1() +{ + typedef itn Typo; // expected-error {{unknown type name 'itn'}} + (void)Typo(1); // used to crash +} diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp index 32d04e2da40b..785ea0efa401 100644 --- a/test/SemaCXX/i-c-e-cxx.cpp +++ b/test/SemaCXX/i-c-e-cxx.cpp @@ -4,3 +4,13 @@ const int c = 10; int ar[c]; + +struct X0 { + static const int value = static_cast<int>(4.0); +}; + +void f() { + if (const int value = 17) { + int array[value]; + } +} diff --git a/test/SemaCXX/illegal-member-initialization.cpp b/test/SemaCXX/illegal-member-initialization.cpp new file mode 100644 index 000000000000..2d7c73d68a3f --- /dev/null +++ b/test/SemaCXX/illegal-member-initialization.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct A { + A() : value(), cvalue() { } // expected-error {{cannot initialize the member to null in default constructor because reference member 'value' cannot be null-initialized}} \ + // expected-error {{constructor for 'struct A' must explicitly initialize the reference member 'value'}} + int &value; // expected-note{{declared at}} {{expected-note{{declared at}} + const int cvalue; +}; + +struct B { +}; + +struct X { + X() { } // expected-error {{constructor for 'struct X' must explicitly initialize the reference member 'value'}} \ + // expected-error {{constructor for 'struct X' must explicitly initialize the const member 'cvalue'}} \ + // expected-error {{constructor for 'struct X' must explicitly initialize the reference member 'b'}} \ + // expected-error {{constructor for 'struct X' must explicitly initialize the const member 'cb'}} + int &value; // expected-note{{declared at}} + const int cvalue; // expected-note{{declared at}} + B& b; // expected-note{{declared at}} + const B cb; // expected-note{{declared at}} +}; diff --git a/test/SemaCXX/incomplete-call.cpp b/test/SemaCXX/incomplete-call.cpp new file mode 100644 index 000000000000..6134189f0a9a --- /dev/null +++ b/test/SemaCXX/incomplete-call.cpp @@ -0,0 +1,38 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct A; // expected-note 13 {{forward declaration of 'struct A'}} + +A f(); // expected-note {{note: 'f' declared here}} + +struct B { + A f(); // expected-note {{'f' declared here}} + A operator()(); // expected-note 2 {{'operator()' declared here}} + operator A(); // expected-note {{'operator A' declared here}} + A operator!(); // expected-note 2 {{'operator!' declared here}} + A operator++(int); // expected-note {{'operator++' declared here}} + A operator[](int); // expected-note {{'operator[]' declared here}} + A operator+(int); // expected-note {{'operator+' declared here}} + A operator->(); // expected-note {{'operator->' declared here}} +}; + +void g() { + f(); // expected-error {{calling 'f' with incomplete return type 'struct A'}} + + typedef A (*Func)(); + Func fp; + fp(); // expected-error {{calling function with incomplete return type 'struct A'}} + ((Func)0)(); // expected-error {{calling function with incomplete return type 'struct A'}} + + B b; + b.f(); // expected-error {{calling 'f' with incomplete return type 'struct A'}} + + b.operator()(); // expected-error {{calling 'operator()' with incomplete return type 'struct A'}} + b.operator A(); // expected-error {{calling 'operator A' with incomplete return type 'struct A'}} + b.operator!(); // expected-error {{calling 'operator!' with incomplete return type 'struct A'}} + + !b; // expected-error {{calling 'operator!' with incomplete return type 'struct A'}} + b(); // expected-error {{calling 'operator()' with incomplete return type 'struct A'}} + b++; // expected-error {{calling 'operator++' with incomplete return type 'struct A'}} + b[0]; // expected-error {{calling 'operator[]' with incomplete return type 'struct A'}} + b + 1; // expected-error {{calling 'operator+' with incomplete return type 'struct A'}} + b->f(); // expected-error {{calling 'operator->' with incomplete return type 'struct A'}} +} diff --git a/test/SemaCXX/inherit.cpp b/test/SemaCXX/inherit.cpp index eaad97cc82a0..069e30d0cdfa 100644 --- a/test/SemaCXX/inherit.cpp +++ b/test/SemaCXX/inherit.cpp @@ -10,7 +10,7 @@ class B3 : virtual virtual A { }; // expected-error{{duplicate 'virtual' in base class C : public B1, private B2 { }; -class D; // expected-note {{forward declaration of 'class D'}} +class D; // expected-note {{forward declaration of 'class D'}} class E : public D { }; // expected-error{{base class has incomplete type}} diff --git a/test/SemaCXX/invalid-member-expr.cpp b/test/SemaCXX/invalid-member-expr.cpp new file mode 100644 index 000000000000..90932ed65e31 --- /dev/null +++ b/test/SemaCXX/invalid-member-expr.cpp @@ -0,0 +1,21 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class X {}; + +void test() { + X x; + + x.int; // expected-error{{expected identifier}} + x.~int(); // expected-error{{expected identifier}} + x.operator; // expected-error{{missing type specifier after 'operator'}} + x.operator typedef; // expected-error{{missing type specifier after 'operator'}} +} + +void test2() { + X *x; + + x->int; // expected-error{{expected identifier}} + x->~int(); // expected-error{{expected identifier}} + x->operator; // expected-error{{missing type specifier after 'operator'}} + x->operator typedef; // expected-error{{missing type specifier after 'operator'}} +} diff --git a/test/SemaCXX/invalid-template-specifier.cpp b/test/SemaCXX/invalid-template-specifier.cpp new file mode 100644 index 000000000000..a3f081ff60b5 --- /dev/null +++ b/test/SemaCXX/invalid-template-specifier.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc %s -verify -fsyntax-only +// PR4809 +// This test is primarily checking that this doesn't crash, not the particular +// diagnostics. + +const template basic_istream<char>; // expected-error {{expected unqualified-id}} + +namespace S {} +template <class X> class Y { + void x() { S::template y<char>(1); } // expected-error {{does not refer to a template}} \ + // expected-error {{no member named 'y'}} +}; diff --git a/test/SemaCXX/libstdcxx_is_pod_hack.cpp b/test/SemaCXX/libstdcxx_is_pod_hack.cpp new file mode 100644 index 000000000000..df064bc6a0fa --- /dev/null +++ b/test/SemaCXX/libstdcxx_is_pod_hack.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only %s + +template<typename T> +struct __is_pod { +}; + +__is_pod<int> ipi; diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp index 864953e9f9c2..b4c72f557d2a 100644 --- a/test/SemaCXX/linkage-spec.cpp +++ b/test/SemaCXX/linkage-spec.cpp @@ -25,3 +25,11 @@ extern "C" int const bar; // <rdar://problem/6895431> extern "C" struct bar d; extern struct bar e; + +extern "C++" { + namespace N0 { + struct X0 { + int foo(int x) { return x; } + }; + } +}
\ No newline at end of file diff --git a/test/SemaCXX/member-expr-static.cpp b/test/SemaCXX/member-expr-static.cpp index b6495a852041..2fa7e0781c1e 100644 --- a/test/SemaCXX/member-expr-static.cpp +++ b/test/SemaCXX/member-expr-static.cpp @@ -2,20 +2,18 @@ typedef void (*thread_continue_t)(); extern "C" { -extern void kernel_thread_start(thread_continue_t continuation); -extern void pure_c(void); + extern void kernel_thread_start(thread_continue_t continuation); + extern void pure_c(void); } -class _IOConfigThread -{ +class _IOConfigThread { public: - static void main( void ); + static void main( void ); }; -void foo( void ) -{ - kernel_thread_start(&_IOConfigThread::main); - kernel_thread_start((thread_continue_t)&_IOConfigThread::main); - kernel_thread_start(&pure_c); +void foo( void ) { + kernel_thread_start(&_IOConfigThread::main); + kernel_thread_start((thread_continue_t)&_IOConfigThread::main); + kernel_thread_start(&pure_c); } diff --git a/test/SemaCXX/member-name-lookup.cpp b/test/SemaCXX/member-name-lookup.cpp index 9fcd922ddf7d..e95641b4bf9c 100644 --- a/test/SemaCXX/member-name-lookup.cpp +++ b/test/SemaCXX/member-name-lookup.cpp @@ -146,3 +146,13 @@ struct HasAnotherMemberType : HasMemberType1, HasMemberType2 { struct UsesAmbigMemberType : HasMemberType1, HasMemberType2 { type t; // expected-error{{member 'type' found in multiple base classes of different types}} }; + +struct X0 { + struct Inner { + static const int m; + }; + + static const int n = 17; +}; + +const int X0::Inner::m = n; diff --git a/test/SemaCXX/member-operator-expr.cpp b/test/SemaCXX/member-operator-expr.cpp new file mode 100644 index 000000000000..4d0e00fd6010 --- /dev/null +++ b/test/SemaCXX/member-operator-expr.cpp @@ -0,0 +1,29 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class X { +public: + int operator++(); + operator int(); +}; + +void test() { + X x; + int i; + + i = x.operator++(); + i = x.operator int(); + x.operator--(); // expected-error{{no member named 'operator--'}} + x.operator float(); // expected-error{{no member named 'operator float'}} + x.operator; // expected-error{{missing type specifier after 'operator'}} +} + +void test2() { + X *x; + int i; + + i = x->operator++(); + i = x->operator int(); + x->operator--(); // expected-error{{no member named 'operator--'}} + x->operator float(); // expected-error{{no member named 'operator float'}} + x->operator; // expected-error{{missing type specifier after 'operator'}} +} diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp index 3b106d5576fe..d13b16e6d672 100644 --- a/test/SemaCXX/member-pointer.cpp +++ b/test/SemaCXX/member-pointer.cpp @@ -40,6 +40,14 @@ void f() { // Conversion to member of base. pdi1 = pdid; // expected-error {{incompatible type assigning 'int struct D::*', expected 'int struct A::*'}} + + // Comparisons + int (A::*pf2)(int, int); + int (D::*pf3)(int, int) = 0; + bool b1 = (pf == pf2); (void)b1; + bool b2 = (pf != pf2); (void)b2; + bool b3 = (pf == pf3); (void)b3; + bool b4 = (pf != 0); (void)b4; } struct TheBase @@ -91,7 +99,7 @@ void h() { int i = phm->*pi; (void)&(hm.*pi); (void)&(phm->*pi); - (void)&((&hm)->*pi); // expected-error {{address expression must be an lvalue or a function designator}} + (void)&((&hm)->*pi); void (HasMembers::*pf)() = &HasMembers::f; (hm.*pf)(); diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp new file mode 100644 index 000000000000..28ad9a04e790 --- /dev/null +++ b/test/SemaCXX/missing-members.cpp @@ -0,0 +1,36 @@ +// RUN: clang-cc -fsyntax-only -verify %s +namespace A { + namespace B { + class C { }; + struct S { }; + union U { }; + } +} + +void f() { + A::B::i; // expected-error {{no member named 'i' in namespace 'A::B'}} + A::B::C::i; // expected-error {{no member named 'i' in 'class A::B::C'}} + ::i; // expected-error {{no member named 'i' in the global namespace}} +} + +namespace B { + class B { }; +} + +void g() { + A::B::D::E; // expected-error {{no member named 'D' in namespace 'A::B'}} + B::B::C::D; // expected-error {{no member named 'C' in 'class B::B'}} + ::C::D; // expected-error {{no member named 'C' in the global namespace}} +} + +int A::B::i = 10; // expected-error {{no member named 'i' in namespace 'A::B'}} +int A::B::C::i = 10; // expected-error {{no member named 'i' in 'class A::B::C'}} +int A::B::S::i = 10; // expected-error {{no member named 'i' in 'struct A::B::S'}} +int A::B::U::i = 10; // expected-error {{no member named 'i' in 'union A::B::U'}} + +using A::B::D; // expected-error {{no member named 'D' in namespace 'A::B'}} + +struct S : A::B::C { + using A::B::C::f; // expected-error {{no member named 'f' in 'class A::B::C'}} + +}; diff --git a/test/SemaCXX/namespace.cpp b/test/SemaCXX/namespace.cpp index 696ea818f657..5ed6ba50ce1b 100644 --- a/test/SemaCXX/namespace.cpp +++ b/test/SemaCXX/namespace.cpp @@ -8,7 +8,8 @@ void f() { A = 0; } // expected-error {{unexpected namespace name 'A': expected int A; // expected-error {{redefinition of 'A' as different kind of symbol}} class A; // expected-error {{redefinition of 'A' as different kind of symbol}} -class B {}; // expected-note {{previous definition is here}} +class B {}; // expected-note {{previous definition is here}} \ + // FIXME: ugly expected-note{{candidate function}} void C(); // expected-note {{previous definition is here}} namespace C {} // expected-error {{redefinition of 'C' as different kind of symbol}} @@ -66,4 +67,4 @@ namespace foo { static foo::x test1; // ok -static foo::X test2; // typo: expected-error {{unknown type name 'X'}} +static foo::X test2; // typo: expected-error {{no type named 'X' in}} diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp index 8fff8a2b2cbc..5178557030b7 100644 --- a/test/SemaCXX/nested-name-spec.cpp +++ b/test/SemaCXX/nested-name-spec.cpp @@ -13,8 +13,8 @@ namespace A { } A:: ; // expected-error {{expected unqualified-id}} -::A::ax::undef ex3; // expected-error {{expected a class or namespace}} expected-error {{unknown type name 'undef'}} -A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}} expected-error {{unknown type name 'undef2'}} +::A::ax::undef ex3; // expected-error {{no member named}} +A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}} int A::C::Ag1() { return 0; } @@ -35,9 +35,9 @@ class C2 { int x; }; -void C2::m() const { } // expected-error{{out-of-line definition does not match any declaration in 'C2'}} +void C2::m() const { } // expected-error{{out-of-line definition of 'm' does not match any declaration in 'class C2'}} -void C2::f(int) { } // expected-error{{out-of-line definition does not match any declaration in 'C2'}} +void C2::f(int) { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'class C2'}} void C2::m() { x = 0; @@ -125,7 +125,7 @@ class Operators { operator bool(); }; -Operators Operators::operator+(const Operators&) { // expected-error{{out-of-line definition does not match any declaration in 'Operators'}} +Operators Operators::operator+(const Operators&) { // expected-error{{out-of-line definition of 'operator+' does not match any declaration in 'class Operators'}} Operators ops; return ops; } @@ -143,13 +143,13 @@ namespace A { void g(int&); // expected-note{{member declaration nearly matches}} } -void A::f() {} // expected-error{{out-of-line definition does not match any declaration in 'A'}} +void A::f() {} // expected-error{{out-of-line definition of 'f' does not match any declaration in namespace 'A'}} -void A::g(const int&) { } // expected-error{{out-of-line definition does not match any declaration in 'A'}} +void A::g(const int&) { } // expected-error{{out-of-line definition of 'g' does not match any declaration in namespace 'A'}} struct Struct { }; -void Struct::f() { } // expected-error{{out-of-line definition does not match any declaration in 'Struct'}} +void Struct::f() { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'struct Struct'}} void global_func(int); void global_func2(int); @@ -166,13 +166,16 @@ void N::f() { } // okay struct Y; // expected-note{{forward declaration of 'struct Y'}} Y::foo y; // expected-error{{incomplete type 'struct Y' named in nested name specifier}} \ - // expected-error{{unknown type name 'foo'}} + // expected-error{{no type named 'foo' in}} X::X() : a(5) { } // expected-error{{use of undeclared identifier 'X'}} \ // expected-error{{C++ requires a type specifier for all declarations}} \ // expected-error{{only constructors take base initializers}} - +struct foo_S { + static bool value; +}; +bool (foo_S::value); namespace somens { diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp index f890bf56e36b..c67a3f653900 100644 --- a/test/SemaCXX/new-delete.cpp +++ b/test/SemaCXX/new-delete.cpp @@ -38,10 +38,11 @@ void good_news() ia4 *pai = new (int[3][4]); pi = ::new int; U *pu = new (ps) U; - // FIXME: Inherited functions are not looked up currently. - //V *pv = new (ps) V; + V *pv = new (ps) V; pi = new (S(1.0f, 2)) int; + + (void)new int[true]; } struct abstract { @@ -95,3 +96,43 @@ void bad_deletes() delete (T*)0; // expected-warning {{deleting pointer to incomplete type}} ::S::delete (int*)0; // expected-error {{expected unqualified-id}} } + +struct X0 { }; + +struct X1 { + operator int*(); + operator float(); +}; + +struct X2 { + operator int*(); // expected-note {{candidate function}} + operator float*(); // expected-note {{candidate function}} +}; + +void test_delete_conv(X0 x0, X1 x1, X2 x2) { + delete x0; // expected-error{{cannot delete}} + delete x1; + delete x2; // expected-error{{ambiguous conversion of delete expression of type 'struct X2' to a pointer}} +} + +// PR4782 +class X3 { +public: + static void operator delete(void * mem, unsigned long size); +}; + +class X4 { +public: + static void release(X3 *x); + static void operator delete(void * mem, unsigned long size); +}; + + +void X4::release(X3 *x) { + delete x; +} + +class X5 { +public: + void Destroy() const { delete this; } +}; diff --git a/test/SemaCXX/overload-value-dep-arg.cpp b/test/SemaCXX/overload-value-dep-arg.cpp new file mode 100644 index 000000000000..1e94d5a30136 --- /dev/null +++ b/test/SemaCXX/overload-value-dep-arg.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class C { + C(void*); +}; + +int f(const C&); +int f(unsigned long); + +template<typename T> int f(const T* t) { + return f(reinterpret_cast<unsigned long>(t)); +} + diff --git a/test/SemaCXX/overloaded-builtin-operators.cpp b/test/SemaCXX/overloaded-builtin-operators.cpp index 2a6c24a6778a..0284b2929b3c 100644 --- a/test/SemaCXX/overloaded-builtin-operators.cpp +++ b/test/SemaCXX/overloaded-builtin-operators.cpp @@ -20,11 +20,21 @@ struct Enum2 { operator E2(); }; + +struct X { + void f(); +}; + +typedef void (X::*pmf)(); +struct Xpmf { + operator pmf(); +}; + yes& islong(long); yes& islong(unsigned long); // FIXME: shouldn't be needed no& islong(int); -void f(Short s, Long l, Enum1 e1, Enum2 e2) { +void f(Short s, Long l, Enum1 e1, Enum2 e2, Xpmf pmf) { // C++ [over.built]p8 int i1 = +e1; int i2 = -e2; @@ -37,6 +47,10 @@ void f(Short s, Long l, Enum1 e1, Enum2 e2) { (void)static_cast<yes&>(islong(s + l)); (void)static_cast<no&>(islong(s + s)); + // C++ [over.built]p16 + (void)(pmf == &X::f); + (void)(pmf == 0); + // C++ [over.built]p17 (void)static_cast<yes&>(islong(s % l)); (void)static_cast<yes&>(islong(l << s)); @@ -45,7 +59,7 @@ void f(Short s, Long l, Enum1 e1, Enum2 e2) { // FIXME: should pass (void)static_cast<no&>(islong(e1 % e2)); } -struct ShortRef { +struct ShortRef { // expected-note{{candidate function}} operator short&(); }; @@ -53,7 +67,15 @@ struct LongRef { operator volatile long&(); }; -void g(ShortRef sr, LongRef lr) { +struct XpmfRef { // expected-note{{candidate function}} + operator pmf&(); +}; + +struct E2Ref { + operator E2&(); +}; + +void g(ShortRef sr, LongRef lr, E2Ref e2_ref, XpmfRef pmf_ref) { // C++ [over.built]p3 short s1 = sr++; @@ -64,6 +86,14 @@ void g(ShortRef sr, LongRef lr) { short& sr1 = (sr *= lr); volatile long& lr1 = (lr *= sr); + // C++ [over.built]p20: + E2 e2r2; + e2r2 = e2_ref; + + pmf &pmr = (pmf_ref = &X::f); // expected-error{{no viable overloaded '='}} + pmf pmr2; + pmr2 = pmf_ref; + // C++ [over.built]p22 short& sr2 = (sr %= lr); volatile long& lr2 = (lr <<= sr); diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp index 916d753a3ff5..8f71ad538138 100644 --- a/test/SemaCXX/overloaded-operator.cpp +++ b/test/SemaCXX/overloaded-operator.cpp @@ -28,12 +28,12 @@ void g(Y y, Z z) { } struct A { - bool operator==(Z&); // expected-note{{candidate function}} + bool operator==(Z&); // expected-note 2{{candidate function}} }; A make_A(); -bool operator==(A&, Z&); // expected-note{{candidate function}} +bool operator==(A&, Z&); // expected-note 2{{candidate function}} void h(A a, const A ac, Z z) { make_A() == z; @@ -155,7 +155,7 @@ typedef INTREF Func1(FLOAT, double); typedef float& Func2(int, double); struct ConvertToFunc { - operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} + operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(float, double)'}} operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}} void operator()(); }; @@ -209,3 +209,34 @@ namespace M { (void)(x + x); } } + +struct AA { bool operator!=(AA&); }; +struct BB : AA {}; +bool x(BB y, BB z) { return y != z; } + + +struct AX { + AX& operator ->(); // expected-note {{declared at}} + int b; +}; + +void m() { + AX a; + a->b = 0; // expected-error {{circular pointer delegation detected}} +} + +struct CircA { + struct CircB& operator->(); // expected-note {{declared at}} + int val; +}; +struct CircB { + struct CircC& operator->(); // expected-note {{declared at}} +}; +struct CircC { + struct CircA& operator->(); // expected-note {{declared at}} +}; + +void circ() { + CircA a; + a->val = 0; // expected-error {{circular pointer delegation detected}} +} diff --git a/test/SemaCXX/primary-base.cpp b/test/SemaCXX/primary-base.cpp new file mode 100644 index 000000000000..62f9087bd91d --- /dev/null +++ b/test/SemaCXX/primary-base.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc -fsyntax-only -verify %s +class A { virtual void f(); }; +class B : virtual A { }; + +class C : B { }; + +// Since A is already a primary base class, C should be the primary base class of F. +class F : virtual A, virtual C { }; + +int sa[sizeof(F) == sizeof(A) ? 1 : -1]; + diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp new file mode 100644 index 000000000000..1f05e81df530 --- /dev/null +++ b/test/SemaCXX/pseudo-destructors.cpp @@ -0,0 +1,40 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct A {}; + +enum Foo { F }; +typedef Foo Bar; + +typedef int Integer; + +void g(); + +namespace N { + typedef Foo Wibble; +} + +void f(A* a, Foo *f, int *i) { + a->~A(); + a->A::~A(); + + a->~foo(); // expected-error{{identifier 'foo' in pseudo-destructor expression does not name a type}} + + // FIXME: the type printed below isn't wonderful + a->~Bar(); // expected-error{{no member named}} + + f->~Bar(); + f->~Foo(); + i->~Bar(); // expected-error{{does not match}} + + g().~Bar(); // expected-error{{non-scalar}} + + f->::~Bar(); + f->N::~Wibble(); + + f->::~Bar(17, 42); // expected-error{{cannot have any arguments}} +} + +typedef int Integer; + +void destroy_without_call(int *ip) { + ip->~Integer; // expected-error{{called immediately}} +}
\ No newline at end of file diff --git a/test/SemaCXX/qual-id-test.cpp b/test/SemaCXX/qual-id-test.cpp new file mode 100644 index 000000000000..ecb6aa9b3592 --- /dev/null +++ b/test/SemaCXX/qual-id-test.cpp @@ -0,0 +1,140 @@ +// RUN: clang-cc -fsyntax-only -verify %s +namespace A +{ + namespace B + { + struct base // expected-note{{object type}} + { + void x() {} + void y() {} + }; + } + + struct member + { + void foo(); + }; + + struct middleman + { + member * operator->() { return 0; } + }; + + struct sub : B::base + { + void x() {} + middleman operator->() { return middleman(); } + }; +} + +struct bad +{ + int x(); +}; + +namespace C +{ + void fun() + { + A::sub a; + + a.x(); + + a.sub::x(); + a.base::x(); + + a.B::base::x(); // expected-error{{use of undeclared identifier 'B'}} + + a.A::sub::x(); + a.A::B::base::x(); + + a.bad::x(); // expected-error{{type 'struct bad' is not a direct or virtual base of ''struct A::sub''}} + + a->foo(); + a->member::foo(); + a->A::member::foo(); + } + + void fun2() + { + A::sub *a; + + a->x(); + + a->sub::x(); + a->base::x(); + + a->B::base::x(); // expected-error{{use of undeclared identifier 'B'}} + + a->A::sub::x(); + a->A::B::base::x(); + + a->bad::x(); // expected-error{{type 'struct bad' is not a direct or virtual base of ''struct A::sub''}} + + (*a)->foo(); + (*a)->member::foo(); + (*a)->A::member::foo(); + } + + void fun3() + { + int i; + i.foo(); // expected-error{{member reference base type 'int' is not a structure or union}} + } + + void fun4a() { + A::sub *a; + + typedef A::member base; // expected-note{{current scope}} + a->base::x(); // expected-error{{ambiguous}} + } + + void fun4b() { + A::sub *a; + + typedef A::B::base base; + a->base::x(); + } + + template<typename T> + void fun5() + { + T a; + a.x(); + a->foo(); + + a.A::sub::x(); + a.A::B::base::x(); + a->A::member::foo(); + + a.bad::x(); // expected-error{{direct or virtual}} + } + + void test_fun5() { + fun5<A::sub>(); // expected-note{{instantiation}} + } + + template<typename T> + void fun6() { + T a; + a.sub::x(); + a.base::x(); + a->member::foo(); + a.B::base::x(); // expected-error{{use of undeclared identifier 'B'}} + } + + void test_fun6() { + fun6<A::sub>(); // expected-note{{instantiation}} + } + +} + +// PR4703 +struct a { + int a; + static int sa; +}; + +a a; + +int a::sa = a.a; diff --git a/test/SemaCXX/ref-init-ambiguous.cpp b/test/SemaCXX/ref-init-ambiguous.cpp new file mode 100644 index 000000000000..dda1ead7b622 --- /dev/null +++ b/test/SemaCXX/ref-init-ambiguous.cpp @@ -0,0 +1,28 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +enum E2 { }; + +struct A { + operator E2&(); // expected-note 3 {{candidate function}} +}; + +struct B { + operator E2&(); // expected-note 3 {{candidate function}} +}; + +struct C : B, A { +}; + +void test(C c) { + const E2 &e2 = c; // expected-error {{reference initialization of type 'enum E2 const &' with initializer of type 'struct C' is ambiguous}} +} + +void foo(const E2 &); + +const E2 & re(C c) { + foo(c); // expected-error {{reference initialization of type 'enum E2 const &' with initializer of type 'struct C' is ambiguous}} + + return c; // expected-error {{reference initialization of type 'enum E2 const &' with initializer of type 'struct C' is ambiguous}} +} + + diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp index 9067a8661d7c..e03abf4300a3 100644 --- a/test/SemaCXX/references.cpp +++ b/test/SemaCXX/references.cpp @@ -87,3 +87,18 @@ void test8(int& const,// expected-error{{'const' qualifier may not be applied to typedef intref const intref_c; // okay. FIXME: how do we verify that this is the same type as intref? } + + +class string { + char *Data; + unsigned Length; +public: + string(); + ~string(); +}; + +string getInput(); + +void test9() { + string &s = getInput(); // expected-error{{lvalue reference}} +} diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp new file mode 100644 index 000000000000..03b0ddb87965 --- /dev/null +++ b/test/SemaCXX/return.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc %s -fsyntax-only -verify + +int test1() { + throw; +} + +// PR5071 +template<typename T> T f() { } + +template<typename T> +void g(T t) { + return t * 2; // okay +} + +template<typename T> +T h() { + return 17; +} diff --git a/test/SemaCXX/static-array-member.cpp b/test/SemaCXX/static-array-member.cpp new file mode 100644 index 000000000000..dac70cd2eabf --- /dev/null +++ b/test/SemaCXX/static-array-member.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only %s + +struct X0 { + static int array[]; + + int x; + int y; +}; + +int X0::array[sizeof(X0) * 2]; + +template<typename T, int N> +struct X1 { + static T array[]; +}; + +template<typename T, int N> +T X1<T, N>::array[N]; diff --git a/test/SemaCXX/static-cast-complete-type.cpp b/test/SemaCXX/static-cast-complete-type.cpp new file mode 100644 index 000000000000..83583a5adf8e --- /dev/null +++ b/test/SemaCXX/static-cast-complete-type.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<typename T> struct S { + S(int); +}; + +struct T; // expected-note{{forward declaration of 'struct T'}} + +void f() { + S<int> s0 = static_cast<S<int> >(0); + S<void*> s1 = static_cast<S<void*> >(00); + + (void)static_cast<T>(10); // expected-error{{'struct T' is an incomplete type}} +} diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp index b5c515d5e161..8db8e33b93ce 100644 --- a/test/SemaCXX/static-cast.cpp +++ b/test/SemaCXX/static-cast.cpp @@ -1,11 +1,11 @@ -// RUN: clang-cc -fsyntax-only -verify %s +// RUN: clang-cc -fsyntax-only -verify -faccess-control %s struct A {}; struct B : public A {}; // Single public base. struct C1 : public virtual B {}; // Single virtual base. struct C2 : public virtual B {}; struct D : public C1, public C2 {}; // Diamond -struct E : private A {}; // Single private base. +struct E : private A {}; // Single private base. expected-note 2 {{'private' inheritance specifier here}} struct F : public C1 {}; // Single path to B with virtual. struct G1 : public B {}; struct G2 : public B {}; @@ -14,6 +14,11 @@ struct H : public G1, public G2 {}; // Ambiguous path to B. enum Enum { En1, En2 }; enum Onom { On1, On2 }; +struct Co1 { operator int(); }; +struct Co2 { Co2(int); }; +struct Co3 { }; +struct Co4 { Co4(Co3); operator Co3(); }; + // Explicit implicits void t_529_2() { @@ -45,7 +50,9 @@ void t_529_2() (void)static_cast<int B::*>((int A::*)0); (void)static_cast<void (B::*)()>((void (A::*)())0); - // TODO: User-defined conversions + (void)static_cast<int>(Co1()); + (void)static_cast<Co2>(1); + (void)static_cast<Co3>(static_cast<Co4>(Co3())); // Bad code below @@ -80,11 +87,10 @@ void t_529_5_8() (void)static_cast<D&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct D &' via virtual base 'struct B'}} (void)static_cast<B*>((const A*)0); // expected-error {{static_cast from 'struct A const *' to 'struct B *' casts away constness}} (void)static_cast<B&>(*((const A*)0)); // expected-error {{static_cast from 'struct A const' to 'struct B &' casts away constness}} - // Accessibility is not yet tested - //(void)static_cast<E*>((A*)0); // {{static_cast from 'struct A *' to 'struct E *' is not allowed}} - //(void)static_cast<E&>(*((A*)0)); // {{static_cast from 'struct A' to 'struct E &' is not allowed}} - (void)static_cast<H*>((A*)0); // expected-error {{ambiguous static_cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} - (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous static_cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + (void)static_cast<E*>((A*)0); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}} + (void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}} + (void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'struct B *' to 'struct E *' is not allowed}} (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'struct E' cannot be initialized with a value of type 'struct B'}} diff --git a/test/SemaCXX/static-initializers.cpp b/test/SemaCXX/static-initializers.cpp index 3d92a532ae1a..a651243df7ef 100644 --- a/test/SemaCXX/static-initializers.cpp +++ b/test/SemaCXX/static-initializers.cpp @@ -1,12 +1,10 @@ // RUN: clang-cc -fsyntax-only -verify %s -int f() -{ - return 10; +int f() { + return 10; } -void g() -{ - static int a = f(); +void g() { + static int a = f(); } static int b = f(); diff --git a/test/SemaCXX/type-traits-incomplete.cpp b/test/SemaCXX/type-traits-incomplete.cpp new file mode 100644 index 000000000000..ac8ec452b93f --- /dev/null +++ b/test/SemaCXX/type-traits-incomplete.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct S; // expected-note{{forward declaration of 'struct S'}} + +void f() { + __is_pod(S); // expected-error{{incomplete type 'struct S' used in type trait expression}} +} diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index 1a2e329b2a44..340c0ae4899b 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -7,14 +7,23 @@ struct NonPOD { NonPOD(int); }; // PODs enum Enum { EV }; struct POD { Enum e; int i; float f; NonPOD* p; }; +struct Empty {}; +typedef Empty EmptyAr[10]; typedef int Int; typedef Int IntAr[10]; class Statics { static int priv; static NonPOD np; }; +union EmptyUnion {}; +union Union { int i; float f; }; +struct HasFunc { void f (); }; +struct HasOp { void operator *(); }; +struct HasConv { operator int(); }; +struct HasAssign { void operator =(int); }; // Not PODs struct Derives : POD {}; +struct DerivesEmpty : Empty {}; struct HasCons { HasCons(int); }; -struct HasAssign { HasAssign operator =(const HasAssign&); }; +struct HasCopyAssign { HasCopyAssign operator =(const HasCopyAssign&); }; struct HasDest { ~HasDest(); }; class HasPriv { int priv; }; class HasProt { protected: int prot; }; @@ -22,6 +31,8 @@ struct HasRef { int i; int& ref; HasRef() : i(0), ref(i) {} }; struct HasNonPOD { NonPOD np; }; struct HasVirt { virtual void Virt() {}; }; typedef Derives NonPODAr[10]; +typedef HasVirt VirtAr[10]; +union NonPODUnion { int i; Derives n; }; void is_pod() { @@ -31,10 +42,17 @@ void is_pod() int t04[T(__is_pod(Int))]; int t05[T(__is_pod(IntAr))]; int t06[T(__is_pod(Statics))]; + int t07[T(__is_pod(Empty))]; + int t08[T(__is_pod(EmptyUnion))]; + int t09[T(__is_pod(Union))]; + int t10[T(__is_pod(HasFunc))]; + int t11[T(__is_pod(HasOp))]; + int t12[T(__is_pod(HasConv))]; + int t13[T(__is_pod(HasAssign))]; int t21[F(__is_pod(Derives))]; int t22[F(__is_pod(HasCons))]; - int t23[F(__is_pod(HasAssign))]; + int t23[F(__is_pod(HasCopyAssign))]; int t24[F(__is_pod(HasDest))]; int t25[F(__is_pod(HasPriv))]; int t26[F(__is_pod(HasProt))]; @@ -42,9 +60,40 @@ void is_pod() int t28[F(__is_pod(HasNonPOD))]; int t29[F(__is_pod(HasVirt))]; int t30[F(__is_pod(NonPODAr))]; + int t31[F(__is_pod(DerivesEmpty))]; + // int t32[F(__is_pod(NonPODUnion))]; +} + +typedef Empty EmptyAr[10]; +struct Bit0 { int : 0; }; +struct Bit0Cons { int : 0; Bit0Cons(); }; +struct BitOnly { int x : 3; }; +//struct DerivesVirt : virtual POD {}; + +void is_empty() +{ + int t01[T(__is_empty(Empty))]; + int t02[T(__is_empty(DerivesEmpty))]; + int t03[T(__is_empty(HasCons))]; + int t04[T(__is_empty(HasCopyAssign))]; + int t05[T(__is_empty(HasDest))]; + int t06[T(__is_empty(HasFunc))]; + int t07[T(__is_empty(HasOp))]; + int t08[T(__is_empty(HasConv))]; + int t09[T(__is_empty(HasAssign))]; + int t10[T(__is_empty(Bit0))]; + int t11[T(__is_empty(Bit0Cons))]; + + int t21[F(__is_empty(Int))]; + int t22[F(__is_empty(POD))]; + int t23[F(__is_empty(EmptyUnion))]; + int t24[F(__is_empty(EmptyAr))]; + int t25[F(__is_empty(HasRef))]; + int t26[F(__is_empty(HasVirt))]; + int t27[F(__is_empty(BitOnly))]; +// int t27[F(__is_empty(DerivesVirt))]; } -union Union { int i; float f; }; typedef Derives ClassType; void is_class() @@ -92,7 +141,7 @@ void is_enum() int t17[F(__is_enum(ClassType))]; } -struct Polymorph { virtual void f(); }; +typedef HasVirt Polymorph; struct InheritPolymorph : Polymorph {}; void is_polymorphic() @@ -109,3 +158,95 @@ void is_polymorphic() int t17[F(__is_polymorphic(ClassType))]; int t18[F(__is_polymorphic(Enum))]; } + +typedef Int& IntRef; +typedef const IntAr ConstIntAr; +typedef ConstIntAr ConstIntArAr[4]; + +struct HasCopy { + HasCopy(HasCopy& cp); +}; + +void has_trivial_default_constructor() { + int t01[T(__has_trivial_constructor(Int))]; + int t02[T(__has_trivial_constructor(IntAr))]; + int t03[T(__has_trivial_constructor(Union))]; + int t04[T(__has_trivial_constructor(UnionAr))]; + int t05[T(__has_trivial_constructor(POD))]; + int t06[T(__has_trivial_constructor(Derives))]; + int t07[T(__has_trivial_constructor(ConstIntAr))]; + int t08[T(__has_trivial_constructor(ConstIntArAr))]; + int t09[T(__has_trivial_constructor(HasDest))]; + int t10[T(__has_trivial_constructor(HasPriv))]; + int t11[F(__has_trivial_constructor(HasCons))]; + int t12[F(__has_trivial_constructor(HasRef))]; + int t13[F(__has_trivial_constructor(HasCopy))]; + int t14[F(__has_trivial_constructor(IntRef))]; + int t15[T(__has_trivial_constructor(HasCopyAssign))]; + int t16[T(__has_trivial_constructor(const Int))]; + int t17[T(__has_trivial_constructor(NonPODAr))]; + int t18[F(__has_trivial_constructor(VirtAr))]; +} + +void has_trivial_copy_constructor() { + int t01[T(__has_trivial_copy(Int))]; + int t02[T(__has_trivial_copy(IntAr))]; + int t03[T(__has_trivial_copy(Union))]; + int t04[T(__has_trivial_copy(UnionAr))]; + int t05[T(__has_trivial_copy(POD))]; + int t06[T(__has_trivial_copy(Derives))]; + int t07[T(__has_trivial_copy(ConstIntAr))]; + int t08[T(__has_trivial_copy(ConstIntArAr))]; + int t09[T(__has_trivial_copy(HasDest))]; + int t10[T(__has_trivial_copy(HasPriv))]; + int t11[T(__has_trivial_copy(HasCons))]; + int t12[T(__has_trivial_copy(HasRef))]; + int t13[F(__has_trivial_copy(HasCopy))]; + int t14[T(__has_trivial_copy(IntRef))]; + int t15[T(__has_trivial_copy(HasCopyAssign))]; + int t16[T(__has_trivial_copy(const Int))]; + int t17[F(__has_trivial_copy(NonPODAr))]; + int t18[F(__has_trivial_copy(VirtAr))]; +} + +void has_trivial_copy_assignment() { + int t01[T(__has_trivial_assign(Int))]; + int t02[T(__has_trivial_assign(IntAr))]; + int t03[T(__has_trivial_assign(Union))]; + int t04[T(__has_trivial_assign(UnionAr))]; + int t05[T(__has_trivial_assign(POD))]; + int t06[T(__has_trivial_assign(Derives))]; + int t07[F(__has_trivial_assign(ConstIntAr))]; + int t08[F(__has_trivial_assign(ConstIntArAr))]; + int t09[T(__has_trivial_assign(HasDest))]; + int t10[T(__has_trivial_assign(HasPriv))]; + int t11[T(__has_trivial_assign(HasCons))]; + int t12[T(__has_trivial_assign(HasRef))]; + int t13[T(__has_trivial_assign(HasCopy))]; + int t14[F(__has_trivial_assign(IntRef))]; + int t15[F(__has_trivial_assign(HasCopyAssign))]; + int t16[F(__has_trivial_assign(const Int))]; + int t17[F(__has_trivial_assign(NonPODAr))]; + int t18[F(__has_trivial_assign(VirtAr))]; +} + +void has_trivial_destructor() { + int t01[T(__has_trivial_destructor(Int))]; + int t02[T(__has_trivial_destructor(IntAr))]; + int t03[T(__has_trivial_destructor(Union))]; + int t04[T(__has_trivial_destructor(UnionAr))]; + int t05[T(__has_trivial_destructor(POD))]; + int t06[T(__has_trivial_destructor(Derives))]; + int t07[T(__has_trivial_destructor(ConstIntAr))]; + int t08[T(__has_trivial_destructor(ConstIntArAr))]; + int t09[F(__has_trivial_destructor(HasDest))]; + int t10[T(__has_trivial_destructor(HasPriv))]; + int t11[T(__has_trivial_destructor(HasCons))]; + int t12[T(__has_trivial_destructor(HasRef))]; + int t13[T(__has_trivial_destructor(HasCopy))]; + int t14[T(__has_trivial_destructor(IntRef))]; + int t15[T(__has_trivial_destructor(HasCopyAssign))]; + int t16[T(__has_trivial_destructor(const Int))]; + int t17[T(__has_trivial_destructor(NonPODAr))]; + int t18[T(__has_trivial_destructor(VirtAr))]; +} diff --git a/test/SemaCXX/unknown-type-name.cpp b/test/SemaCXX/unknown-type-name.cpp new file mode 100644 index 000000000000..054212951338 --- /dev/null +++ b/test/SemaCXX/unknown-type-name.cpp @@ -0,0 +1,29 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// PR3990 +namespace N { + struct Wibble { + }; + + typedef Wibble foo; +} +using namespace N; + +foo::bar x; // expected-error{{no type named 'bar' in 'struct N::Wibble'}} + +void f() { + foo::bar = 4; // expected-error{{no member named 'bar' in 'struct N::Wibble'}} +} + +template<typename T> +struct A { + typedef T type; + + type f(); +}; + +template<typename T> +A<T>::type g(T t) { return t; } // expected-error{{missing 'typename'}} + +template<typename T> +A<T>::type A<T>::f() { return type(); } // expected-error{{missing 'typename'}} diff --git a/test/SemaCXX/unreachable-catch-clauses.cpp b/test/SemaCXX/unreachable-catch-clauses.cpp new file mode 100644 index 000000000000..c8b642e7ab53 --- /dev/null +++ b/test/SemaCXX/unreachable-catch-clauses.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class BaseEx {}; +class Ex1: public BaseEx {}; +typedef Ex1 Ex2; + +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}} + diff --git a/test/SemaCXX/using-decl-1.cpp b/test/SemaCXX/using-decl-1.cpp index 2459f251deb2..37e101e221ea 100644 --- a/test/SemaCXX/using-decl-1.cpp +++ b/test/SemaCXX/using-decl-1.cpp @@ -6,3 +6,14 @@ namespace std { using ::f; inline void f() { return f(true); } } + +namespace M { + void f(float); +} + +namespace N { + using M::f; + void f(int) { } // expected-note{{previous}} + + void f(int) { } // expected-error{{redefinition}} +} diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp new file mode 100644 index 000000000000..1a53704c1e68 --- /dev/null +++ b/test/SemaCXX/using-decl-templates.cpp @@ -0,0 +1,36 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> struct A { + void f() { } + struct N { }; +}; + +template<typename T> struct B : A<T> { + using A<T>::f; + using A<T>::N; + + using A<T>::foo; // expected-error{{no member named 'foo'}} + using A<double>::f; // expected-error{{using declaration refers into 'A<double>::', which is not a base class of 'B'}} +}; + +B<int> a; // expected-note{{in instantiation of template class 'struct B<int>' requested here}} + +template<typename T> struct C : A<T> { + using A<T>::f; + + void f() { }; +}; + +template <typename T> struct D : A<T> { + using A<T>::f; + + void f(); +}; + +template<typename T> void D<T>::f() { } + +template<typename T> struct E : A<T> { + using A<T>::f; + + void g() { f(); } +}; diff --git a/test/SemaCXX/value-dependent-exprs.cpp b/test/SemaCXX/value-dependent-exprs.cpp new file mode 100644 index 000000000000..c70f895d2bf9 --- /dev/null +++ b/test/SemaCXX/value-dependent-exprs.cpp @@ -0,0 +1,47 @@ +// RUN: clang-cc -verify %s + +template <unsigned I> +class C0 { + static const int iv0 = 1 << I; + + enum { + A = I, + B = I + 1 + }; + + struct s0 { + int a : I; + int b[I]; + }; + + // FIXME: I'm unclear where the right place to handle this is. +#if 0 + void f0(int *p) { + if (p == I) { + } + } +#endif + +#if 0 + // FIXME: Not sure whether we care about these. + void f1(int *a) + __attribute__((nonnull(1 + I))) + __attribute__((constructor(1 + I))) + __attribute__((destructor(1 + I))) + __attribute__((sentinel(1 + I, 2 + I))), + __attribute__((reqd_work_group_size(1 + I, 2 + I, 3 + I))), + __attribute__((format_arg(1 + I))), + __attribute__((aligned(1 + I))), + __attribute__((regparm(1 + I))); + + typedef int int_a0 __attribute__((address_space(1 + B))); +#endif + +#if 0 + // FIXME: This doesn't work. PR4996. + int f2() { + return __builtin_choose_expr(I, 1, 2); + } +#endif + +}; diff --git a/test/SemaCXX/vararg-non-pod.cpp b/test/SemaCXX/vararg-non-pod.cpp index 1c5fe74a154d..390f58b1b7b3 100644 --- a/test/SemaCXX/vararg-non-pod.cpp +++ b/test/SemaCXX/vararg-non-pod.cpp @@ -51,6 +51,18 @@ void t4() D d; - d(10, c); // expected-warning{{Line 48: cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}} + d(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}} d(10, version); } + +class E { + E(int, ...); +}; + +void t5() +{ + C c(10); + + E e(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic constructor; call will abort at runtime}} + (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic constructor; call will abort at runtime}} +}
\ No newline at end of file diff --git a/test/SemaCXX/vector-casts.cpp b/test/SemaCXX/vector-casts.cpp new file mode 100644 index 000000000000..5b08043545fa --- /dev/null +++ b/test/SemaCXX/vector-casts.cpp @@ -0,0 +1,40 @@ +// RUN: clang-cc -fsyntax-only -verify %s +typedef int __v2si __attribute__((__vector_size__(8))); +typedef short __v4hi __attribute__((__vector_size__(8))); +typedef short __v8hi __attribute__((__vector_size__(16))); + +struct S { }; + +void f() { + __v2si v2si; + __v4hi v4hi; + __v8hi v8hi; + unsigned long long ll; + unsigned char c; + S s; + + (void)reinterpret_cast<__v2si>(v4hi); + (void)(__v2si)v4hi; + (void)reinterpret_cast<__v4hi>(v2si); + (void)(__v4hi)v2si; + (void)reinterpret_cast<unsigned long long>(v2si); + (void)(unsigned long long)v2si; + (void)reinterpret_cast<__v2si>(ll); + (void)(__v2si)(ll); + + (void)reinterpret_cast<S>(v2si); // expected-error {{reinterpret_cast from '__v2si' to 'struct S' is not allowed}} + (void)(S)v2si; // expected-error {{C-style cast from '__v2si' to 'struct S' is not allowed}} + (void)reinterpret_cast<__v2si>(s); // expected-error {{reinterpret_cast from 'struct S' to '__v2si' is not allowed}} + (void)(__v2si)s; // expected-error {{C-style cast from 'struct S' to '__v2si' is not allowed}} + + (void)reinterpret_cast<unsigned char>(v2si); // expected-error {{reinterpret_cast from vector '__v2si' to scalar 'unsigned char' of different size}} + (void)(unsigned char)v2si; // expected-error {{C-style cast from vector '__v2si' to scalar 'unsigned char' of different size}} + (void)reinterpret_cast<__v2si>(c); // expected-error {{reinterpret_cast from scalar 'unsigned char' to vector '__v2si' of different size}} + + (void)reinterpret_cast<__v8hi>(v4hi); // expected-error {{reinterpret_cast from vector '__v4hi' to vector '__v8hi' of different size}} + (void)(__v8hi)v4hi; // expected-error {{C-style cast from vector '__v4hi' to vector '__v8hi' of different size}} + (void)reinterpret_cast<__v4hi>(v8hi); // expected-error {{reinterpret_cast from vector '__v8hi' to vector '__v4hi' of different size}} + (void)(__v4hi)v8hi; // expected-error {{C-style cast from vector '__v8hi' to vector '__v4hi' of different size}} +} + + diff --git a/test/SemaCXX/warn-assignment-condition.cpp b/test/SemaCXX/warn-assignment-condition.cpp new file mode 100644 index 000000000000..3b9f3066a16b --- /dev/null +++ b/test/SemaCXX/warn-assignment-condition.cpp @@ -0,0 +1,65 @@ +// RUN: clang-cc -fsyntax-only -Wparentheses -verify %s + +struct A { + int foo(); + friend A operator+(const A&, const A&); + operator bool(); +}; + +void test() { + int x, *p; + A a, b; + + // With scalars. + if (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + if ((x = 7)) {} + do { + } while (x = 7); // expected-warning {{using the result of an assignment as a condition without parentheses}} + do { + } while ((x = 7)); + while (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + while ((x = 7)) {} + for (; x = 7; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + for (; (x = 7); ) {} + + if (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + if ((p = p)) {} + do { + } while (p = p); // expected-warning {{using the result of an assignment as a condition without parentheses}} + do { + } while ((p = p)); + while (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + while ((p = p)) {} + for (; p = p; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + for (; (p = p); ) {} + + // Initializing variables (shouldn't warn). + if (int y = x) {} + while (int y = x) {} + if (A y = a) {} + while (A y = a) {} + + // With temporaries. + if (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + if ((x = (b+b).foo())) {} + do { + } while (x = (b+b).foo()); // expected-warning {{using the result of an assignment as a condition without parentheses}} + do { + } while ((x = (b+b).foo())); + while (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + while ((x = (b+b).foo())) {} + for (; x = (b+b).foo(); ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + for (; (x = (b+b).foo()); ) {} + + // With a user-defined operator. + if (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + if ((a = b + b)) {} + do { + } while (a = b + b); // expected-warning {{using the result of an assignment as a condition without parentheses}} + do { + } while ((a = b + b)); + while (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + while ((a = b + b)) {} + for (; a = b + b; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + for (; (a = b + b); ) {} +} diff --git a/test/SemaCXX/warn-char-subscripts.cpp b/test/SemaCXX/warn-char-subscripts.cpp new file mode 100644 index 000000000000..1c06db91c3f7 --- /dev/null +++ b/test/SemaCXX/warn-char-subscripts.cpp @@ -0,0 +1,21 @@ +// RUN: clang-cc -Wchar-subscripts -fsyntax-only -verify %s + +template<typename T> +void t1() { + int array[1] = { 0 }; + T subscript = 0; + int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}} +} + +template<typename T> +void t2() { + int array[1] = { 0 }; + T subscript = 0; + int val = subscript[array]; // expected-warning{{array subscript is of type 'char'}} +} + +void test() { + t1<char>(); // expected-note {{in instantiation of function template specialization 't1<char>' requested here}} + t2<char>(); // expected-note {{in instantiation of function template specialization 't2<char>' requested here}} +} + diff --git a/test/SemaCXX/warn-for-var-in-else.cpp b/test/SemaCXX/warn-for-var-in-else.cpp index 3368da223a48..f73c60689446 100644 --- a/test/SemaCXX/warn-for-var-in-else.cpp +++ b/test/SemaCXX/warn-for-var-in-else.cpp @@ -8,6 +8,7 @@ int foo() { return X; } else { do_something(X); // expected-warning{{'X' is always zero in this context}} + return 0; } } diff --git a/test/SemaCXX/warn-reorder-ctor-initialization.cpp b/test/SemaCXX/warn-reorder-ctor-initialization.cpp new file mode 100644 index 000000000000..bfce588b570a --- /dev/null +++ b/test/SemaCXX/warn-reorder-ctor-initialization.cpp @@ -0,0 +1,89 @@ +// RUN: clang-cc -fsyntax-only -Wreorder -verify %s + +struct BB {}; + +struct BB1 {}; + +class complex : public BB, BB1 { +public: + complex() : s2(1), // expected-warning {{member 's2' will be initialized after}} + s1(1) , // expected-note {{field s1}} + s3(3), // expected-warning {{member 's3' will be initialized after}} + BB1(), // expected-note {{base 'struct BB1'}} \ + // expected-warning {{base class 'struct BB1' will be initialized after}} + BB() {} // expected-note {{base 'struct BB'}} + int s1; + int s2; + int s3; +}; + + +// testing virtual bases. + + +struct V { + V(); +}; + +struct A : public virtual V { + A(); +}; + +struct B : public virtual V { + B(); +}; + +struct Diamond : public A, public B { + Diamond() : A(), B() {} +}; + + +struct C : public A, public B, private virtual V { + C() { } +}; + + +struct D : public A, public B { + D() : A(), V() { } // expected-warning {{base class 'struct A' will be initialized after}} \ + // expected-note {{base 'struct V'}} +}; + + +struct E : public A, public B, private virtual V { + E() : A(), V() { } // expected-warning {{base class 'struct A' will be initialized after}} \ + // expected-note {{base 'struct V'}} +}; + + +struct A1 { + A1(); +}; + +struct B1 { + B1(); +}; + +struct F : public A1, public B1, private virtual V { + F() : A1(), V() { } // expected-warning {{base class 'struct A1' will be initialized after}} \ + // expected-note {{base 'struct V'}} +}; + +struct X : public virtual A, virtual V, public virtual B { + X(): A(), V(), B() {} // expected-warning {{base class 'struct A' will be initialized after}} \ + // expected-note {{base 'struct V'}} +}; + +class Anon { + int c; union {int a,b;}; int d; + Anon() : c(10), b(1), d(2) {} +}; +class Anon2 { + int c; union {int a,b;}; int d; + Anon2() : c(2), + d(10), // expected-warning {{member 'd' will be initialized after}} + b(1) {} // expected-note {{field b}} +}; +class Anon3 { + union {int a,b;}; + Anon3() : b(1) {} +}; diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp new file mode 100644 index 000000000000..d8b9a00ad6de --- /dev/null +++ b/test/SemaCXX/warn-unused-variables.cpp @@ -0,0 +1,6 @@ +// RUN: clang -fsyntax-only -Wunused-variable -verify %s + +template<typename T> void f() { + T t; + t = 17; +} diff --git a/test/SemaCXX/wchar_t.cpp b/test/SemaCXX/wchar_t.cpp index fc258da7d1a6..cb85bc3ae729 100644 --- a/test/SemaCXX/wchar_t.cpp +++ b/test/SemaCXX/wchar_t.cpp @@ -7,3 +7,7 @@ void f(wchar_t p) { signed wchar_t z; // expected-warning {{'wchar_t' cannot be signed or unsigned}} ++x; } + +// PR4502 +wchar_t const c = L'c'; +int a[c == L'c' ? 1 : -1]; diff --git a/test/SemaObjC/access-property-getter.m b/test/SemaObjC/access-property-getter.m index 50a301688905..225d63b0173c 100644 --- a/test/SemaObjC/access-property-getter.m +++ b/test/SemaObjC/access-property-getter.m @@ -31,5 +31,6 @@ - (id)harvestPredictivelyProcessedOutputFiles { _outputStream.release; + return 0; } @end diff --git a/test/SemaObjC/attr-malloc.m b/test/SemaObjC/attr-malloc.m new file mode 100644 index 000000000000..6cd6be00a8cf --- /dev/null +++ b/test/SemaObjC/attr-malloc.m @@ -0,0 +1,16 @@ +// RUN: clang-cc -verify -fsyntax-only -fblocks %s + +@interface TestAttrMallocOnMethods {} +- (id) test1 __attribute((malloc)); // expected-warning {{functions returning a pointer type}} +- (int) test2 __attribute((malloc)); // expected-warning {{functions returning a pointer type}} +@end + +id bar(void) __attribute((malloc)); // no-warning + +typedef void (^bptr)(void); +bptr baz(void) __attribute((malloc)); // no-warning + +__attribute((malloc)) id (*f)(); // expected-warning {{functions returning a pointer type}} +__attribute((malloc)) bptr (*g)(); // expected-warning {{functions returning a pointer type}} +__attribute((malloc)) void *(^h)(); // expected-warning {{functions returning a pointer type}} + diff --git a/test/SemaObjC/block-explicit-return-type.m b/test/SemaObjC/block-explicit-return-type.m new file mode 100644 index 000000000000..cfe72de39523 --- /dev/null +++ b/test/SemaObjC/block-explicit-return-type.m @@ -0,0 +1,77 @@ +// RUN: clang-cc -fsyntax-only %s -verify -fblocks +// FIXME: should compile +// Test for blocks with explicit return type specified. + +typedef float * PF; +float gf; + +@interface NSView + - (id) some_method_that_returns_id; +@end + +NSView *some_object; + +void some_func (NSView * (^) (id)); + +typedef struct dispatch_item_s *dispatch_item_t; +typedef void (^completion_block_t)(void); + +typedef double (^myblock)(int); +double test(myblock I); + +int main() { + __block int x = 1; + __block int y = 2; + + (void)^void *{ return 0; }; + + (void)^float(float y){ return y; }; + + (void)^double (float y, double d) { + if (y) + return d; + else + return y; + }; + + const char * (^chb) (int flag, const char *arg, char *arg1) = ^ const char * (int flag, const char *arg, char *arg1) { + if (flag) + return 0; + if (flag == 1) + return arg; + else if (flag == 2) + return ""; + return arg1; + }; + + (void)^PF { return &gf; }; + + some_func(^ NSView * (id whatever) { return [some_object some_method_that_returns_id]; }); + + double res = test(^(int z){x = y+z; return (double)z; }); +} + +void func() { + completion_block_t X; + + completion_block_t (^blockx)(dispatch_item_t) = ^completion_block_t (dispatch_item_t item) { + return X; + }; + + completion_block_t (^blocky)(dispatch_item_t) = ^(dispatch_item_t item) { + return X; + }; + + blockx = blocky; +} + + +// intent: block taking int returning block that takes char,int and returns int +int (^(^block)(double x))(char, short); + +void foo() { + int one = 1; + block = ^(double x){ return ^(char c, short y) { return one + c + y; };}; // expected-error {{returning block that lives on the local stack}} + // or: + block = ^(double x){ return ^(char c, short y) { return one + (int)c + y; };}; // expected-error {{returning block that lives on the local stack}} +} diff --git a/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m index 6dab289ae9f2..aecdfd1f5e4e 100644 --- a/test/SemaObjC/blocks.m +++ b/test/SemaObjC/blocks.m @@ -44,3 +44,14 @@ void foo8() { P = ^itf() {}; // expected-error {{Objective-C interface type 'itf' cannot be returned by value}} P = ^itf{}; // expected-error {{Objective-C interface type 'itf' cannot be returned by value}} } + + +int foo9() { + typedef void (^DVTOperationGroupScheduler)(); + id _suboperationSchedulers; + + for (DVTOperationGroupScheduler scheduler in _suboperationSchedulers) { + ; + } + +} diff --git a/test/SemaObjC/call-super-2.m b/test/SemaObjC/call-super-2.m index 92bec27c6783..a481cffd2886 100644 --- a/test/SemaObjC/call-super-2.m +++ b/test/SemaObjC/call-super-2.m @@ -40,8 +40,8 @@ id objc_getClass(const char *s); { int i = [(id <Func>)self class_func0]; i += [(id <Func>)super class_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}} - i += [(Class <Func>)self class_func0]; // expected-error {{protocol qualified 'Class' is unsupported}} - return i + [(Class <Func>)super class_func0]; // expected-error {{protocol qualified 'Class' is unsupported}} // expected-error {{cannot cast 'super' (it isn't an expression)}} + i += [(Class <Func>)self class_func0]; // + return i + [(Class <Func>)super class_func0]; // // expected-error {{cannot cast 'super' (it isn't an expression)}} } + (int) class_func3 { diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m index 6ae775848e78..dcbda42cd136 100644 --- a/test/SemaObjC/category-1.m +++ b/test/SemaObjC/category-1.m @@ -53,4 +53,23 @@ @implementation XCRemoteComputerManager @end +@implementation XCRemoteComputerManager(x) // expected-note {{previous definition is here}} +@end + +@implementation XCRemoteComputerManager(x) // expected-error {{reimplementation of category 'x' for class 'XCRemoteComputerManager'}} +@end + +// <rdar://problem/7249233> + +@protocol MultipleCat_P +-(void) im0; +@end + +@interface MultipleCat_I @end + +@interface MultipleCat_I() @end +@interface MultipleCat_I() <MultipleCat_P> @end + +@implementation MultipleCat_I // expected-warning {{incomplete implementation}}, expected-warning {{method definition for 'im0' not found}} +@end diff --git a/test/SemaObjC/category-method-lookup-2.m b/test/SemaObjC/category-method-lookup-2.m index 76048cc2f74c..15da63783fee 100644 --- a/test/SemaObjC/category-method-lookup-2.m +++ b/test/SemaObjC/category-method-lookup-2.m @@ -17,6 +17,7 @@ typedef struct objc_class *Class; - instanceMethod { [[self class] classMethod]; + return 0; } @end diff --git a/test/SemaObjC/class-bitfield.m b/test/SemaObjC/class-bitfield.m index 01b532464c28..82209121b183 100644 --- a/test/SemaObjC/class-bitfield.m +++ b/test/SemaObjC/class-bitfield.m @@ -20,7 +20,7 @@ } @end -@interface WithBitfields: Base { +@interface WithBitFields: Base { void *isa; // expected-note {{previous definition is here}} unsigned a: 5; signed b: 4; @@ -28,10 +28,10 @@ } @end -@implementation WithBitfields { +@implementation WithBitFields { char *isa; // expected-error {{instance variable 'isa' has conflicting type: 'char *' vs 'void *'}} unsigned a: 5; signed b: 4; - int c: 3; // expected-error {{instance variable 'c' has conflicting bitfield width}} + int c: 3; // expected-error {{instance variable 'c' has conflicting bit-field width}} } @end diff --git a/test/SemaObjC/class-getter-using-dotsyntax.m b/test/SemaObjC/class-getter-using-dotsyntax.m new file mode 100644 index 000000000000..ba42590c3419 --- /dev/null +++ b/test/SemaObjC/class-getter-using-dotsyntax.m @@ -0,0 +1,39 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +typedef struct objc_class *Class; + +struct objc_class { + Class isa; +}; + +typedef struct objc_object { + Class isa; +} *id; + +@interface XCActivityLogSection ++ (unsigned)serializationFormatVersion; ++ (unsigned)sectionByDeserializingData; ++ (Class)retursClass; +@end + +@implementation XCActivityLogSection + ++ (unsigned)serializationFormatVersion +{ + + return 0; +} ++ (unsigned)sectionByDeserializingData { + unsigned version; + return self.serializationFormatVersion; +} + ++ (Class)retursClass { + Class version; + // FIXIT. (*version).isa does not work. Results in compiler error. + return version->isa; +} + +@end + + diff --git a/test/SemaObjC/class-impl-1.m b/test/SemaObjC/class-impl-1.m index 5a67bef3d605..09ad1556c035 100644 --- a/test/SemaObjC/class-impl-1.m +++ b/test/SemaObjC/class-impl-1.m @@ -9,7 +9,7 @@ typedef int INTF3; // expected-note {{previous definition is here}} @interface INTF : OBJECT @end -@implementation INTF @end +@implementation INTF @end // expected-note {{previous definition is here}} @implementation INTF // expected-error {{reimplementation of class 'INTF'}} @end diff --git a/test/SemaObjC/compatible-protocol-qualified-types.m b/test/SemaObjC/compatible-protocol-qualified-types.m index 3c27b5f0d3cd..71f00542b1c6 100644 --- a/test/SemaObjC/compatible-protocol-qualified-types.m +++ b/test/SemaObjC/compatible-protocol-qualified-types.m @@ -70,6 +70,7 @@ extern NSString * const XCActiveSelectionLevel; - (NSTextStorage *)contents { [_contents setDelegate:self]; // expected-warning {{incompatible type sending 'SKTText *', expected 'id<NSTextStorageDelegate>'}} + return 0; } @end diff --git a/test/SemaObjC/comptypes-1.m b/test/SemaObjC/comptypes-1.m index 8717bd09eb84..df0785bf89e1 100644 --- a/test/SemaObjC/comptypes-1.m +++ b/test/SemaObjC/comptypes-1.m @@ -66,9 +66,7 @@ int main() /* Any comparison between 'MyClass *' and anything which is not an 'id' must generate a warning. */ - /* FIXME: GCC considers this a warning ("comparison of distinct pointer types"). */ - /* There is a corresponding FIXME in ASTContext::mergeTypes() */ - if (obj_p == obj_c) foo() ; + if (obj_p == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'MyClass *')}} if (obj_c == obj_cp) foo() ; // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'MyOtherClass *')}} if (obj_cp == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'MyClass *')}} diff --git a/test/SemaObjC/comptypes-3.m b/test/SemaObjC/comptypes-3.m index 2d8f19d806a7..0506bce7ad1a 100644 --- a/test/SemaObjC/comptypes-3.m +++ b/test/SemaObjC/comptypes-3.m @@ -42,8 +42,8 @@ int main() obj_ac = obj_b; // expected-warning {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAC>'}} obj_ac = obj_ab; // expected-warning {{incompatible type assigning 'id<MyProtocolAB>', expected 'id<MyProtocolAC>'}} - if (obj_a == obj_b) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolA>' and 'id<MyProtocolB>')}} - if (obj_b == obj_a) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolA>')}} + if (obj_a == obj_b) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolA>' and 'id<MyProtocolB>')}} + if (obj_b == obj_a) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolB>' and 'id<MyProtocolA>')}} if (obj_a == obj_ab) foo (); /* Ok */ if (obj_ab == obj_a) foo (); /* Ok */ @@ -54,11 +54,11 @@ int main() if (obj_b == obj_ab) foo (); /* Ok */ if (obj_ab == obj_b) foo (); /* Ok */ - if (obj_b == obj_ac) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolAC>')}} - if (obj_ac == obj_b) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolB>')}} + if (obj_b == obj_ac) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolB>' and 'id<MyProtocolAC>')}} + if (obj_ac == obj_b) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAC>' and 'id<MyProtocolB>')}} - if (obj_ab == obj_ac) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAB>' and 'id<MyProtocolAC>')}} - if (obj_ac == obj_ab) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolAB>')}} + if (obj_ab == obj_ac) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAB>' and 'id<MyProtocolAC>')}} + if (obj_ac == obj_ab) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAC>' and 'id<MyProtocolAB>')}} return 0; } diff --git a/test/SemaObjC/comptypes-5.m b/test/SemaObjC/comptypes-5.m index afd8a4949ed6..478e8c8114ac 100644 --- a/test/SemaObjC/comptypes-5.m +++ b/test/SemaObjC/comptypes-5.m @@ -26,8 +26,8 @@ int main() MyOtherClass<MyProtocol> *obj_c_super_p_q = nil; MyClass<MyProtocol> *obj_c_cat_p_q = nil; - obj_c_cat_p = obj_id_p; // expected-warning {{incompatible type assigning 'id<MyProtocol>', expected 'MyClass *'}} - obj_c_super_p = obj_id_p; // expected-warning {{incompatible type assigning 'id<MyProtocol>', expected 'MyOtherClass *'}} + obj_c_cat_p = obj_id_p; + obj_c_super_p = obj_id_p; obj_id_p = obj_c_cat_p; /* Ok */ obj_id_p = obj_c_super_p; /* Ok */ diff --git a/test/SemaObjC/comptypes-7.m b/test/SemaObjC/comptypes-7.m index faca6937cb74..881fd2b5553b 100644 --- a/test/SemaObjC/comptypes-7.m +++ b/test/SemaObjC/comptypes-7.m @@ -28,7 +28,7 @@ int main() obj = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'id'}} obj_p = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'id<MyProtocol>'}} - obj_p = j; // expected-warning {{incompatible type assigning 'int *', expected 'id<MyProtocol>'}} + obj_p = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'id<MyProtocol>'}} obj_c = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'MyClass *'}} obj_c = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'MyClass *'}} @@ -42,7 +42,7 @@ int main() i = obj_C; // expected-warning {{incompatible pointer to integer conversion assigning 'Class', expected 'int'}} j = obj; // expected-warning {{incompatible pointer types assigning 'id', expected 'int *'}} - j = obj_p; // expected-warning {{incompatible type assigning 'id<MyProtocol>', expected 'int *'}} + j = obj_p; // expected-warning {{incompatible pointer types assigning 'id<MyProtocol>', expected 'int *'}} j = obj_c; // expected-warning {{incompatible pointer types assigning 'MyClass *', expected 'int *'}} j = obj_C; // expected-warning {{incompatible pointer types assigning 'Class', expected 'int *'}} diff --git a/test/SemaObjC/comptypes-a.m b/test/SemaObjC/comptypes-a.m index 936c6dfc5de9..5570d56b0b83 100644 --- a/test/SemaObjC/comptypes-a.m +++ b/test/SemaObjC/comptypes-a.m @@ -13,6 +13,7 @@ extern NSInteger codeAssistantCaseCompareItems(id a, id b, void *context); NSInteger codeAssistantCaseCompareItems(id<PBXCompletionItem> a, id<PBXCompletionItem> b, void *context) { + return 0; } @interface TedWantsToVerifyObjCDoesTheRightThing diff --git a/test/SemaObjC/conditional-expr-3.m b/test/SemaObjC/conditional-expr-3.m index 31d4834ff0af..9f1ee68c6f94 100644 --- a/test/SemaObjC/conditional-expr-3.m +++ b/test/SemaObjC/conditional-expr-3.m @@ -51,15 +51,15 @@ void f7(int cond, id x, A *a) { } void f8(int cond, id<P0,P1> x0, id<P0,P2> x1) { - barP0(cond ? x0 : x1); + barP0(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}} } void f9(int cond, id<P0,P1> x0, id<P0,P2> x1) { - barP1(cond ? x0 : x1); + barP1(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}} } void f10(int cond, id<P0,P1> x0, id<P0,P2> x1) { - barP2(cond ? x0 : x1); + barP2(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}} } int f11(int cond, A* a, B* b) { diff --git a/test/SemaObjC/conditional-expr-4.m b/test/SemaObjC/conditional-expr-4.m index 7d50ba60750c..87209581534c 100644 --- a/test/SemaObjC/conditional-expr-4.m +++ b/test/SemaObjC/conditional-expr-4.m @@ -1,5 +1,4 @@ -// RUN: clang-cc -fsyntax-only %s -// XFAIL +// RUN: clang-cc -fsyntax-only -verify %s // <rdar://problem/6212771> #define nil ((void*) 0) @@ -26,6 +25,11 @@ A *f1_a(int cond, A *a) { return cond ? a : nil; } +void *f1_const_a(int x, void *p, const A * q) { + void *r = x ? p : q; // expected-warning{{initializing 'void const *' discards qualifiers, expected 'void *'}} + return r; +} + // Check interaction with qualified id @protocol P0 @end @@ -48,9 +52,7 @@ id f3(int cond, id<P0> a) { @end int f5(int cond, id<P1> a, id<P1> b) { - // This should result in something with id type, currently. This is - // almost certainly wrong and should be fixed. - return (cond ? a : b).x; // expected-error {{member reference base type ('id') is not a structure or union}} + return (cond ? a : b).x; } int f5_a(int cond, A *a, A *b) { return (cond ? a : b).x; @@ -61,7 +63,7 @@ int f5_b(int cond, A *a, B *b) { int f6(int cond, id<P1> a, void *b) { // This should result in something with id type, currently. - return (cond ? a : b).x; // expected-error {{member reference base type ('id') is not a structure or union}} + return (cond ? a : b).x; // expected-error {{member reference base type 'void *' is not a structure or union}} } int f7(int cond, id<P1> a) { @@ -69,10 +71,10 @@ int f7(int cond, id<P1> a) { } int f8(int cond, id<P1> a, A *b) { - // GCC regards this as a warning (comparison of distinct Objective-C types lacks a cast) - return a == b; // expected-error {{invalid operands to binary expression}} + return a == b; // expected-warning {{comparison of distinct pointer types ('id<P1>' and 'A *')}} } int f9(int cond, id<P1> a, A *b) { - return (cond ? a : b).x; // expected-error {{incompatible operand types}} + return (cond ? a : b).x; // expected-warning {{incompatible operand types ('id<P1>' and 'A *')}} \ + expected-error {{property 'x' not found on object of type 'id'}} } diff --git a/test/SemaObjC/conditional-expr-5.m b/test/SemaObjC/conditional-expr-5.m new file mode 100644 index 000000000000..d9c1a9474fe7 --- /dev/null +++ b/test/SemaObjC/conditional-expr-5.m @@ -0,0 +1,27 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface PBXBuildSettingsDictionary +{ + int i; +} +@end + +@interface XCConditionalBuildSettingsDictionary : PBXBuildSettingsDictionary +{ +} +@end + +@implementation PBXBuildSettingsDictionary + +- (XCConditionalBuildSettingsDictionary *)conditionalDictionaryForConditionSet +{ + return i ? self : (id)0; +} + +- (XCConditionalBuildSettingsDictionary *)conditionalDictionaryForConditionSet2 +{ + return i ? (id)0 : self; +} +@end + + diff --git a/test/SemaObjC/conditional-expr.m b/test/SemaObjC/conditional-expr.m index ec3613b2aa9b..2043503ddf7b 100644 --- a/test/SemaObjC/conditional-expr.m +++ b/test/SemaObjC/conditional-expr.m @@ -27,9 +27,8 @@ @implementation DTFilterOutputStream2 // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'nextOutputStream' not found}} - (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream { id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; - // GCC warns about both of these. self = nextOutputStream; // expected-warning {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream2 *'}} - return nextOutputStream ? nextOutputStream : self; + return nextOutputStream ? nextOutputStream : self; // expected-warning {{incompatible operand types ('id<DTOutputStreams>' and 'DTFilterOutputStream2 *')}} } @end @@ -37,8 +36,84 @@ @implementation DTFilterOutputStream3 // expected-warning {{cannot find interface declaration for 'DTFilterOutputStream3'}} - (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream { id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; // expected-warning {{method '-nextOutputStream' not found (return type defaults to 'id')}} - // GCC warns about both of these as well (no errors). self = nextOutputStream; // expected-warning {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream3 *'}} - return nextOutputStream ? nextOutputStream : self; + return nextOutputStream ? nextOutputStream : self; // expected-warning {{incompatible operand types ('id<DTOutputStreams>' and 'DTFilterOutputStream3 *')}} } @end + +// + +@protocol P0 +@property int intProp; +@end +@protocol P1 +@end +@protocol P2 +@end + +@interface A <P0> +@end + +@interface B : A +@end + +@interface C +@end + +@interface D +@end + +void f0(id<P0> x) { + x.intProp = 1; +} + +void f1(int cond, id<P0> x, id<P0> y) { + (cond ? x : y).intProp = 1; +} + +void f2(int cond, id<P0> x, A *y) { + (cond ? x : y).intProp = 1; +} + +void f3(int cond, id<P0> x, B *y) { + (cond ? x : y).intProp = 1; +} + +void f4(int cond, id x, B *y) { + (cond ? x : y).intProp = 1; // expected-error {{property 'intProp' not found on object of type 'id'}} +} + +void f5(int cond, id<P0> x, C *y) { + (cond ? x : y).intProp = 1; // expected-warning {{incompatible operand types ('id<P0>' and 'C *')}} expected-error {{property 'intProp' not found on object of type 'id'}} +} + +void f6(int cond, C *x, D *y) { + (cond ? x : y).intProp = 1; // expected-warning {{incompatible operand types}}, expected-error {{property 'intProp' not found on object of type 'id'}} +} + +id f7(int a, id<P0> x, A* p) { + return a ? x : p; +} + +void f8(int a, A<P0> *x, A *y) { + [ (a ? x : y ) intProp ]; +} + +void f9(int a, A<P0> *x, A<P1> *y) { + id l0 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')'}} + A<P0> *l1 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}} + A<P1> *l2 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}} + [ (a ? x : y ) intProp ]; // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}} +} + +void f10(int a, id<P0> x, id y) { + [ (a ? x : y ) intProp ]; +} + +void f11(int a, id<P0> x, id<P1> y) { + [ (a ? x : y ) intProp ]; // expected-warning {{incompatible operand types ('id<P0>' and 'id<P1>')}} +} + +void f12(int a, A<P0> *x, A<P1> *y) { + A<P1>* l0 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}} +} diff --git a/test/SemaObjC/crash-label.m b/test/SemaObjC/crash-label.m new file mode 100644 index 000000000000..ff40cc67c5dc --- /dev/null +++ b/test/SemaObjC/crash-label.m @@ -0,0 +1,9 @@ +// RUN: clang-cc -fsyntax-only -verify %s + + - (NSDictionary*) _executeScript:(NSString *)source { // expected-error 2 {{expected a type}} \ + // expected-error {{missing context for method declaration}} + Exit: [nilArgs release]; // expected-error {{use of undeclared identifier}} + } + - (NSDictionary *) _setupKernelStandardMode:(NSString *)source { // expected-error 2 {{expected a type}} \ +expected-error {{missing context for method declaration}} + Exit: if(_ciKernel && !success ) { // expected-error {{use of undeclared identifier}} // expected-error 2 {{expected}} diff --git a/test/SemaObjC/deref-interface.m b/test/SemaObjC/deref-interface.m new file mode 100644 index 000000000000..1c85918ed57c --- /dev/null +++ b/test/SemaObjC/deref-interface.m @@ -0,0 +1,12 @@ +// RUN: clang-cc -triple x86_64-apple-darwin9 -verify -fsyntax-only %s + +@interface NSView + - (id)initWithView:(id)realView; +@end + +@implementation NSView + - (id)initWithView:(id)realView { + *(NSView *)self = *(NSView *)realView; // expected-error {{indirection cannot be to an interface in non-fragile ABI}} + } +@end + diff --git a/test/SemaObjC/format-arg-attribute.m b/test/SemaObjC/format-arg-attribute.m index 60cc7cb44f25..dc5aa8932cda 100644 --- a/test/SemaObjC/format-arg-attribute.m +++ b/test/SemaObjC/format-arg-attribute.m @@ -11,8 +11,7 @@ extern void fc3 (const NSString *) __attribute__((format_arg(1, 2))); // expecte struct s1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to function types}} union u1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to function types}} -// FIXME: We don't flag this yet. -enum e1 { E1V0 } __attribute__((format_arg(1))); /* { dg-error "does not apply|only applies" "format_arg on enum" } */ +enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to function types}} extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2))); extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{attribute requires 1 argument(s)}} diff --git a/test/SemaObjC/id-isa-ref.m b/test/SemaObjC/id-isa-ref.m new file mode 100644 index 000000000000..dc42f9a53965 --- /dev/null +++ b/test/SemaObjC/id-isa-ref.m @@ -0,0 +1,37 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// Failing currently due to Obj-C type representation changes. 2009-09-17 +// XFAIL + +typedef struct objc_object { + struct objc_class *isa; +} *id; + +@interface NSObject { + struct objc_class *isa; +} +@end +@interface Whatever : NSObject ++self; +@end + +static void func() { + + id x; + + [(*x).isa self]; + [x->isa self]; + + Whatever *y; + + // GCC allows this, with the following warning: + // instance variable ‘isa’ is @protected; this will be a hard error in the future + // + // FIXME: see if we can avoid the 2 warnings that follow the error. + [(*y).isa self]; // expected-error {{instance variable 'isa' is protected}} \ + expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} \ + expected-warning{{method '-self' not found (return type defaults to 'id')}} + [y->isa self]; // expected-error {{instance variable 'isa' is protected}} \ + expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} \ + expected-warning{{method '-self' not found (return type defaults to 'id')}} +} diff --git a/test/SemaObjC/id.m b/test/SemaObjC/id.m index 1781ce71d9c3..70d981c42b17 100644 --- a/test/SemaObjC/id.m +++ b/test/SemaObjC/id.m @@ -15,6 +15,6 @@ void foo() { } // Test attempt to redefine 'id' in an incompatible fashion. -typedef int id; // expected-error {{typedef redefinition with different types}} +typedef int id; // FIXME: Decide how we want to deal with this (now that 'id' is more of a built-in type). id b; diff --git a/test/SemaObjC/interface-scope-2.m b/test/SemaObjC/interface-scope-2.m index d054e714f3b2..c9025903940c 100644 --- a/test/SemaObjC/interface-scope-2.m +++ b/test/SemaObjC/interface-scope-2.m @@ -83,6 +83,7 @@ typedef struct __LoreStuffNode {} LoreStuffNode; - init { LoreStuffNode *node; node = &(_historyStuff[1]); + return 0; } @end @@ -108,6 +109,7 @@ _nfttFlags; if (self != ((void *)0)) { (void)memset(&_nfttFlags, 0, sizeof(struct _OingoBoingoContraptionPeonFlags)); } + return 0; } @end diff --git a/test/SemaObjC/invalid-objc-decls-1.m b/test/SemaObjC/invalid-objc-decls-1.m index e3a94f62d5a6..4a3732eff188 100644 --- a/test/SemaObjC/invalid-objc-decls-1.m +++ b/test/SemaObjC/invalid-objc-decls-1.m @@ -32,3 +32,11 @@ Super foo( // expected-error{{interface interface type 'Super' cannot be returne Super p1; // expected-error{{interface type cannot be statically allocated}} return p1; } + +@interface NSMutableSet @end + +@interface DVTDummyAnnotationProvider + @property(readonly) NSMutableSet annotations; // expected-error{{interface type cannot be statically allocated}} + +@end + diff --git a/test/SemaObjC/message.m b/test/SemaObjC/message.m index 7b6a4ee3f796..02901238f17f 100644 --- a/test/SemaObjC/message.m +++ b/test/SemaObjC/message.m @@ -95,6 +95,6 @@ int test5(int X) { void foo4() { struct objc_object X[10]; - [X rect]; + [X rect]; // expected-warning {{receiver type 'struct objc_object *' is not 'id' or interface pointer, consider casting it to 'id'}} expected-warning {{method '-rect' not found (return type defaults to 'id')}} } diff --git a/test/SemaObjC/method-arg-decay.m b/test/SemaObjC/method-arg-decay.m index 4b045914c095..7fd07d2ede33 100644 --- a/test/SemaObjC/method-arg-decay.m +++ b/test/SemaObjC/method-arg-decay.m @@ -87,6 +87,7 @@ extern NSMutableArray *XCFindPossibleKeyModules(PBXModule *module, BOOL useExpos PBXModule *obj = [XCFindPossibleKeyModules(pModule, (BOOL)0) objectOfType:type matchingFunction:comparator usingData:data]; } } + return 0; } - (BOOL)buffer:(char *)buf containsAnyPrompts:(char *[])prompts { diff --git a/test/SemaObjC/method-conflict.m b/test/SemaObjC/method-conflict.m index 7a9b9f0beee8..a4213f6c63c9 100644 --- a/test/SemaObjC/method-conflict.m +++ b/test/SemaObjC/method-conflict.m @@ -47,7 +47,9 @@ typedef NSUInteger XDSourceLanguage; + appendVisibility: (id <XDUMLNamedElement>) element withSpecification: (XDSCDisplaySpecification *) displaySpec to: (NSMutableAttributedString *) attributedString { + return 0; } -+ (NSUInteger) compartmentsForClassifier: (id <XDSCClassifier>) classifier withSpecification: (XDSCDisplaySpecification *) displaySpec { ++ (NSUInteger) compartmentsForClassifier: (id <XDSCClassifier>) classifier withSpecification: (XDSCDisplaySpecification *) displaySpec { + return 0; } @end diff --git a/test/SemaObjC/method-encoding-2.m b/test/SemaObjC/method-encoding-2.m index 64a0bc4c323d..b3ffdcd0585c 100644 --- a/test/SemaObjC/method-encoding-2.m +++ b/test/SemaObjC/method-encoding-2.m @@ -7,6 +7,6 @@ @end @implementation Intf -- (in out bycopy id) address:(byref inout void *)location with:(out oneway unsigned **)arg2{} -- (id) another:(void *)location with:(unsigned **)arg2 {} +- (in out bycopy id) address:(byref inout void *)location with:(out oneway unsigned **)arg2{ return 0; } +- (id) another:(void *)location with:(unsigned **)arg2 { return 0; } @end diff --git a/test/SemaObjC/method-lookup-2.m b/test/SemaObjC/method-lookup-2.m index dd0bca93644e..cca757509ad1 100644 --- a/test/SemaObjC/method-lookup-2.m +++ b/test/SemaObjC/method-lookup-2.m @@ -35,8 +35,8 @@ extern NSString *const NSWillBecomeMultiThreadedNotification; @implementation SenTestTool + (void) initialize {} -+(SenTestTool *) sharedInstance {} --(int) run {} ++(SenTestTool *) sharedInstance { return 0; } +-(int) run { return 0; } +(int) run { return[[self sharedInstance] run]; } @@ -57,6 +57,7 @@ extern NSString *const NSWillBecomeMultiThreadedNotification; - whatever { id obj = [[XX alloc] init]; [[obj class] classMethod]; + return 0; } @end diff --git a/test/SemaObjC/method-lookup.m b/test/SemaObjC/method-lookup.m index 917ad6b3ee92..49dc789af783 100644 --- a/test/SemaObjC/method-lookup.m +++ b/test/SemaObjC/method-lookup.m @@ -29,6 +29,7 @@ static NSMutableArray * recentCompletions = ((void *)0); [(id)item setPriority:[item priority] / [PBXCodeAssistant factorForRecentCompletion:[item name]]]; } } + return 0; } @end diff --git a/test/SemaObjC/method-typecheck-1.m b/test/SemaObjC/method-typecheck-1.m index d110c858a41a..a53c4d9f416a 100644 --- a/test/SemaObjC/method-typecheck-1.m +++ b/test/SemaObjC/method-typecheck-1.m @@ -8,8 +8,8 @@ @implementation A -(void) setMoo: (float) x {} // expected-warning {{conflicting parameter types in implementation of 'setMoo:': 'int' vs 'float'}} -- (char) setMoo1: (int) x {} // expected-warning {{conflicting return type in implementation of 'setMoo1:': 'int' vs 'char'}} -- (int) setOk : (int) x : (double) d {} +- (char) setMoo1: (int) x { return 0; } // expected-warning {{conflicting return type in implementation of 'setMoo1:': 'int' vs 'char'}} +- (int) setOk : (int) x : (double) d { return 0; } @end @@ -20,7 +20,7 @@ @implementation C +(float) cMoo: // expected-warning {{conflicting return type in implementation of 'cMoo:': 'void' vs 'float'}} - (float) x {} // expected-warning {{conflicting parameter types in implementation of 'cMoo:': 'int' vs 'float'}} + (float) x { return 0; } // expected-warning {{conflicting parameter types in implementation of 'cMoo:': 'int' vs 'float'}} @end @@ -31,7 +31,6 @@ @implementation A(CAT) -(float) setCat: // expected-warning {{conflicting return type in implementation of 'setCat:': 'void' vs 'float'}} -(float) x {} // expected-warning {{conflicting parameter types in implementation of 'setCat:': 'int' vs 'float'}} -+ (int) cCat: (int) x {} // expected-warning {{conflicting return type in implementation of 'cCat:': 'void' vs 'int'}} +(float) x { return 0; } // expected-warning {{conflicting parameter types in implementation of 'setCat:': 'int' vs 'float'}} ++ (int) cCat: (int) x { return 0; } // expected-warning {{conflicting return type in implementation of 'cCat:': 'void' vs 'int'}} @end - diff --git a/test/SemaObjC/no-warn-unimpl-method.m b/test/SemaObjC/no-warn-unimpl-method.m index 756c47b2fe80..2fcb06ff5e92 100644 --- a/test/SemaObjC/no-warn-unimpl-method.m +++ b/test/SemaObjC/no-warn-unimpl-method.m @@ -38,5 +38,5 @@ - (void)forwardInvocation:(NSInvocation *)anInvocation { } - - (id) init {} + - (id) init { return 0; } @end diff --git a/test/SemaObjC/nonnull.m b/test/SemaObjC/nonnull.m new file mode 100644 index 000000000000..869bbbd57e85 --- /dev/null +++ b/test/SemaObjC/nonnull.m @@ -0,0 +1,42 @@ +// RUN: clang-cc -fblocks -fsyntax-only -verify %s + +@class NSObject; + +int f1(int x) __attribute__((nonnull)); // expected-warning{{'nonnull' attribute applied to function with no pointer arguments}} +int f2(int *x) __attribute__ ((nonnull (1))); +int f3(int *x) __attribute__ ((nonnull (0))); // expected-error {{'nonnull' attribute parameter 1 is out of bounds}} +int f4(int *x, int *y) __attribute__ ((nonnull (1,2))); +int f5(int *x, int *y) __attribute__ ((nonnull (2,1))); +int f6(NSObject *x) __attribute__ ((nonnull (1))); // no-warning +int f7(NSObject *x) __attribute__ ((nonnull)); // no-warning + + +extern void func1 (void (^block1)(), void (^block2)(), int) __attribute__((nonnull)); + +extern void func3 (void (^block1)(), int, void (^block2)(), int) +__attribute__((nonnull(1,3))); + +extern void func4 (void (^block1)(), void (^block2)()) __attribute__((nonnull(1))) +__attribute__((nonnull(2))); + +void +foo (int i1, int i2, int i3, void (^cp1)(), void (^cp2)(), void (^cp3)()) +{ + func1(cp1, cp2, i1); + + func1(0, cp2, i1); // expected-warning {{null passed to a callee which requires a non-null argument}} + func1(cp1, 0, i1); // expected-warning {{null passed to a callee which requires a non-null argument}} + func1(cp1, cp2, 0); + + + func3(0, i2, cp3, i3); // expected-warning {{null passed to a callee which requires a non-null argument}} + func3(cp3, i2, 0, i3); // expected-warning {{null passed to a callee which requires a non-null argument}} + + func4(0, cp1); // expected-warning {{null passed to a callee which requires a non-null argument}} + func4(cp1, 0); // expected-warning {{null passed to a callee which requires a non-null argument}} + + // Shouldn't these emit warnings? Clang doesn't, and neither does GCC. It + // seems that the checking should handle Objective-C pointers. + func6((NSObject*) 0); // no-warning + func7((NSObject*) 0); // no-warning +} diff --git a/test/SemaObjC/nsobject-attribute.m b/test/SemaObjC/nsobject-attribute.m index 3544cb139aab..c47b909846c1 100644 --- a/test/SemaObjC/nsobject-attribute.m +++ b/test/SemaObjC/nsobject-attribute.m @@ -26,7 +26,7 @@ id getProperty(id self) { @synthesize x=x; @end -int main(char *argc, char *argv[]) { +int main(int argc, char *argv[]) { HandTested *to; to.x = tmp; // setter if (tmp != to.x) diff --git a/test/SemaObjC/objc2-merge-gc-attribue-decl.m b/test/SemaObjC/objc2-merge-gc-attribue-decl.m index 9dae1efdcd2a..0da0ce876d3e 100644 --- a/test/SemaObjC/objc2-merge-gc-attribue-decl.m +++ b/test/SemaObjC/objc2-merge-gc-attribue-decl.m @@ -25,6 +25,5 @@ extern __strong id p5; extern char* __strong p6; // expected-note {{previous definition is here}} extern char* p6; // expected-error {{redefinition of 'p6' with a different type}} -// FIXME. We do not issue error here because we don't put the attribute on the pointer type. -extern __strong char* p7; -extern char* p7; +extern __strong char* p7; // expected-note {{previous definition is here}} +extern char* p7; // expected-error {{redefinition of 'p7' with a different type}} diff --git a/test/SemaObjC/property-11.m b/test/SemaObjC/property-11.m index e8e60914716d..bb36c2766e75 100644 --- a/test/SemaObjC/property-11.m +++ b/test/SemaObjC/property-11.m @@ -29,6 +29,7 @@ o = x.foo; [x setFoo:o]; x.foo = o; + return 0; } @end diff --git a/test/SemaObjC/property-9-impl-method.m b/test/SemaObjC/property-9-impl-method.m index c97f38891190..06cb30482c82 100644 --- a/test/SemaObjC/property-9-impl-method.m +++ b/test/SemaObjC/property-9-impl-method.m @@ -55,10 +55,11 @@ NSSize minimumSize; @implementation OrganizerTabView @dynamic tabHeaderView, headerRect, minimumSize; --(CGFloat) tabAreaThickness {} +-(CGFloat) tabAreaThickness { return 0; } -(NSRectEdge) rectEdgeForTabs { NSRect dummy, result = {}; NSDivideRect(self.bounds, &result, &dummy, self.tabAreaThickness, self.rectEdgeForTabs); + return 0; } @end diff --git a/test/SemaObjC/property-error-readonly-assign.m b/test/SemaObjC/property-error-readonly-assign.m index edeff09dfadd..d5cef78f18f4 100644 --- a/test/SemaObjC/property-error-readonly-assign.m +++ b/test/SemaObjC/property-error-readonly-assign.m @@ -19,3 +19,26 @@ void f0(A *a, B* b) { b.ok = 20; } +typedef struct { + int i1, i2; +} NSRect; + +NSRect NSMakeRect(); + +@interface NSWindow +{ + NSRect _frame; +} +- (NSRect)frame; +@end + +@interface NSWindow (Category) +-(void)methodToMakeClangCrash; +@end + +@implementation NSWindow (Category) +-(void)methodToMakeClangCrash +{ + self.frame = NSMakeRect(); // expected-error {{setter method is needed to assign to object using property assignment syntax}} +} +@end diff --git a/test/SemaObjC/property-expression-error.m b/test/SemaObjC/property-expression-error.m new file mode 100644 index 000000000000..b648ee939dbe --- /dev/null +++ b/test/SemaObjC/property-expression-error.m @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface AddressMyProperties +{ + unsigned index; +} +@property unsigned index; +@end + +@implementation AddressMyProperties +@synthesize index; +@end + +int main() { + AddressMyProperties *object; + &object.index; // expected-error {{address of property expression requested}} + return 0; +} diff --git a/test/SemaObjC/property-method-lookup-impl.m b/test/SemaObjC/property-method-lookup-impl.m index ed7e9bcd4315..295bba524009 100644 --- a/test/SemaObjC/property-method-lookup-impl.m +++ b/test/SemaObjC/property-method-lookup-impl.m @@ -8,9 +8,7 @@ @implementation SSyncCEList -- (id) list -{ -} +- (id) list { return 0; } @end @interface SSyncConflictList : SSyncCEList diff --git a/test/SemaObjC/property-missing.m b/test/SemaObjC/property-missing.m index 1aa94ce71b25..301907ad1c7d 100644 --- a/test/SemaObjC/property-missing.m +++ b/test/SemaObjC/property-missing.m @@ -17,6 +17,6 @@ void f2(id<NSCopying> o) void f3(id o) { - o.foo; // expected-error{{member reference base type 'id' is not a structure or union}} + o.foo; // expected-error{{property 'foo' not found on object of type 'id'}} } diff --git a/test/SemaObjC/protocol-archane.m b/test/SemaObjC/protocol-archane.m index 3e70c0509652..05f5103178f2 100644 --- a/test/SemaObjC/protocol-archane.m +++ b/test/SemaObjC/protocol-archane.m @@ -28,8 +28,7 @@ typedef int NotAnObjCObjectType; // GCC doesn't diagnose this. NotAnObjCObjectType <SomeProtocol> *obj; // expected-error {{invalid protocol qualifiers on non-ObjC type}} -// Decided not to support the following GCC extension. Found while researching rdar://6497631 typedef struct objc_class *Class; -Class <SomeProtocol> UnfortunateGCCExtension; // expected-error {{protocol qualified 'Class' is unsupported}} +Class <SomeProtocol> UnfortunateGCCExtension; diff --git a/test/SemaObjC/protocol-attribute.m b/test/SemaObjC/protocol-attribute.m index ae8441132c77..6bd58dd9a03a 100644 --- a/test/SemaObjC/protocol-attribute.m +++ b/test/SemaObjC/protocol-attribute.m @@ -3,7 +3,7 @@ __attribute ((unavailable)) @protocol FwProto; // expected-note{{marked unavailable}} -Class <FwProto> cFw = 0; // expected-warning {{'FwProto' is unavailable}} expected-error{{protocol qualified 'Class' is unsupported}} +Class <FwProto> cFw = 0; // expected-warning {{'FwProto' is unavailable}} __attribute ((deprecated)) @protocol MyProto1 @@ -31,7 +31,7 @@ __attribute ((deprecated)) @protocol MyProto1 -Class <MyProto1> clsP1 = 0; // expected-warning {{'MyProto1' is deprecated}} expected-error{{protocol qualified 'Class' is unsupported}} +Class <MyProto1> clsP1 = 0; // expected-warning {{'MyProto1' is deprecated}} @protocol FwProto @end // expected-note{{marked unavailable}} diff --git a/test/SemaObjC/protocol-implementation-inherited.m b/test/SemaObjC/protocol-implementation-inherited.m index 1aace211c844..55b92ae6684a 100644 --- a/test/SemaObjC/protocol-implementation-inherited.m +++ b/test/SemaObjC/protocol-implementation-inherited.m @@ -26,7 +26,7 @@ @end @implementation B1 --foo {}; +-foo { return 0; }; @end // Interface conforms to a protocol whose methods are provided by an diff --git a/test/SemaObjC/protocol-lookup.m b/test/SemaObjC/protocol-lookup.m index 0f1860d2c88e..87655bd9e7a0 100644 --- a/test/SemaObjC/protocol-lookup.m +++ b/test/SemaObjC/protocol-lookup.m @@ -44,6 +44,7 @@ [_foo release]; [_bar release]; [super dealloc]; + return 0; } @end diff --git a/test/SemaObjC/protocol-qualified-class-unsupported.m b/test/SemaObjC/protocol-qualified-class-unsupported.m index ad1ed5dc9411..6e344c1f4414 100644 --- a/test/SemaObjC/protocol-qualified-class-unsupported.m +++ b/test/SemaObjC/protocol-qualified-class-unsupported.m @@ -23,7 +23,7 @@ id objc_getClass(const char *s); @interface Derived2: Object <Func> @end -static void doSomething(Class <Func> unsupportedObjectType) { // expected-error {{protocol qualified 'Class' is unsupported}} +static void doSomething(Class <Func> unsupportedObjectType) { [unsupportedObjectType class_func0]; } diff --git a/test/SemaObjC/rdr-6211479-array-property.m b/test/SemaObjC/rdr-6211479-array-property.m index f8e4a07cba58..1781c5a40402 100644 --- a/test/SemaObjC/rdr-6211479-array-property.m +++ b/test/SemaObjC/rdr-6211479-array-property.m @@ -1,9 +1,8 @@ // RUN: clang-cc -fsyntax-only -verify %s -// XFAIL // <rdar://problem/6211479> typedef int T[2]; @interface A -@property(assign) T p2; // expected-error {{FIXME: property has invalid type}} +@property(assign) T p2; // expected-error {{property cannot have array or function type 'T' (aka 'int [2]')}} @end diff --git a/test/SemaObjC/return.m b/test/SemaObjC/return.m new file mode 100644 index 000000000000..9acf47079958 --- /dev/null +++ b/test/SemaObjC/return.m @@ -0,0 +1,6 @@ +// RUN: clang-cc %s -fsyntax-only -verify + +int test1() { + id a; + @throw a; +} diff --git a/test/SemaObjC/selector-1.m b/test/SemaObjC/selector-1.m index ee77015041db..a969b100cc68 100644 --- a/test/SemaObjC/selector-1.m +++ b/test/SemaObjC/selector-1.m @@ -8,6 +8,19 @@ @end +@interface I +- (id) compare: (char) arg1; +@end + +@interface J +- (id) compare: (id) arg1; +@end + +SEL foo() +{ + return @selector(compare:); // Non warning on multiple selector found. +} + int main() { SEL s = @selector(retain); SEL s1 = @selector(meth1:); diff --git a/test/SemaObjC/sizeof-interface.m b/test/SemaObjC/sizeof-interface.m index 75d7daafbbcc..140a980311e4 100644 --- a/test/SemaObjC/sizeof-interface.m +++ b/test/SemaObjC/sizeof-interface.m @@ -77,3 +77,14 @@ int bar(I0 *P) { } @end + +@interface Foo @end + +int foo() +{ + Foo *f; + + // Both of these crash clang nicely + ++f; // expected-error {{arithmetic on pointer to interface 'Foo', which is not a constant size in non-fragile ABI}} + --f; // expected-error {{arithmetic on pointer to interface 'Foo', which is not a constant size in non-fragile ABI}} +} diff --git a/test/SemaObjC/static-ivar-ref-1.m b/test/SemaObjC/static-ivar-ref-1.m index 3c37e9e83026..6b1a31226b20 100644 --- a/test/SemaObjC/static-ivar-ref-1.m +++ b/test/SemaObjC/static-ivar-ref-1.m @@ -1,4 +1,5 @@ -// RUN: clang-cc -ast-print %s +// RUN: clang-cc -triple i386-unknown-unknown -ast-print %s && +// RUN: clang-cc -triple x86_64-apple-darwin10 -ast-print %s @interface current { diff --git a/test/SemaObjC/super-cat-prot.m b/test/SemaObjC/super-cat-prot.m index 1ab0752faa38..6ddc31fbb9e6 100644 --- a/test/SemaObjC/super-cat-prot.m +++ b/test/SemaObjC/super-cat-prot.m @@ -35,14 +35,16 @@ typedef struct _IBInset {} IBInset; @interface NSView (NSView_IBViewProtocol) <IBViewProtocol> - (NSRect)layoutRect; @end typedef enum { NSProTextFieldSquareBezel = 0, NSProTextFieldRoundedBezel = 1, NSProTextFieldDisplayBezel = 2 } MKModuleReusePolicy; @implementation NSProBox(IBAdditions) --(NSString *)inspectorClassName {} +-(NSString *)inspectorClassName { return 0; } -(IBInset)ibShadowInset { if ([self boxType] == NSBoxSeparator) { return [super ibShadowInset]; } + while (1) {} } -(NSSize)minimumFrameSizeFromKnobPosition:(IBKnobPosition)knobPosition { if ([self boxType] != NSBoxSeparator) return [super minimumFrameSizeFromKnobPosition:knobPosition]; + while (1) {} } @end diff --git a/test/SemaObjC/super.m b/test/SemaObjC/super.m index 9afd4eb983c5..83842afb9c3f 100644 --- a/test/SemaObjC/super.m +++ b/test/SemaObjC/super.m @@ -21,6 +21,7 @@ + classMethod { [super cMethod]; // expected-warning{{method '+cMethod' not found (return type defaults to 'id')}} + return 0; } @end diff --git a/test/SemaObjC/synchronized.m b/test/SemaObjC/synchronized.m index 7131265b5bb7..01f82c168622 100644 --- a/test/SemaObjC/synchronized.m +++ b/test/SemaObjC/synchronized.m @@ -3,7 +3,7 @@ @interface PBXTrackableTaskManager @end @implementation PBXTrackableTaskManager -- (id) init {} +- (id) init { return 0; } - (void) unregisterTask:(id) task { @synchronized (self) { id taskID = [task taskIdentifier]; // expected-warning {{method '-taskIdentifier' not found (return type defaults to 'id')}} diff --git a/test/SemaObjC/undef-superclass-1.m b/test/SemaObjC/undef-superclass-1.m index 0d670f8c0809..cb15dc39a3dc 100644 --- a/test/SemaObjC/undef-superclass-1.m +++ b/test/SemaObjC/undef-superclass-1.m @@ -24,3 +24,10 @@ [super dealloc]; // expected-error {{no super class declared in @interface for 'SUPER'}} } @end + +@interface RecursiveClass : RecursiveClass // expected-error {{trying to recursively use 'RecursiveClass' as superclass of 'RecursiveClass'}} +@end + +@implementation RecursiveClass +@end + diff --git a/test/SemaObjC/unused.m b/test/SemaObjC/unused.m index 88c6f1054c8d..bbe3109a2817 100644 --- a/test/SemaObjC/unused.m +++ b/test/SemaObjC/unused.m @@ -1,4 +1,4 @@ -// RUN: clang-cc %s -verify -fsyntax-only +// RUN: clang-cc %s -verify -Wunused -fsyntax-only #include <stdio.h> @interface Greeter @@ -11,8 +11,33 @@ } @end -int main (void) { - [Greeter hello]; - return 0; + +int test1(void) { + [Greeter hello]; + return 0; +} + + + +@interface NSObject @end +@interface NSString : NSObject +- (int)length; +@end + +void test2() { + @"pointless example call for test purposes".length; // expected-warning {{property access result unused - getters should not have side effects}} } + + + + +@interface foo +- (int)meth: (int)x: (int)y: (int)z ; +@end + +@implementation foo +- (int) meth: (int)x: +(int)y: // expected-warning{{unused}} +(int) __attribute__((unused))z { return x; } +@end diff --git a/test/SemaObjC/warn-assign-property-nscopying.m b/test/SemaObjC/warn-assign-property-nscopying.m new file mode 100644 index 000000000000..cf1acc466a27 --- /dev/null +++ b/test/SemaObjC/warn-assign-property-nscopying.m @@ -0,0 +1,15 @@ +// RUN: clang-cc -fobjc-gc -fsyntax-only -verify %s + +@protocol NSCopying @end + +@interface NSObject <NSCopying> +@end + +@interface NSDictionary : NSObject +@end + +@interface INTF + @property NSDictionary* undoAction; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}} // expected-warning {{default assign attribute on property 'undoAction' which implements NSCopying protocol is not appropriate with}} + @property id okAction; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}} +@end + diff --git a/test/SemaObjC/warn-superclass-method-mismatch.m b/test/SemaObjC/warn-superclass-method-mismatch.m new file mode 100644 index 000000000000..f123a3f2ddac --- /dev/null +++ b/test/SemaObjC/warn-superclass-method-mismatch.m @@ -0,0 +1,50 @@ +// RUN: clang-cc -fsyntax-only -Wsuper-class-method-mismatch -verify %s + +@interface Root +-(void) method_r: (char)ch : (float*)f1 : (int*) x; // expected-note {{previous declaration is here}} +@end + +@class Sub; + +@interface Base : Root +-(void) method: (int*) x; // expected-note {{previous declaration is here}} +-(void) method1: (Base*) x; // expected-note {{previous declaration is here}} +-(void) method2: (Sub*) x; ++ method3: (int)x1 : (Base *)x2 : (float)x3; // expected-note {{previous declaration is here}} ++ mathod4: (id)x1; +- method5: (int) x : (double) d; // expected-note {{previous declaration is here}} +- method6: (int) x : (float) d; // expected-note {{previous declaration is here}} +@end + +struct A { + int x,y,z; +}; + +@interface Sub : Base +-(void) method: (struct A*) a; // expected-warning {{method parameter type 'struct A *' does not match super class method parameter type 'int *'}} +-(void) method1: (Sub*) x; // expected-warning {{method parameter type 'Sub *' does not match super class method parameter type 'Base *'}} +-(void) method2: (Base*) x; // no need to warn. At call point we warn if need be. ++ method3: (int)x1 : (Sub *)x2 : (float)x3; // expected-warning {{method parameter type 'Sub *' does not match super class method parameter type 'Base *'}} ++ mathod4: (Base*)x1; +-(void) method_r: (char)ch : (float*)f1 : (Sub*) x; // expected-warning {{method parameter type 'Sub *' does not match super class method parameter type 'int *'}} +- method5: (int) x : (float) d; // expected-warning {{method parameter type 'float' does not match super class method parameter type 'double'}} +- method6: (int) x : (double) d; // expected-warning {{method parameter type 'double' does not match super class method parameter type 'float'}} +@end + +void f(Base *base, Sub *sub) { + int x; + [base method:&x]; // warn. if base is actually 'Sub' it will use -[Sub method] with wrong arguments + + Base *b; + [base method1:b]; // if base is actuall 'Sub' it will use [Sub method1] with wrong argument. + + [base method2:b]; // expected-warning {{}} + + Sub *s; + [base method2:s]; // if base is actually 'Sub' OK. Either way OK. + +} + + + + diff --git a/test/SemaObjC/weak-attr-ivar.m b/test/SemaObjC/weak-attr-ivar.m index 9e0e8cb4b3af..6af96ddb3c8b 100644 --- a/test/SemaObjC/weak-attr-ivar.m +++ b/test/SemaObjC/weak-attr-ivar.m @@ -45,8 +45,7 @@ typedef enum { Foo_HUH_NONE } FooHUHCode; } @property(copy) NSString *author; - (BOOL) isInteresting; -@end NSString *FooHUHCodeToString(FooHUHCode HUH) { -} +@end NSString *FooHUHCodeToString(FooHUHCode HUH) { return 0; } @interface FooHUHCodeToStringTransformer: NSValueTransformer { } @end @implementation FooPlaypenEntry @synthesize author = _author; @@ -62,12 +61,14 @@ typedef enum { Foo_HUH_NONE } FooHUHCode; } } } + return 0; } - (FooHUHCode) HUH { if (_HUH == Foo_HUH_NONE) { if (_mostInterestingChild) return [_mostInterestingChild HUH]; } + return 0; } @end diff --git a/test/SemaObjCXX/overload.mm b/test/SemaObjCXX/overload.mm index 8ab22e1ca73e..47141002864c 100644 --- a/test/SemaObjCXX/overload.mm +++ b/test/SemaObjCXX/overload.mm @@ -1,4 +1,5 @@ // RUN: clang-cc -fsyntax-only -verify %s +// XFAIL @interface Foo @end diff --git a/test/SemaObjCXX/protocol-lookup.mm b/test/SemaObjCXX/protocol-lookup.mm index 0f1860d2c88e..87655bd9e7a0 100644 --- a/test/SemaObjCXX/protocol-lookup.mm +++ b/test/SemaObjCXX/protocol-lookup.mm @@ -44,6 +44,7 @@ [_foo release]; [_bar release]; [super dealloc]; + return 0; } @end diff --git a/test/SemaObjCXX/references.mm b/test/SemaObjCXX/references.mm index 6a28ea902967..82797cef77c7 100644 --- a/test/SemaObjCXX/references.mm +++ b/test/SemaObjCXX/references.mm @@ -1,4 +1,6 @@ -// RUN: clang-cc -verify -emit-llvm -o %t %s +// FIXME: This crashes, disable it until fixed. +// RN: clang-cc -verify -emit-llvm -o - %s +// RUN: false // XFAIL // Test reference binding. diff --git a/test/SemaTemplate/ackermann.cpp b/test/SemaTemplate/ackermann.cpp index 48fbbbb3cf1d..c936889f25f9 100644 --- a/test/SemaTemplate/ackermann.cpp +++ b/test/SemaTemplate/ackermann.cpp @@ -1,9 +1,9 @@ -// RUN: clang-cc -fsyntax-only -ftemplate-depth=1000 -verify %s +// RUN: clang-cc -fsyntax-only -verify %s // template<unsigned M, unsigned N> // struct Ackermann { // enum { -// value = M ? (N ? Ackermann<M-1, Ackermann<M-1, N-1> >::value +// value = M ? (N ? Ackermann<M-1, Ackermann<M, N-1> >::value // : Ackermann<M-1, 1>::value) // : N + 1 // }; @@ -34,4 +34,5 @@ template<> struct Ackermann<0, 0> { }; }; -int g0[Ackermann<3, 8>::value == 2045 ? 1 : -1]; +int g0[Ackermann<3, 4>::value == 125 ? 1 : -1]; + diff --git a/test/SemaTemplate/ambiguous-ovl-print.cpp b/test/SemaTemplate/ambiguous-ovl-print.cpp new file mode 100644 index 000000000000..ccdeb9bebc57 --- /dev/null +++ b/test/SemaTemplate/ambiguous-ovl-print.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void f(void*, int); // expected-note{{candidate function}} +template<typename T> + void f(T*, long); // expected-note{{candidate function template}} + +void test_f(int *ip, int i) { + f(ip, i); // expected-error{{ambiguous}} +} diff --git a/test/SemaTemplate/canonical-expr-type-0x.cpp b/test/SemaTemplate/canonical-expr-type-0x.cpp new file mode 100644 index 000000000000..21552105b0ff --- /dev/null +++ b/test/SemaTemplate/canonical-expr-type-0x.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -fsyntax-only -verify -std=c++0x %s + +void f(); + +// FIXME: would like to refer to the first function parameter in these test, +// but that won't work (yet). + +// Test typeof(expr) canonicalization +template<typename T, T N> +void f0(T x, decltype(f(N)) y) { } // expected-note{{previous}} + +template<typename T, T N> +void f0(T x, decltype((f)(N)) y) { } + +template<typename U, U M> +void f0(U u, decltype(f(M))) { } // expected-error{{redefinition}} diff --git a/test/SemaTemplate/canonical-expr-type.cpp b/test/SemaTemplate/canonical-expr-type.cpp new file mode 100644 index 000000000000..0580c677e627 --- /dev/null +++ b/test/SemaTemplate/canonical-expr-type.cpp @@ -0,0 +1,53 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void f(); + +// Test typeof(expr) canonicalization +template<typename T> +void f0(T x, __typeof__(f(x)) y) { } // expected-note{{previous}} + +template<typename T> +void f0(T x, __typeof__((f)(x)) y) { } + +template<typename U> +void f0(U u, __typeof__(f(u))) { } // expected-error{{redefinition}} + +// Test insane typeof(expr) overload set canonicalization +void f(int); +void f(double); + +template<typename T, T N> +void f0a(T x, __typeof__(f(N)) y) { } // expected-note{{previous}} + +void f(int); + +template<typename T, T N> +void f0a(T x, __typeof__(f(N)) y) { } // expected-error{{redefinition}} \ + // expected-note{{previous}} + +void f(float); + +template<typename T, T N> +void f0a(T x, __typeof__(f(N)) y) { } // expected-error{{redefinition}} + +// Test dependently-sized array canonicalization +template<typename T, int N, int M> +void f1(T (&array)[N + M]) { } // expected-note{{previous}} + +template<typename T, int N, int M> +void f1(T (&array)[M + N]) { } + +template<typename T, int M, int N> +void f1(T (&array)[M + N]) { } // expected-error{{redefinition}} + +// Test dependently-sized extended vector type canonicalization +template<typename T, int N, int M> +struct X2 { + typedef T __attribute__((ext_vector_type(N))) type1; + typedef T __attribute__((ext_vector_type(M))) type2; + typedef T __attribute__((ext_vector_type(N))) type3; + + void f0(type1); // expected-note{{previous}} + void f0(type2); + void f0(type3); // expected-error{{redeclared}} +}; diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp index 71d8ea14be6b..e44115c748c3 100644 --- a/test/SemaTemplate/class-template-spec.cpp +++ b/test/SemaTemplate/class-template-spec.cpp @@ -1,5 +1,6 @@ // RUN: clang-cc -fsyntax-only -verify %s -template<typename T, typename U = int> struct A; // expected-note 2{{template is declared here}} +template<typename T, typename U = int> struct A; // expected-note {{template is declared here}} \ + // expected-note{{explicitly specialized}} template<> struct A<double, double>; // expected-note{{forward declaration}} @@ -19,7 +20,8 @@ int test_incomplete_specs(A<double, double> *a1, A<double> *a2) { (void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}} - (void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}} + (void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}} \ + // expected-note{{first required here}} } typedef float FLOAT; @@ -49,13 +51,33 @@ struct A<char> { A<char>::A() { } +// Make sure we can see specializations defined before the primary template. +namespace N{ + template<typename T> struct A0; +} + +namespace N { + template<> + struct A0<void> { + typedef void* pointer; + }; +} + +namespace N { + template<typename T> + struct A0 { + void foo(A0<void>::pointer p = 0); + }; +} + // Diagnose specialization errors -struct A<double> { }; // expected-error{{template specialization requires 'template<>'}} +struct A<double> { }; // expected-error{{template specialization requires 'template<>'}} \ + // expected-error{{after instantiation}} template<> struct ::A<double>; namespace N { - template<typename T> struct B; // expected-note 2{{template is declared here}} + template<typename T> struct B; // expected-note 2{{explicitly specialized}} template<> struct ::N::B<char>; // okay template<> struct ::N::B<short>; // okay @@ -66,12 +88,12 @@ namespace N { template<> struct N::B<int> { }; // okay -template<> struct N::B<float> { }; // expected-error{{class template specialization of 'B' not in namespace 'N'}} +template<> struct N::B<float> { }; // expected-error{{originally}} namespace M { template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}} - template<> struct ::A<long double>; // expected-error{{class template specialization of 'A' must occur in the global scope}} + template<> struct ::A<long double>; // expected-error{{originally}} } template<> struct N::B<char> { diff --git a/test/SemaTemplate/constructor-template.cpp b/test/SemaTemplate/constructor-template.cpp new file mode 100644 index 000000000000..acd845bc2fd5 --- /dev/null +++ b/test/SemaTemplate/constructor-template.cpp @@ -0,0 +1,53 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct X0 { // expected-note{{candidate}} + X0(int); // expected-note{{candidate}} + template<typename T> X0(T); + template<typename T, typename U> X0(T*, U*); + + // PR4761 + template<typename T> X0() : f0(T::foo) {} + int f0; +}; + +void accept_X0(X0); + +void test_X0(int i, float f) { + X0 x0a(i); + X0 x0b(f); + X0 x0c = i; + X0 x0d = f; + accept_X0(i); + accept_X0(&i); + accept_X0(f); + accept_X0(&f); + X0 x0e(&i, &f); + X0 x0f(&f, &i); + + X0 x0g(f, &i); // expected-error{{no matching constructor}} +} + +template<typename T> +struct X1 { + X1(const X1&); + template<typename U> X1(const X1<U>&); +}; + +template<typename T> +struct Outer { + typedef X1<T> A; + + A alloc; + + explicit Outer(const A& a) : alloc(a) { } +}; + +void test_X1(X1<int> xi) { + Outer<int> oi(xi); + Outer<float> of(xi); +} + +// PR4655 +template<class C> struct A {}; +template <> struct A<int>{A(const A<int>&);}; +struct B { A<int> x; B(B& a) : x(a.x) {} }; diff --git a/test/SemaTemplate/copy-ctor-assign.cpp b/test/SemaTemplate/copy-ctor-assign.cpp new file mode 100644 index 000000000000..90fb0133a721 --- /dev/null +++ b/test/SemaTemplate/copy-ctor-assign.cpp @@ -0,0 +1,36 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// Make sure that copy constructors and assignment operators are properly +// generated when there is a matching + +// PR5072 +template<typename T> +struct X { + template<typename U> + X(const X<U>& other) + : value(other.value + 1) { } // expected-error{{binary expression}} + + template<typename U> + X& operator=(const X<U>& other) { + value = other.value + 1; // expected-error{{binary expression}} + return *this; + } + + T value; +}; + +struct Y {}; + +X<int Y::*> test0(X<int Y::*> x) { return x; } +X<int> test1(X<long> x) { return x; } + + +X<int> test2(X<int Y::*> x) { + return x; // expected-note{{instantiation}} +} + +void test3(X<int> &x, X<int> xi, X<long> xl, X<int Y::*> xmptr) { + x = xi; + x = xl; + x = xmptr; // expected-note{{instantiation}} +}
\ No newline at end of file diff --git a/test/SemaTemplate/current-instantiation.cpp b/test/SemaTemplate/current-instantiation.cpp index 603c14016fbc..a1d9fcb5372b 100644 --- a/test/SemaTemplate/current-instantiation.cpp +++ b/test/SemaTemplate/current-instantiation.cpp @@ -69,3 +69,76 @@ struct X0 { void g8(typename ::X0<typename X0<T_type, U>::X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}} }; }; + + +template<typename T, typename U> +struct X0<T*, U*> { + typedef T T_type; + typedef U U_type; + typedef T* Tptr; + typedef U* Uptr; + + void f0(T&); // expected-note{{previous}} + void f0(typename X0::U_type&); + void f0(typename X0::T_type&); // expected-error{{redecl}} + + void f1(T&); // expected-note{{previous}} + void f1(typename X0::U_type&); + void f1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}} + + void f2(T&); // expected-note{{previous}} + void f2(typename X0::U_type&); + void f2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} + + void f3(T&); // expected-note{{previous}} + void f3(typename X0::U_type&); + void f3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} + + void f4(T&); // expected-note{{previous}} + void f4(typename X0::U_type&); + void f4(typename ::X0<Tptr, Uptr>::T_type&); // expected-error{{redecl}} + + void f5(X0*); // expected-note{{previous}} + void f5(::X0<T, U>*); + void f5(::X0<T*, U*>*); // expected-error{{redecl}} + + struct X2 { + typedef T my_T_type; + + void g0(T&); // expected-note{{previous}} + void g0(typename X0::U_type&); + void g0(typename X0::T_type&); // expected-error{{redecl}} + + void g1(T&); // expected-note{{previous}} + void g1(typename X0::U_type&); + void g1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}} + + void g2(T&); // expected-note{{previous}} + void g2(typename X0::U_type&); + void g2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} + + void g3(T&); // expected-note{{previous}} + void g3(typename X0::U_type&); + void g3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} + + void g4(T&); // expected-note{{previous}} + void g4(typename X0::U_type&); + void g4(typename X2::my_T_type&); // expected-error{{redecl}} + + void g5(T&); // expected-note{{previous}} + void g5(typename X0::U_type&); + void g5(typename X0::X2::my_T_type&); // expected-error{{redecl}} + + void g6(T&); // expected-note{{previous}} + void g6(typename X0::U_type&); + void g6(typename X0<T*, U*>::X2::my_T_type&); // expected-error{{redecl}} + + void g7(T&); // expected-note{{previous}} + void g7(typename X0::U_type&); + void g7(typename ::X0<typename X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}} + + void g8(T&); // expected-note{{previous}} + void g8(typename X0<U, T_type>::T_type&); + void g8(typename ::X0<typename X0<T_type*, U*>::X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}} + }; +}; diff --git a/test/SemaTemplate/default-arguments.cpp b/test/SemaTemplate/default-arguments.cpp index f9bb44ecb9c0..33677aab73ac 100644 --- a/test/SemaTemplate/default-arguments.cpp +++ b/test/SemaTemplate/default-arguments.cpp @@ -22,3 +22,23 @@ template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member na template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}} template struct p<int>; + +// PR5187 +template<typename T, typename U> +struct A; + +template<typename T, typename U = T> +struct A; + +template<typename T, typename U> +struct A { + void f(A<T>); +}; + +template<typename T> +struct B { }; + +template<> +struct B<void> { + typedef B<void*> type; +}; diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp new file mode 100644 index 000000000000..575283ed8b51 --- /dev/null +++ b/test/SemaTemplate/default-expr-arguments.cpp @@ -0,0 +1,86 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +class C { C(int a0 = 0); }; + +template<> +C<char>::C(int a0); + +struct S { }; + +template<typename T> void f1(T a, T b = 10) { } // expected-error{{cannot initialize 'b' with an rvalue of type 'int'}} + +template<typename T> void f2(T a, T b = T()) { } + +template<typename T> void f3(T a, T b = T() + T()); // expected-error{{invalid operands to binary expression ('struct S' and 'struct S')}} + +void g() { + f1(10); + f1(S()); // expected-note{{in instantiation of default function argument expression for 'f1<struct S>' required here}} + + f2(10); + f2(S()); + + f3(10); + f3(S()); // expected-note{{in instantiation of default function argument expression for 'f3<struct S>' required here}} +} + +template<typename T> struct F { + F(T t = 10); // expected-error{{cannot initialize 't' with an rvalue of type 'int'}} + void f(T t = 10); // expected-error{{cannot initialize 't' with an rvalue of type 'int'}} +}; + +struct FD : F<int> { }; + +void g2() { + F<int> f; + FD fd; +} + +void g3(F<int> f, F<struct S> s) { + f.f(); + s.f(); // expected-note{{in instantiation of default function argument expression for 'f<struct S>' required here}} + + F<int> f2; + F<S> s2; // expected-note{{in instantiation of default function argument expression for 'F<struct S>' required here}} +} + +template<typename T> struct G { + G(T) {} +}; + +void s(G<int> flags = 10) { } + +// Test default arguments +template<typename T> +struct X0 { + void f(T = T()); // expected-error{{no matching}} +}; + +template<typename U> +void X0<U>::f(U) { } + +void test_x0(X0<int> xi) { + xi.f(); + xi.f(17); +} + +struct NotDefaultConstructible { // expected-note{{candidate}} + NotDefaultConstructible(int); // expected-note{{candidate}} +}; + +void test_x0_not_default_constructible(X0<NotDefaultConstructible> xn) { + xn.f(NotDefaultConstructible(17)); + xn.f(42); + xn.f(); // expected-note{{in instantiation of default function argument}} +} + +template<typename T> +struct X1 { + typedef T value_type; + X1(const value_type& value = value_type()); +}; + +void test_X1() { + X1<int> x1; +} diff --git a/test/SemaTemplate/dependent-base-member-init.cpp b/test/SemaTemplate/dependent-base-member-init.cpp new file mode 100644 index 000000000000..b3d707b632b1 --- /dev/null +++ b/test/SemaTemplate/dependent-base-member-init.cpp @@ -0,0 +1,36 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// PR4381 +template<class T> struct X {}; +template<typename T> struct Y : public X<T>::X { }; + +// PR4621 +class A1 { + A1(int x) {} +}; +template<class C> class B1 : public A1 { + B1(C x) : A1(x.x) {} +}; +class A2 { A2(int x, int y); }; +template <class C> class B2 { + A2 x; + B2(C x) : x(x.x, x.y) {} +}; +template <class C> class B3 { + C x; + B3() : x(1,2) {} +}; + +// PR4627 +template<typename _Container> class insert_iterator { + _Container* container; + insert_iterator(_Container& __x) : container(&__x) {} +}; + +// PR4763 +template<typename T> struct s0 {}; +template<typename T> struct s0_traits {}; +template<typename T> struct s1 : s0<typename s0_traits<T>::t0> { + s1() {} +}; + diff --git a/test/SemaTemplate/dependent-type-identity.cpp b/test/SemaTemplate/dependent-type-identity.cpp index 739cb7f39fa3..b7c9040e6cb5 100644 --- a/test/SemaTemplate/dependent-type-identity.cpp +++ b/test/SemaTemplate/dependent-type-identity.cpp @@ -59,7 +59,7 @@ struct X1 { void f6(typename N::X2<U>::template apply<U> *); void f6(typename N::X2<U>::template apply<T> *); void f6(typename ::N::X2<type>::template apply<U_type> *); // expected-error{{redeclar}} - + void f7(typename N::X2<T>::template apply<U> *); // expected-note{{previous}} void f7(typename N::X2<U>::template apply<U> *); void f7(typename N::X2<U>::template apply<T> *); diff --git a/test/SemaTemplate/destructor-template.cpp b/test/SemaTemplate/destructor-template.cpp new file mode 100644 index 000000000000..a7c8d247f021 --- /dev/null +++ b/test/SemaTemplate/destructor-template.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename A> class s0 { + + template<typename B> class s1 : public s0<A> { + ~s1() {} + s0<A> ms0; + }; + +}; + + diff --git a/test/SemaTemplate/example-dynarray.cpp b/test/SemaTemplate/example-dynarray.cpp index 680ee04ba18e..0b8d605b623d 100644 --- a/test/SemaTemplate/example-dynarray.cpp +++ b/test/SemaTemplate/example-dynarray.cpp @@ -1,4 +1,4 @@ -// RUN: clang-cc -fsyntax-only -verify %s +// RUN: clang %s -o %t #include <stddef.h> #include <stdlib.h> #include <assert.h> @@ -24,6 +24,9 @@ public: } ~dynarray() { + for (unsigned I = 0, N = size(); I != N; ++I) + Start[I].~T(); + free(Start); } @@ -33,7 +36,9 @@ public: for (unsigned I = 0, N = other.size(); I != N; ++I) new (NewStart + I) T(other[I]); - // FIXME: destroy everything in Start + for (unsigned I = 0, N = size(); I != N; ++I) + Start[I].~T(); + free(Start); Start = NewStart; Last = End = NewStart + other.size(); @@ -43,33 +48,11 @@ public: unsigned size() const { return Last - Start; } unsigned capacity() const { return End - Start; } - void push_back(const T& value) { - if (Last == End) { - unsigned NewCapacity = capacity() * 2; - if (NewCapacity == 0) - NewCapacity = 4; - - T* NewStart = (T*)malloc(sizeof(T) * NewCapacity); - - unsigned Size = size(); - for (unsigned I = 0; I != Size; ++I) - new (NewStart + I) T(Start[I]); - - // FIXME: destruct old values - free(Start); - - Start = NewStart; - Last = Start + Size; - End = Start + NewCapacity; - } - - new (Last) T(value); - ++Last; - } - + void push_back(const T& value); + void pop_back() { - // FIXME: destruct old value --Last; + Last->~T(); } T& operator[](unsigned Idx) { @@ -108,6 +91,32 @@ public: T* Start, *Last, *End; }; +template<typename T> +void dynarray<T>::push_back(const T& value) { + if (Last == End) { + unsigned NewCapacity = capacity() * 2; + if (NewCapacity == 0) + NewCapacity = 4; + + T* NewStart = (T*)malloc(sizeof(T) * NewCapacity); + + unsigned Size = size(); + for (unsigned I = 0; I != Size; ++I) + new (NewStart + I) T(Start[I]); + + for (unsigned I = 0, N = size(); I != N; ++I) + Start[I].~T(); + free(Start); + + Start = NewStart; + Last = Start + Size; + End = Start + NewCapacity; + } + + new (Last) T(value); + ++Last; +} + struct Point { Point() { x = y = z = 0.0; } Point(const Point& other) : x(other.x), y(other.y), z(other.z) { } diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp new file mode 100644 index 000000000000..b9a4ad282b9f --- /dev/null +++ b/test/SemaTemplate/explicit-instantiation.cpp @@ -0,0 +1,75 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template void *; // expected-error{{expected unqualified-id}} + +template typedef void f0; // expected-error{{explicit instantiation of typedef}} + +int v0; // expected-note{{refers here}} +template int v0; // expected-error{{does not refer}} + +template<typename T> +struct X0 { + static T value; + + T f0(T x) { + return x + 1; // expected-error{{invalid operands}} + } + T* f0(T*, T*); + + template<typename U> + T f0(T, U); +}; + +template int X0<int>::value; + +struct NotDefaultConstructible { + NotDefaultConstructible(int); +}; + +template NotDefaultConstructible X0<NotDefaultConstructible>::value; + +template int X0<int>::f0(int); +template int* X0<int>::f0(int*, int*); +template int X0<int>::f0(int, float); + +template int X0<int>::f0(int) const; // expected-error{{does not refer}} +template int* X0<int>::f0(int*, float*); // expected-error{{does not refer}} + +struct X1 { }; +typedef int X1::*MemPtr; + +template MemPtr X0<MemPtr>::f0(MemPtr); // expected-note{{requested here}} + +struct X2 { + int f0(int); // expected-note{{refers here}} + + template<typename T> T f1(T); + template<typename T> T* f1(T*); + + template<typename T, typename U> void f2(T, U*); // expected-note{{candidate}} + template<typename T, typename U> void f2(T*, U); // expected-note{{candidate}} +}; + +template int X2::f0(int); // expected-error{{not an instantiation}} + +template int *X2::f1(int *); // okay + +template void X2::f2(int *, int *); // expected-error{{ambiguous}} + + +template<typename T> void print_type(); + +template void print_type<int>(); +template void print_type<float>(); + +template<typename T> void print_type(T*); + +template void print_type(int*); +template void print_type<int>(float*); // expected-error{{does not refer}} + +void print_type(double*); +template void print_type<double>(double*); + +// PR5069 +template<int I> void foo0 (int (&)[I + 1]) { } +template void foo0<2> (int (&)[3]); diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp new file mode 100644 index 000000000000..197dae5a15af --- /dev/null +++ b/test/SemaTemplate/explicit-specialization-member.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<typename T> +struct X0 { + typedef T* type; + + void f0(T); + void f1(type); +}; + +template<> void X0<char>::f0(char); +template<> void X0<char>::f1(type); diff --git a/test/SemaTemplate/ext-vector-type.cpp b/test/SemaTemplate/ext-vector-type.cpp index d6c02bb629ff..b6aebc102fb4 100644 --- a/test/SemaTemplate/ext-vector-type.cpp +++ b/test/SemaTemplate/ext-vector-type.cpp @@ -4,7 +4,7 @@ struct make1 { typedef T __attribute__((ext_vector_type(Length))) type; }; -int test_make1() { +void test_make1() { make1<int, 5>::type x; x.x = 4; } diff --git a/test/SemaTemplate/extern-templates.cpp b/test/SemaTemplate/extern-templates.cpp new file mode 100644 index 000000000000..28fda1a11e6b --- /dev/null +++ b/test/SemaTemplate/extern-templates.cpp @@ -0,0 +1,66 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +class X0 { +public: + void f(T t); + + struct Inner { + void g(T t); + }; +}; + +template<typename T> +void X0<T>::f(T t) { + t = 17; // expected-error{{incompatible}} +} + +extern template class X0<int>; + +extern template class X0<int*>; + +template<typename T> +void X0<T>::Inner::g(T t) { + t = 17; // expected-error{{incompatible}} +} + +void test_intptr(X0<int*> xi, X0<int*>::Inner xii) { + xi.f(0); + xii.g(0); +} + +// FIXME: we would like the notes to point to the explicit instantiation at the +// bottom. +extern template class X0<long*>; // expected-note 2{{instantiation}} + +void test_longptr(X0<long*> xl, X0<long*>::Inner xli) { + xl.f(0); + xli.g(0); +} + +template class X0<long*>; + +template<typename T> +class X1 { +public: + void f(T t) { t += 2; } + + void g(T t); +}; + +template<typename T> +void X1<T>::g(T t) { + t += 2; +} + +extern template class X1<void*>; + +void g_X1(X1<void*> x1, void *ptr) { + x1.g(ptr); +} + +extern template void X1<const void*>::g(const void*); + +void g_X1_2(X1<const void *> x1, const void *ptr) { + x1.g(ptr); +} diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp new file mode 100644 index 000000000000..761c13076d2a --- /dev/null +++ b/test/SemaTemplate/friend-template.cpp @@ -0,0 +1,64 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// PR5057 +namespace std { + class X { + public: + template<typename T> + friend struct Y; + }; +} + +namespace std { + template<typename T> + struct Y + { + }; +} + + +namespace N { + template<typename T> void f1(T) { } // expected-note{{here}} + + class X { + template<typename T> friend void f0(T); + template<typename T> friend void f1(T); + }; + + template<typename T> void f0(T) { } + template<typename T> void f1(T) { } // expected-error{{redefinition}} +} + +// PR4768 +template<typename T> +struct X0 { + template<typename U> friend struct X0; +}; + +template<typename T> +struct X0<T*> { + template<typename U> friend struct X0; +}; + +template<> +struct X0<int> { + template<typename U> friend struct X0; +}; + +template<typename T> +struct X1 { + template<typename U> friend void f2(U); + template<typename U> friend void f3(U); +}; + +template<typename U> void f2(U); + +X1<int> x1i; + +template<> void f2(int); + +// FIXME: Should this declaration of f3 be required for the specialization of +// f3<int> (further below) to work? GCC and EDG don't require it, we do... +template<typename U> void f3(U); + +template<> void f3(int); diff --git a/test/SemaTemplate/friend.cpp b/test/SemaTemplate/friend.cpp new file mode 100644 index 000000000000..27299523862e --- /dev/null +++ b/test/SemaTemplate/friend.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<typename T> struct A { + struct B { }; + + friend struct B; +}; + +void f() { + A<int>::B b; +} + +struct C0 { + friend struct A<int>; +}; diff --git a/test/SemaTemplate/fun-template-def.cpp b/test/SemaTemplate/fun-template-def.cpp index 8833ef4ddc1d..dee425007898 100644 --- a/test/SemaTemplate/fun-template-def.cpp +++ b/test/SemaTemplate/fun-template-def.cpp @@ -10,8 +10,13 @@ namespace std { class type_info {}; } struct dummy {}; +template<typename T> +int f0(T x) { + return (sizeof(x) == sizeof(int))? 0 : (sizeof(x) == sizeof(double))? 1 : 2; +} + template <typename T, typename U> -T f(T t1, U u1, int i1) +T f1(T t1, U u1, int i1) { T t2 = i1; t2 = i1 + u1; diff --git a/test/SemaTemplate/function-template-specialization.cpp b/test/SemaTemplate/function-template-specialization.cpp new file mode 100644 index 000000000000..90e38cc882fe --- /dev/null +++ b/test/SemaTemplate/function-template-specialization.cpp @@ -0,0 +1,35 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<int N> void f0(int (&array)[N]); + +// Simple function template specialization (using overloading) +template<> void f0(int (&array)[1]); + +void test_f0() { + int iarr1[1]; + f0(iarr1); +} + +// Function template specialization where there are no matches +template<> void f0(char (&array)[1]); // expected-error{{no function template matches}} +template<> void f0<2>(int (&array)[2]) { } + +// Function template specialization that requires partial ordering +template<typename T, int N> void f1(T (&array)[N]); // expected-note{{matches}} +template<int N> void f1(int (&array)[N]); // expected-note{{matches}} + +template<> void f1(float (&array)[1]); +template<> void f1(int (&array)[1]); + +// Function template specialization that results in an ambiguity +template<typename T> void f1(T (&array)[17]); // expected-note{{matches}} +template<> void f1(int (&array)[17]); // expected-error{{ambiguous}} + +// Resolving that ambiguity with explicitly-specified template arguments. +template<int N> void f2(double (&array)[N]); +template<typename T> void f2(T (&array)[42]); + +template<> void f2<double>(double (&array)[42]); +template<> void f2<42>(double (&array)[42]); + +void f2<25>(double (&array)[25]); // expected-error{{specialization}} diff --git a/test/SemaTemplate/implicit-instantiation-1.cpp b/test/SemaTemplate/implicit-instantiation-1.cpp index b8f9622001e1..d04bbd848407 100644 --- a/test/SemaTemplate/implicit-instantiation-1.cpp +++ b/test/SemaTemplate/implicit-instantiation-1.cpp @@ -22,4 +22,4 @@ void test_add(char *cp, int i, int *ip) { char* cp2 = add(cp, i); add(cp, cp); // expected-note{{instantiation of}} (void)sizeof(add(ip, ip)); -}
\ No newline at end of file +} diff --git a/test/SemaTemplate/injected-class-name.cpp b/test/SemaTemplate/injected-class-name.cpp index c5f826d849ca..f9674c39a58b 100644 --- a/test/SemaTemplate/injected-class-name.cpp +++ b/test/SemaTemplate/injected-class-name.cpp @@ -19,7 +19,7 @@ X<float>::X<int> xi = x; // [temp.local]p1: -// FIXME: test non-type and template template parameters +// FIXME: test template template parameters template<typename T, typename U> struct X0 { typedef T type; @@ -38,3 +38,11 @@ struct X0 { void f2(X0&); void f2(const ::X0<type, U_type2>&); // expected-error{{redecl}} }; + +template<typename T, T N> +struct X1 { + void f0(const X1&); // expected-note{{here}} + void f0(X1&); + void f0(const X1<T, N>&); // expected-error{{redecl}} +}; + diff --git a/test/SemaTemplate/instantiate-anonymous-union.cpp b/test/SemaTemplate/instantiate-anonymous-union.cpp new file mode 100644 index 000000000000..375c1da3ca59 --- /dev/null +++ b/test/SemaTemplate/instantiate-anonymous-union.cpp @@ -0,0 +1,31 @@ +// RUN: clang-cc -fsyntax-only %s -Wall + +template <typename T> class A { struct { }; }; + +A<int> a0; + +template <typename T> struct B { + union { + int a; + void* b; + }; + + void f() { + a = 10; + b = 0; + } +}; + +B<int> b0; + +template <typename T> struct C { + union { + int a; + void* b; + }; + + C(int a) : a(a) { } + C(void* b) : b(b) { } +}; + +C<int> c0(0); diff --git a/test/SemaTemplate/instantiate-cast.cpp b/test/SemaTemplate/instantiate-cast.cpp index d99f3e556602..6b3fc6e12534 100644 --- a/test/SemaTemplate/instantiate-cast.cpp +++ b/test/SemaTemplate/instantiate-cast.cpp @@ -1,6 +1,6 @@ // RUN: clang-cc -fsyntax-only -verify %s -struct A { int x; }; +struct A { int x; }; class Base { public: @@ -23,7 +23,7 @@ struct Constructible { template<typename T, typename U> struct CStyleCast0 { void f(T t) { - (void)((U)t); // FIXME:ugly expected-error{{operand}} + (void)((U)t); // expected-error{{C-style cast from 'struct A' to 'int'}} } }; @@ -36,7 +36,7 @@ template struct CStyleCast0<A, int>; // expected-note{{instantiation}} template<typename T, typename U> struct StaticCast0 { void f(T t) { - (void)static_cast<U>(t); // expected-error{{static_cast}} + (void)static_cast<U>(t); // expected-error{{static_cast from 'int' to 'struct A' is not allowed}} } }; @@ -89,7 +89,7 @@ template struct ConstCast0<int const *, float *>; // expected-note{{instantiatio template<typename T, typename U> struct FunctionalCast1 { void f(T t) { - (void)U(t); // FIXME:ugly expected-error{{operand}} + (void)U(t); // expected-error{{functional-style cast from 'struct A' to 'int'}} } }; diff --git a/test/SemaTemplate/instantiate-deeply.cpp b/test/SemaTemplate/instantiate-deeply.cpp new file mode 100644 index 000000000000..27e430be5cbe --- /dev/null +++ b/test/SemaTemplate/instantiate-deeply.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only -Wall -verify %s + +template<typename a> struct A { + template <typename b> struct B { + template <typename c> struct C { + template <typename d> struct D { + template <typename e> struct E { + e field; + E() : field(0) { + d v1 = 4; + c v2 = v1 * v1; + b v3 = 8; + a v4 = v3 * v3; + field += v2 + v4; + } + }; + }; + }; + }; +}; + +A<int>::B<int>::C<int>::D<int>::E<int> global; diff --git a/test/SemaTemplate/instantiate-expr-2.cpp b/test/SemaTemplate/instantiate-expr-2.cpp index 80f403ed56fe..146e63c5bb00 100644 --- a/test/SemaTemplate/instantiate-expr-2.cpp +++ b/test/SemaTemplate/instantiate-expr-2.cpp @@ -130,3 +130,51 @@ struct X0 { void test_X0(X0<int> x, IntegralConstant<int, sizeof(int)> ic) { x.f(5,ic); } + +namespace N8 { + struct X { + X operator+(const X&) const; + }; + + template<typename T> + T test_plus(const T* xp, const T& x, const T& y) { + x.operator+(y); + return xp->operator+(y); + } + + void test_test_plus(X x) { + test_plus(&x, x, x); + } +} + +namespace N9 { + struct A { + bool operator==(int value); + }; + + template<typename T> struct B { + bool f(A a) { + return a == 1; + } + }; + + template struct B<int>; +} + +namespace N10 { + template <typename T> + class A { + struct X { }; + + public: + ~A() { + f(reinterpret_cast<X *>(0), reinterpret_cast<X *>(0)); + } + + private: + void f(X *); + void f(X *, X *); + }; + + template class A<int>; +} diff --git a/test/SemaTemplate/instantiate-expr-5.cpp b/test/SemaTemplate/instantiate-expr-5.cpp new file mode 100644 index 000000000000..b42c0fb2aaf8 --- /dev/null +++ b/test/SemaTemplate/instantiate-expr-5.cpp @@ -0,0 +1,4 @@ +// RUN: clang-cc -fsyntax-only %s + +template <class A> int x(A x) { return x++; } +int y() { return x<int>(1); } diff --git a/test/SemaTemplate/instantiate-friend-class.cpp b/test/SemaTemplate/instantiate-friend-class.cpp new file mode 100644 index 000000000000..9a4a73cc8a52 --- /dev/null +++ b/test/SemaTemplate/instantiate-friend-class.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc -fsyntax-only -verify %s +// PR4794 + +template <class T> class X +{ + friend class Y; +}; +X<int> y; + diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp index 023cc5437f69..2749ec24401b 100644 --- a/test/SemaTemplate/instantiate-function-1.cpp +++ b/test/SemaTemplate/instantiate-function-1.cpp @@ -140,7 +140,7 @@ template<typename T> struct Member0 { tp->f; this->f; - this.f; // expected-error{{member reference base type 'Member0<T> *const' is not a structure or union}} + this.f; // expected-error{{member reference base type 'Member0<T> *' is not a structure or union}} } }; diff --git a/test/SemaTemplate/instantiate-function-1.mm b/test/SemaTemplate/instantiate-function-1.mm index aef2d9dbb7eb..be995e7ff615 100644 --- a/test/SemaTemplate/instantiate-function-1.mm +++ b/test/SemaTemplate/instantiate-function-1.mm @@ -1,3 +1,6 @@ +// RUN: clang-cc -fsyntax-only -verify %s +// XFAIL + template<typename T> struct Member0 { void f(T t) { t; diff --git a/test/SemaTemplate/instantiate-init.cpp b/test/SemaTemplate/instantiate-init.cpp new file mode 100644 index 000000000000..870b27537fce --- /dev/null +++ b/test/SemaTemplate/instantiate-init.cpp @@ -0,0 +1,28 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct X0 { // expected-note 4{{candidate}} + X0(int*, float*); // expected-note 4{{candidate}} +}; + +template<typename T, typename U> +X0 f0(T t, U u) { + X0 x0(t, u); // expected-error{{no matching}} + return X0(t, u); // expected-error{{no matching}} +} + +void test_f0(int *ip, float *fp, double *dp) { + f0(ip, fp); + f0(ip, dp); // expected-note{{instantiation}} +} + +template<typename Ret, typename T, typename U> +Ret f1(Ret *retty, T t, U u) { + Ret r0(t, u); // expected-error{{no matching}} + return Ret(t, u); // expected-error{{no matching}} +} + +void test_f1(X0 *x0, int *ip, float *fp, double *dp) { + f1(x0, ip, fp); + f1(x0, ip, dp); // expected-note{{instantiation}} +} + diff --git a/test/SemaTemplate/instantiate-member-initializers.cpp b/test/SemaTemplate/instantiate-member-initializers.cpp new file mode 100644 index 000000000000..6fc70429a9d3 --- /dev/null +++ b/test/SemaTemplate/instantiate-member-initializers.cpp @@ -0,0 +1,26 @@ +// RUN: clang-cc -fsyntax-only -Wall -verify %s + +template<typename T> struct A { + A() : a(1) { } // expected-error{{incompatible type passing 'int', expected 'void *'}} + + T a; +}; + +A<int> a0; +A<void*> a1; // expected-note{{in instantiation of member function 'A<void *>::A' requested here}} + +template<typename T> struct B { + // FIXME: This should warn about initialization order + B() : b(1), a(2) { } + + int a; + int b; +}; + +B<int> b0; + +template <class T> struct AA { AA(int); }; +template <class T> class BB : public AA<T> { + BB() : AA<T>(1) {} +}; +BB<int> x; diff --git a/test/SemaTemplate/instantiate-member-template.cpp b/test/SemaTemplate/instantiate-member-template.cpp new file mode 100644 index 000000000000..36f3b6fd490d --- /dev/null +++ b/test/SemaTemplate/instantiate-member-template.cpp @@ -0,0 +1,105 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct X0 { + template<typename U> T f0(U); + template<typename U> U& f1(T*, U); // expected-error{{pointer to a reference}} \ + // expected-note{{candidate}} +}; + +X0<int> x0i; +X0<void> x0v; +X0<int&> x0ir; // expected-note{{instantiation}} + +void test_X0(int *ip, double *dp) { + X0<int> xi; + int i1 = xi.f0(ip); + double *&dpr = xi.f1(ip, dp); + xi.f1(dp, dp); // expected-error{{no matching}} + + X0<void> xv; + double *&dpr2 = xv.f1(ip, dp); +} + +template<typename T> +struct X1 { + template<typename U> + struct Inner0 { + U x; + T y; // expected-error{{void}} + }; + + template<typename U> + struct Inner1 { + U x; // expected-error{{void}} + T y; + }; + + template<typename U> + struct Inner2 { + struct SuperInner { + U z; // expected-error{{void}} + }; + }; + + template<typename U> + struct Inner3 { + void f0(T t, U u) { + (void)(t + u); // expected-error{{invalid operands}} + } + + template<typename V> + V f1(T t, U u, V) { + return t + u; // expected-error{{incompatible type}} + } + }; + + template<typename U> + struct Inner4; +}; + +template<typename T> +template<typename U> +struct X1<T>::Inner4 { + template<typename V> + V f2(T t, U u, V); + + static U value; +}; + +template<typename T> +template<typename U> +U X1<T>::Inner4<U>::value; // expected-error{{reference variable}} + +template<typename T> +template<typename U> +template<typename V> +V X1<T>::Inner4<U>::f2(T t, U u, V) { + return t + u; // expected-error{{incompatible type}} +} + +void test_X1(int *ip, int i, double *dp) { + X1<void>::Inner0<int> *xvip; // okay + X1<void>::Inner0<int> xvi; // expected-note{{instantiation}} + + X1<int>::Inner1<void> *xivp; // okay + X1<int>::Inner1<void> xiv; // expected-note{{instantiation}} + + X1<int>::Inner2<void>::SuperInner *xisivp; // okay + X1<int>::Inner2<void>::SuperInner xisiv; // expected-note{{instantiation}} + + X1<int*>::Inner3<int> id3; + id3.f0(ip, i); + id3.f0(dp, i); // expected-error{{incompatible type}} + id3.f1(ip, i, ip); + id3.f1(ip, i, dp); // expected-note{{instantiation}} + + X1<int*>::Inner3<double*> id3b; + id3b.f0(ip, dp); // expected-note{{instantiation}} + + X1<int*>::Inner4<int> id4; + id4.f2(ip, i, dp); // expected-note{{instantiation}} + + X1<int*>::Inner4<int>::value = 17; + i = X1<int*>::Inner4<int&>::value; // expected-note{{instantiation}} +} diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp index daea7465dc12..f7c09ef87900 100644 --- a/test/SemaTemplate/instantiate-method.cpp +++ b/test/SemaTemplate/instantiate-method.cpp @@ -72,3 +72,12 @@ void test_converts_to(ConvertsTo<int> ci, ConvertsTo<int *> cip) { int i = ci; int *ip = cip; } + +// PR4660 +template<class T> struct A0 { operator T*(); }; +template<class T> struct A1; + +int *a(A0<int> &x0, A1<int> &x1) { + int *y0 = x0; + int *y1 = x1; // expected-error{{initializing}} +} diff --git a/test/SemaTemplate/instantiate-static-var.cpp b/test/SemaTemplate/instantiate-static-var.cpp index 99e6b9cc06c3..96fa34cc2aff 100644 --- a/test/SemaTemplate/instantiate-static-var.cpp +++ b/test/SemaTemplate/instantiate-static-var.cpp @@ -16,3 +16,25 @@ class Y { }; Y<float> fy; // expected-note{{in instantiation of template class 'class Y<float>' requested here}} + + +// out-of-line static member variables + +template<typename T> +struct Z { + static T value; +}; + +template<typename T> +T Z<T>::value; // expected-error{{no matching constructor}} + +struct DefCon {}; + +struct NoDefCon { + NoDefCon(const NoDefCon&); +}; + +void test() { + DefCon &DC = Z<DefCon>::value; + NoDefCon &NDC = Z<NoDefCon>::value; // expected-note{{instantiation}} +} diff --git a/test/SemaTemplate/instantiate-typedef.cpp b/test/SemaTemplate/instantiate-typedef.cpp index d30309cc86ca..e092b531582b 100644 --- a/test/SemaTemplate/instantiate-typedef.cpp +++ b/test/SemaTemplate/instantiate-typedef.cpp @@ -12,5 +12,5 @@ add_pointer<float>::type test2(int * ptr) { } add_pointer<int&>::type // expected-note{{in instantiation of template class 'struct add_pointer<int &>' requested here}} \ -// expected-error {{unknown type name 'type'}} +// expected-error {{no type named 'type' in 'struct add_pointer<int &>'}} test3(); diff --git a/test/SemaTemplate/instantiate-using-decl.cpp b/test/SemaTemplate/instantiate-using-decl.cpp new file mode 100644 index 000000000000..fd9010fa4bbb --- /dev/null +++ b/test/SemaTemplate/instantiate-using-decl.cpp @@ -0,0 +1,17 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct A { + void f(); +}; + +template<typename T> +struct B : A<T> { + using A<T>::f; + + void g() { + f(); + } +}; + +template struct B<int>; diff --git a/test/SemaTemplate/member-access-expr.cpp b/test/SemaTemplate/member-access-expr.cpp new file mode 100644 index 000000000000..f4922e8ff520 --- /dev/null +++ b/test/SemaTemplate/member-access-expr.cpp @@ -0,0 +1,77 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<typename T> +void call_f0(T x) { + x.Base::f0(); +} + +struct Base { + void f0(); +}; + +struct X0 : Base { + typedef Base CrazyBase; +}; + +void test_f0(X0 x0) { + call_f0(x0); +} + +template<typename TheBase, typename T> +void call_f0_through_typedef(T x) { + typedef TheBase Base2; + x.Base2::f0(); +} + +void test_f0_through_typedef(X0 x0) { + call_f0_through_typedef<Base>(x0); +} + +template<typename TheBase, typename T> +void call_f0_through_typedef2(T x) { + typedef TheBase CrazyBase; // expected-note{{current scope}} + x.CrazyBase::f0(); // expected-error{{ambiguous}} \ + // expected-error 2{{no member named}} +} + +struct OtherBase { }; + +struct X1 : Base, OtherBase { + typedef OtherBase CrazyBase; // expected-note{{object type}} +}; + +void test_f0_through_typedef2(X0 x0, X1 x1) { + call_f0_through_typedef2<Base>(x0); + call_f0_through_typedef2<OtherBase>(x1); // expected-note{{instantiation}} + call_f0_through_typedef2<Base>(x1); // expected-note{{instantiation}} +} + + +struct X2 { + operator int() const; +}; + +template<typename T, typename U> +T convert(const U& value) { + return value.operator T(); // expected-error{{operator long}} +} + +void test_convert(X2 x2) { + convert<int>(x2); + convert<long>(x2); // expected-note{{instantiation}} +} + +template<typename T> +void destruct(T* ptr) { + ptr->~T(); +} + +template<typename T> +void destruct_intptr(int *ip) { + ip->~T(); +} + +void test_destruct(X2 *x2p, int *ip) { + destruct(x2p); + destruct(ip); + destruct_intptr<int>(ip); +}
\ No newline at end of file diff --git a/test/SemaTemplate/member-function-template.cpp b/test/SemaTemplate/member-function-template.cpp new file mode 100644 index 000000000000..83bf16c69004 --- /dev/null +++ b/test/SemaTemplate/member-function-template.cpp @@ -0,0 +1,51 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct X { + template<typename T> T& f0(T); + + void g0(int i, double d) { + int &ir = f0(i); + double &dr = f0(d); + } + + template<typename T> T& f1(T); + template<typename T, typename U> U& f1(T, U); + + void g1(int i, double d) { + int &ir1 = f1(i); + int &ir2 = f1(d, i); + int &ir3 = f1(i, i); + } +}; + +void test_X_f0(X x, int i, float f) { + int &ir = x.f0(i); + float &fr = x.f0(f); +} + +void test_X_f1(X x, int i, float f) { + int &ir1 = x.f1(i); + int &ir2 = x.f1(f, i); + int &ir3 = x.f1(i, i); +} + +void test_X_f0_address() { + int& (X::*pm1)(int) = &X::f0; + float& (X::*pm2)(float) = &X::f0; +} + +void test_X_f1_address() { + int& (X::*pm1)(int) = &X::f1; + float& (X::*pm2)(float) = &X::f1; + int& (X::*pm3)(float, int) = &X::f1; +} + +void test_X_f0_explicit(X x, int i, long l) { + int &ir1 = x.f0<int>(i); + int &ir2 = x.f0<>(i); + long &il1 = x.f0<long>(i); +} + +// PR4608 +class A { template <class x> x a(x z) { return z+y; } int y; }; + diff --git a/test/SemaTemplate/member-initializers.cpp b/test/SemaTemplate/member-initializers.cpp new file mode 100644 index 000000000000..62077fabc721 --- /dev/null +++ b/test/SemaTemplate/member-initializers.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> struct A { + A() : j(10), i(10) { } + + int i; + int j; +}; + +template<typename T> struct B : A<T> { + B() : A<T>() { } +}; + diff --git a/test/SemaTemplate/member-template-access-expr.cpp b/test/SemaTemplate/member-template-access-expr.cpp new file mode 100644 index 000000000000..20437aee39dc --- /dev/null +++ b/test/SemaTemplate/member-template-access-expr.cpp @@ -0,0 +1,30 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename U, typename T> +U f0(T t) { + return t.template get<U>(); +} + +template<typename U, typename T> +int &f1(T t) { + // FIXME: When we pretty-print this, we lose the "template" keyword. + return t.U::template get<int&>(); +} + +struct X { + template<typename T> T get(); +}; + +void test_f0(X x) { + int i = f0<int>(x); + int &ir = f0<int&>(x); +} + +struct XDerived : public X { +}; + +void test_f1(XDerived xd) { + // FIXME: Not quite functional yet. +// int &ir = f1<X>(xd); +} + diff --git a/test/SemaTemplate/metafun-apply.cpp b/test/SemaTemplate/metafun-apply.cpp index 9261ed6a6c96..471b2ad3fae6 100644 --- a/test/SemaTemplate/metafun-apply.cpp +++ b/test/SemaTemplate/metafun-apply.cpp @@ -35,7 +35,8 @@ void test() { apply1<add_reference, void>::type t; // expected-note{{in instantiation of template class 'struct apply1<struct add_reference, void>' requested here}} \ // FIXME: expected-error{{unexpected type name 'type': expected expression}} - apply1<bogus, int>::type t2; // expected-note{{in instantiation of template class 'struct apply1<struct bogus, int>' requested here}} + apply1<bogus, int>::type t2; // expected-note{{in instantiation of template class 'struct apply1<struct bogus, int>' requested here}} \ + // FIXME: expected-error{{unexpected type name 'type': expected expression}} } diff --git a/test/SemaTemplate/nested-linkage.cpp b/test/SemaTemplate/nested-linkage.cpp new file mode 100644 index 000000000000..ffe9adc927d6 --- /dev/null +++ b/test/SemaTemplate/nested-linkage.cpp @@ -0,0 +1,3 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +extern "C" { extern "C++" { template<class C> C x(); } } diff --git a/test/SemaTemplate/nested-template.cpp b/test/SemaTemplate/nested-template.cpp index 84b1d35ba91d..5ee2c9954005 100644 --- a/test/SemaTemplate/nested-template.cpp +++ b/test/SemaTemplate/nested-template.cpp @@ -1,5 +1,4 @@ // RUN: clang-cc -fsyntax-only -verify %s - class A; class S { @@ -14,3 +13,91 @@ public: int i; S::A<int>::Nested::type *ip = &i; +template<typename T> +struct Outer { + template<typename U> + class Inner0; + + template<typename U> + class Inner1 { + struct ReallyInner; + + T foo(U); + template<typename V> T bar(V); + template<typename V> T* bar(V); + + static T value1; + static U value2; + }; +}; + +template<typename X> +template<typename Y> +class Outer<X>::Inner0 { +public: + void f(X, Y); +}; + +template<typename X> +template<typename Y> +void Outer<X>::Inner0<Y>::f(X, Y) { +} + +template<typename X> +template<typename Y> +struct Outer<X>::Inner1<Y>::ReallyInner { + static Y value3; + + void g(X, Y); +}; + +template<typename X> +template<typename Y> +void Outer<X>::Inner1<Y>::ReallyInner::g(X, Y) { +} + +template<typename X> +template<typename Y> +X Outer<X>::Inner1<Y>::foo(Y) { + return X(); +} + +template<typename X> +template<typename Y> +template<typename Z> +X Outer<X>::Inner1<Y>::bar(Z) { + return X(); +} + +template<typename X> +template<typename Y> +template<typename Z> +X* Outer<X>::Inner1<Y>::bar(Z) { + return 0; +} + +template<typename X> +template<typename Y> +X Outer<X>::Inner1<Y>::value1 = 0; + +template<typename X> +template<typename Y> +Y Outer<X>::Inner1<Y>::value2 = Y(); + +template<typename X> +template<typename Y> +Y Outer<X>::Inner1<Y>::ReallyInner::value3 = Y(); + +template<typename X> +template<typename Y> +Y Outer<X>::Inner1<Y*>::ReallyInner::value4; // expected-error{{Outer<X>::Inner1<Y *>::ReallyInner::}} + + +template<typename T> +struct X0 { }; + +template<typename T> +struct X0<T*> { + template<typename U> + void f(U u = T()) { } +}; diff --git a/test/SemaTemplate/partial-spec-instantiate.cpp b/test/SemaTemplate/partial-spec-instantiate.cpp new file mode 100644 index 000000000000..8d1ae238977c --- /dev/null +++ b/test/SemaTemplate/partial-spec-instantiate.cpp @@ -0,0 +1,20 @@ +// RUN: clang-cc -fsyntax-only %s + +// PR4607 +template <class T> struct X {}; + +template <> struct X<char> +{ + static char* g(); +}; + +template <class T> struct X2 {}; + +template <class U> +struct X2<U*> { + static void f() { + X<U>::g(); + } +}; + +void a(char *a, char *b) {X2<char*>::f();} diff --git a/test/SemaTemplate/qualified-id.cpp b/test/SemaTemplate/qualified-id.cpp new file mode 100644 index 000000000000..85efab2b5cc9 --- /dev/null +++ b/test/SemaTemplate/qualified-id.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// PR5061 +namespace a { + template <typename T> class C {}; +} +namespace b { + template<typename T> void f0(a::C<T> &a0) { } +} diff --git a/test/SemaTemplate/qualified-names-diag.cpp b/test/SemaTemplate/qualified-names-diag.cpp index c875332905fb..1d53e5cb98ba 100644 --- a/test/SemaTemplate/qualified-names-diag.cpp +++ b/test/SemaTemplate/qualified-names-diag.cpp @@ -1,7 +1,7 @@ // RUN: clang-cc -fsyntax-only -verify %s namespace std { - template<typename T> class vector { }; + template<typename T> class vector { }; // expected-note{{candidate}} } typedef int INT; diff --git a/test/SemaTemplate/temp_class_order.cpp b/test/SemaTemplate/temp_class_order.cpp new file mode 100644 index 000000000000..4687ddf7d9e9 --- /dev/null +++ b/test/SemaTemplate/temp_class_order.cpp @@ -0,0 +1,42 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T, typename U> +struct X1 { + static const int value = 0; +}; + +template<typename T, typename U> +struct X1<T*, U*> { + static const int value = 1; +}; + +template<typename T> +struct X1<T*, T*> { + static const int value = 2; +}; + +template<typename T> +struct X1<const T*, const T*> { + static const int value = 3; +}; + +int array0[X1<int, int>::value == 0? 1 : -1]; +int array1[X1<int*, float*>::value == 1? 1 : -1]; +int array2[X1<int*, int*>::value == 2? 1 : -1]; +typedef const int* CIP; +int array3[X1<const int*, CIP>::value == 3? 1 : -1]; + +template<typename T, typename U> +struct X2 { }; + +template<typename T, typename U> +struct X2<T*, U> { }; // expected-note{{matches}} + +template<typename T, typename U> +struct X2<T, U*> { }; // expected-note{{matches}} + +template<typename T, typename U> +struct X2<const T*, const U*> { }; + +X2<int*, int*> x2a; // expected-error{{ambiguous}} +X2<const int*, const int*> x2b; diff --git a/test/SemaTemplate/temp_class_spec.cpp b/test/SemaTemplate/temp_class_spec.cpp index 1a534236c8eb..dad857e8e66d 100644 --- a/test/SemaTemplate/temp_class_spec.cpp +++ b/test/SemaTemplate/temp_class_spec.cpp @@ -16,8 +16,7 @@ struct is_pointer<const T*> { int array0[is_pointer<int>::value? -1 : 1]; int array1[is_pointer<int*>::value? 1 : -1]; -int array2[is_pointer<const int*>::value? 1 : -1]; // expected-error{{partial ordering}} \ -// expected-error{{negative}} +int array2[is_pointer<const int*>::value? 1 : -1]; template<typename T> struct is_lvalue_reference { @@ -32,6 +31,38 @@ struct is_lvalue_reference<T&> { int lvalue_ref0[is_lvalue_reference<int>::value? -1 : 1]; int lvalue_ref1[is_lvalue_reference<const int&>::value? 1 : -1]; +template<typename T> +struct is_const { + static const bool value = false; +}; + +template<typename T> +struct is_const<const T> { + static const bool value = true; +}; + +int is_const0[is_const<int>::value? -1 : 1]; +int is_const1[is_const<const int>::value? 1 : -1]; +int is_const2[is_const<const volatile int>::value? 1 : -1]; +int is_const3[is_const<const int [3]>::value? 1 : -1]; +int is_const4[is_const<const volatile int[3]>::value? 1 : -1]; +int is_const5[is_const<volatile int[3]>::value? -1 : 1]; + +template<typename T> +struct is_volatile { + static const bool value = false; +}; + +template<typename T> +struct is_volatile<volatile T> { + static const bool value = true; +}; + +int is_volatile0[is_volatile<int>::value? -1 : 1]; +int is_volatile1[is_volatile<volatile int>::value? 1 : -1]; +int is_volatile2[is_volatile<const volatile int>::value? 1 : -1]; +int is_volatile3[is_volatile<volatile char[3]>::value? 1 : -1]; + template<typename T, typename U> struct is_same { static const bool value = false; @@ -62,7 +93,20 @@ struct remove_reference<T&> { int remove_ref0[is_same<remove_reference<int>::type, int>::value? 1 : -1]; int remove_ref1[is_same<remove_reference<int&>::type, int>::value? 1 : -1]; - + +template<typename T> +struct remove_const { + typedef T type; +}; + +template<typename T> +struct remove_const<const T> { + typedef T type; +}; + +int remove_const0[is_same<remove_const<const int>::type, int>::value? 1 : -1]; +int remove_const1[is_same<remove_const<const int[3]>::type, int[3]>::value? 1 : -1]; + template<typename T> struct is_incomplete_array { static const bool value = false; @@ -104,6 +148,24 @@ struct get_array_size<T[N]> { int array_size0[get_array_size<int[12]>::value == 12? 1 : -1]; template<typename T> +struct remove_extent { + typedef T type; +}; + +template<typename T> +struct remove_extent<T[]> { + typedef T type; +}; + +template<typename T, unsigned N> +struct remove_extent<T[N]> { + typedef T type; +}; + +int remove_extent0[is_same<remove_extent<int[][5]>::type, int[5]>::value? 1 : -1]; +int remove_extent1[is_same<remove_extent<const int[][5]>::type, const int[5]>::value? 1 : -1]; + +template<typename T> struct is_unary_function { static const bool value = false; }; @@ -261,3 +323,10 @@ template<class T, int I> class A<T, T*, I> { }; //#2 template<class T1, class T2, int I> class A<T1*, T2, I> { }; //#3 template<class T> class A<int, T*, 5> { }; //#4 template<class T1, class T2, int I> class A<T1, T2*, I> { }; //#5 + +// Redefinition of class template partial specializations +template<typename T, T N, typename U> class A0; + +template<typename T, T N> class A0<T, N, int> { }; // expected-note{{here}} +template<typename T, T N> class A0<T, N, int>; +template<typename T, T N> class A0<T, N, int> { }; // expected-error{{redef}} diff --git a/test/SemaTemplate/temp_class_spec_neg.cpp b/test/SemaTemplate/temp_class_spec_neg.cpp index b50bd8f634aa..a029f474fc58 100644 --- a/test/SemaTemplate/temp_class_spec_neg.cpp +++ b/test/SemaTemplate/temp_class_spec_neg.cpp @@ -9,7 +9,7 @@ namespace N { } template<typename T> -struct N::M::A<T*> { }; // expected-error{{not in namespace}} +struct N::M::A<T*> { }; // expected-error{{originally}} // C++ [temp.class.spec]p9 // bullet 1 @@ -25,7 +25,7 @@ template <class T, T* t> struct C<T*, t>; // okay template< int X, int (*array_ptr)[X] > class A2 {}; // expected-note{{here}} int array[5]; -template< int X > class A2<X,&array> { }; // expected-error{{specializes}} +template< int X > class A2<X, &array> { }; // expected-error{{specializes}} template<typename T, int N, template<typename X> class TT> struct Test0; diff --git a/test/SemaTemplate/temp_func_order.cpp b/test/SemaTemplate/temp_func_order.cpp new file mode 100644 index 000000000000..5fd7c8d74571 --- /dev/null +++ b/test/SemaTemplate/temp_func_order.cpp @@ -0,0 +1,95 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<typename T> +int &f0(T); + +template<typename T> +float &f0(T*); + +void test_f0(int i, int *ip) { + int &ir = f0(i); + float &fr = f0(ip); +} + +template<typename T, typename U> +int &f1(T, U); + +template<typename T> +float &f1(T, T); + +void test_f1(int i, float f) { + int &ir = f1(i, f); + float &fr1 = f1(i, i); + float &fr2 = f1(f, f); +} + +template<typename T, typename U> +struct A { }; + +template<typename T> +int &f2(T); + +template<typename T, typename U> +float &f2(A<T, U>); + +template<typename T> +double &f2(A<T, T>); + +void test_f2(int i, A<int, float> aif, A<int, int> aii) { + int &ir = f2(i); + float &fr = f2(aif); + double &dr = f2(aii); +} + +template<typename T, typename U> +int &f3(T*, U); // expected-note{{candidate}} + +template<typename T, typename U> +float &f3(T, U*); // expected-note{{candidate}} + +void test_f3(int i, int *ip, float *fp) { + int &ir = f3(ip, i); + float &fr = f3(i, fp); + f3(ip, ip); // expected-error{{ambiguous}} +} + +template<typename T> +int &f4(T&); + +template<typename T> +float &f4(const T&); + +void test_f4(int i, const int ic) { + int &ir1 = f4(i); + float &fr1 = f4(ic); +} + +template<typename T, typename U> +int &f5(T&, const U&); // expected-note{{candidate}} + +template<typename T, typename U> +float &f5(const T&, U&); // expected-note{{candidate}} + +void test_f5(int i, const int ic) { + f5(i, i); // expected-error{{ambiguous}} +} + +template<typename T, typename U> +int &f6(T&, U&); + +template<typename T, typename U> +float &f6(const T&, U&); + +void test_f6(int i, const int ic) { + int &ir = f6(i, i); + float &fr = f6(ic, ic); +} + +struct CrazyFun { + template<typename T, typename U> operator A<T, U>(); + template<typename T> operator A<T, T>(); +}; + +void fun(CrazyFun cf) { + A<int, float> aif = cf; + A<int, int> aii = cf; +} diff --git a/test/SemaTemplate/typename-specifier-4.cpp b/test/SemaTemplate/typename-specifier-4.cpp new file mode 100644 index 000000000000..c7484c19fca7 --- /dev/null +++ b/test/SemaTemplate/typename-specifier-4.cpp @@ -0,0 +1,70 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +template<typename MetaFun, typename T1, typename T2> +struct metafun_apply2 { + typedef typename MetaFun::template apply<T1, T2> inner; + typedef typename inner::type type; +}; + +template<typename T, typename U> struct pair; + +struct make_pair { + template<typename T1, typename T2> + struct apply { + typedef pair<T1, T2> type; + }; +}; + +int a0[is_same<metafun_apply2<make_pair, int, float>::type, + pair<int, float> >::value? 1 : -1]; +int a1[is_same< + typename make_pair::template apply<int, float>, + make_pair::apply<int, float> + >::value? 1 : -1]; + +template<typename MetaFun> +struct swap_and_apply2 { + template<typename T1, typename T2> + struct apply { + typedef typename MetaFun::template apply<T2, T1> new_metafun; + typedef typename new_metafun::type type; + }; +}; + +int a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type, + pair<float, int> >::value? 1 : -1]; + +template<typename MetaFun> +struct swap_and_apply2b { + template<typename T1, typename T2> + struct apply { + typedef typename MetaFun::template apply<T2, T1>::type type; + }; +}; + +int a3[is_same<swap_and_apply2b<make_pair>::apply<int, float>::type, + pair<float, int> >::value? 1 : -1]; + +template<typename T> +struct X0 { + template<typename U, typename V> + struct Inner; + + void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}} + void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}} + + void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}} + void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}} + + void f2(typename X0<T>::Inner<T*, T&>::type); // expected-note{{here}} + void f2(typename X0<T>::template Inner<T*, T&>::type); // expected-error{{redecl}} +}; diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp index d3fca3eacad5..2501b8d048ff 100644 --- a/test/SemaTemplate/typename-specifier.cpp +++ b/test/SemaTemplate/typename-specifier.cpp @@ -16,7 +16,7 @@ namespace N { int i; typename N::A::type *ip1 = &i; -typename N::B::type *ip2 = &i; // expected-error{{ no type named 'type' in 'B'}} +typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'struct N::B'}} typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to non-type member 'type'}} void test(double d) { @@ -33,7 +33,8 @@ void test(double d) { namespace N { template<typename T> struct X { - typedef typename T::type type; // expected-error 2{{no type named 'type' in 'B'}} \ + typedef typename T::type type; // expected-error {{no type named 'type' in 'struct N::B'}} \ + // expected-error {{no type named 'type' in 'struct B'}} \ // FIXME: location info for error above isn't very good \ // expected-error 2{{typename specifier refers to non-type member 'type'}} \ // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} @@ -42,12 +43,12 @@ namespace N { N::X<N::A>::type *ip4 = &i; N::X<N::B>::type *ip5 = &i; // expected-note{{in instantiation of template class 'struct N::X<struct N::B>' requested here}} \ -// expected-error{{unknown type name 'type'}} +// expected-error{{no type named 'type' in}} N::X<N::C>::type *ip6 = &i; // expected-note{{in instantiation of template class 'struct N::X<struct N::C>' requested here}} \ -// expected-error{{unknown type name 'type'}} +// expected-error{{no type named 'type' in}} N::X<int>::type fail1; // expected-note{{in instantiation of template class 'struct N::X<int>' requested here}} \ -// expected-error{{unknown type name 'type'}} +// expected-error{{no type named 'type' in}} template<typename T> struct Y { @@ -69,6 +70,6 @@ struct C { ::Y<A>::type ip7 = &i; ::Y<B>::type ip8 = &i; // expected-note{{in instantiation of template class 'struct Y<struct B>' requested here}} \ -// expected-error{{unknown type name 'type'}} +// expected-error{{no type named 'type' in}} ::Y<C>::type ip9 = &i; // expected-note{{in instantiation of template class 'struct Y<struct C>' requested here}} \ -// expected-error{{unknown type name 'type'}} +// expected-error{{no type named 'type' in}} diff --git a/test/SemaTemplate/value-dependent-null-pointer-constant.cpp b/test/SemaTemplate/value-dependent-null-pointer-constant.cpp new file mode 100644 index 000000000000..8bde1277edd5 --- /dev/null +++ b/test/SemaTemplate/value-dependent-null-pointer-constant.cpp @@ -0,0 +1,29 @@ +// RUN: clang-cc -fsyntax-only %s + +template<typename T, int N> +struct X0 { + const char *f0(bool Cond) { + return Cond? "honk" : N; + } + + const char *f1(bool Cond) { + return Cond? N : "honk"; + } + + bool f2(const char *str) { + return str == N; + } +}; + +// PR4996 +template<unsigned I> int f0() { + return __builtin_choose_expr(I, 0, 1); +} + +// PR5041 +struct A { }; + +template <typename T> void f(T *t) +{ + (void)static_cast<void*>(static_cast<A*>(t)); +}
\ No newline at end of file diff --git a/test/TestRunner.sh b/test/TestRunner.sh index bb20728578c1..f96d3d552d2e 100755 --- a/test/TestRunner.sh +++ b/test/TestRunner.sh @@ -1,134 +1,13 @@ #!/bin/sh # -# TestRunner.sh - This script is used to run arbitrary unit tests. Unit -# tests must contain the command used to run them in the input file, starting -# immediately after a "RUN:" string. -# -# This runner recognizes and replaces the following strings in the command: -# -# %s - Replaced with the input name of the program, or the program to -# execute, as appropriate. -# %S - Replaced with the directory where the input file resides -# %prcontext - prcontext.tcl script -# %t - temporary file name (derived from testcase name) -# - -FILENAME=$1 -TESTNAME=$1 -SUBST=$1 -FILEDIR=`dirname $TESTNAME` - -OUTPUT=Output/$1.out - -# create the output directory if it does not already exist -mkdir -p `dirname $OUTPUT` > /dev/null 2>&1 - -if test $# != 1; then - # If more than one parameter is passed in, there must be three parameters: - # The filename to read from (already processed), the command used to execute, - # and the file to output to. - SUBST=$2 - OUTPUT=$3 - TESTNAME=$3 -fi - -ulimit -t 40 - -# Verify the script contains a run line. -grep -q 'RUN:' $FILENAME || ( - echo "******************** TEST '$TESTNAME' HAS NO RUN LINE! ********************" - exit 1 -) - -# Run under valgrind if the VG environment variable has been set. -CLANG=$CLANG -if [ ! -n "$CLANG" ]; then - CLANG="clang" -fi - -# Resolve the path, and Make sure $CLANG actually exists; otherwise -# ensuing failures are non-obvious. -CLANG=$(which "$CLANG") -if [ -z $CLANG ]; then - echo "Couldn't find 'clang' program, try setting CLANG in your environment" - exit 1 -fi - -if [ -n "$VG" ]; then - rm -f $OUTPUT.vg - CLANG="valgrind --leak-check=full --quiet --log-file=$OUTPUT.vg $CLANG" -fi - -# Assuming $CLANG is correct, use it to derive clang-cc. We expect to -# be looking in a build directory, so just add '-cc'. -CLANGCC=$CLANGCC -if [ ! -n "$CLANGCC" ]; then - CLANGCC="$CLANG-cc" -fi - -# Try to sanity check $CLANGCC too -CLANGCC=$(which "$CLANGCC") -# If that failed, ask clang. -if [ -z "$CLANGCC" ]; then - CLANGCC=$($CLANG -print-prog-name=clang-cc) -fi -if [ -z "$CLANGCC" ]; then - echo "Couldn't find 'clang-cc' program, make sure clang is found in your build directory" - exit 1 -fi - -SCRIPT=$OUTPUT.script -TEMPOUTPUT=$OUTPUT.tmp -grep 'RUN:' $FILENAME | \ - sed -e "s|^.*RUN:\(.*\)$|\1|g" \ - -e "s| clang | $CLANG |g" \ - -e "s| clang-cc | $CLANGCC |g" \ - -e "s|%s|$SUBST|g" \ - -e "s|%S|$FILEDIR|g" \ - -e "s|%prcontext|prcontext.tcl|g" \ - -e "s|%t|$TEMPOUTPUT|g" > $SCRIPT - -IS_XFAIL=0 -if (grep -q XFAIL $FILENAME); then - IS_XFAIL=1 - printf "XFAILED '$TESTNAME': " - grep XFAIL $FILENAME -fi - -/bin/sh $SCRIPT > $OUTPUT 2>&1 -SCRIPT_STATUS=$? +# TestRunner.sh - Backward compatible utility for testing an individual file. -if [ -n "$VG" ]; then - [ ! -s $OUTPUT.vg ] - VG_STATUS=$? -else - VG_STATUS=0 -fi +# Find where this script is. +Dir=$(dirname $(which $0)) +AbsDir=$(cd $Dir; pwd) -if [ $IS_XFAIL -ne 0 ]; then - if [ $SCRIPT_STATUS -ne 0 ]; then - SCRIPT_STATUS=0 - else - SCRIPT_STATUS=1 - fi -fi +# Find 'lit', assuming standard layout. +lit=$AbsDir/../../../utils/lit/lit.py -if [ $SCRIPT_STATUS -ne 0 -o $VG_STATUS -ne 0 ]; then - echo "******************** TEST '$TESTNAME' FAILED! ********************" - echo "Command: " - cat $SCRIPT - if [ $SCRIPT_STATUS -eq 0 ]; then - echo "Output:" - elif [ $IS_XFAIL -ne 0 ]; then - echo "Incorrect Output (Expected Failure):" - else - echo "Incorrect Output:" - fi - cat $OUTPUT - if [ $VG_STATUS -ne 0 ]; then - echo "Valgrind Output:" - cat $OUTPUT.vg - fi - echo "******************** TEST '$TESTNAME' FAILED! ********************" - exit 1 -fi +# Dispatch to lit. +$lit "$@" diff --git a/test/lit.cfg b/test/lit.cfg new file mode 100644 index 000000000000..60d8df057730 --- /dev/null +++ b/test/lit.cfg @@ -0,0 +1,152 @@ +# -*- Python -*- + +import os +import platform + +# Configuration file for the 'lit' test runner. + +# name: The name of this test suite. +config.name = 'Clang' + +# testFormat: The test format to use to interpret tests. +# +# For now we require '&&' between commands, until they get globally killed and +# the test runner updated. +execute_external = platform.system() != 'Windows' +config.test_format = lit.formats.ShTest(execute_external, + require_and_and = True) + +# suffixes: A list of file extensions to treat as test files. +config.suffixes = ['.c', '.cpp', '.m', '.mm'] + +# test_source_root: The root path where tests are located. +config.test_source_root = os.path.dirname(__file__) + +# test_exec_root: The root path where tests should be run. +clang_obj_root = getattr(config, 'clang_obj_root', None) +if clang_obj_root is not None: + config.test_exec_root = os.path.join(clang_obj_root, 'test') + +# Set llvm_{src,obj}_root for use by others. +config.llvm_src_root = getattr(config, 'llvm_src_root', None) +config.llvm_obj_root = getattr(config, 'llvm_obj_root', None) + +# Tweak the PATH to include the tools dir and the scripts dir. +if clang_obj_root is not None: + llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) + if not llvm_tools_dir: + lit.fatal('No LLVM tools dir set!') + path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH'])) + config.environment['PATH'] = path + + llvm_libs_dir = getattr(config, 'llvm_libs_dir', None) + if not llvm_libs_dir: + lit.fatal('No LLVM libs dir set!') + path = os.path.pathsep.join((llvm_libs_dir, + config.environment.get('LD_LIBRARY_PATH',''))) + config.environment['LD_LIBRARY_PATH'] = path + +### + +# Check that the object root is known. +if config.test_exec_root is None: + # Otherwise, we haven't loaded the site specific configuration (the user is + # probably trying to run on a test file directly, and either the site + # configuration hasn't been created by the build system, or we are in an + # out-of-tree build situation). + + # Try to detect the situation where we are using an out-of-tree build by + # looking for 'llvm-config'. + # + # FIXME: I debated (i.e., wrote and threw away) adding logic to + # automagically generate the lit.site.cfg if we are in some kind of fresh + # build situation. This means knowing how to invoke the build system + # though, and I decided it was too much magic. + + llvm_config = lit.util.which('llvm-config', config.environment['PATH']) + if not llvm_config: + lit.fatal('No site specific configuration available!') + + # Get the source and object roots. + llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip() + llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip() + clang_src_root = os.path.join(llvm_src_root, "tools", "clang") + clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang") + + # Validate that we got a tree which points to here, using the standard + # tools/clang layout. + this_src_root = os.path.dirname(config.test_source_root) + if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root): + lit.fatal('No site specific configuration available!') + + # Check that the site specific configuration exists. + site_cfg = os.path.join(clang_obj_root, 'test', 'lit.site.cfg') + if not os.path.exists(site_cfg): + lit.fatal('No site specific configuration available!') + + # Okay, that worked. Notify the user of the automagic, and reconfigure. + lit.note('using out-of-tree build at %r' % clang_obj_root) + lit.load_config(config, site_cfg) + raise SystemExit + +### + +# Discover the 'clang' and 'clangcc' to use. + +import os + +def inferClang(PATH): + # Determine which clang to use. + clang = os.getenv('CLANG') + + # If the user set clang in the environment, definitely use that and don't + # try to validate. + if clang: + return clang + + # Otherwise look in the path. + clang = lit.util.which('clang', PATH) + + if not clang: + lit.fatal("couldn't find 'clang' program, try setting " + "CLANG in your environment") + + return clang + +def inferClangCC(clang, PATH): + clangcc = os.getenv('CLANGCC') + + # If the user set clang in the environment, definitely use that and don't + # try to validate. + if clangcc: + return clangcc + + # Otherwise try adding -cc since we expect to be looking in a build + # directory. + if clang.endswith('.exe'): + clangccName = clang[:-4] + '-cc.exe' + else: + clangccName = clang + '-cc' + clangcc = lit.util.which(clangccName, PATH) + if not clangcc: + # Otherwise ask clang. + res = lit.util.capture([clang, '-print-prog-name=clang-cc']) + res = res.strip() + if res and os.path.exists(res): + clangcc = res + + if not clangcc: + lit.fatal("couldn't find 'clang-cc' program, try setting " + "CLANGCC in your environment") + + return clangcc + +config.clang = inferClang(config.environment['PATH']) +if not lit.quiet: + lit.note('using clang: %r' % config.clang) +config.substitutions.append( (' clang ', ' ' + config.clang + ' ') ) + +config.clang_cc = inferClangCC(config.clang, config.environment['PATH']) +if not lit.quiet: + lit.note('using clang-cc: %r' % config.clang_cc) +config.substitutions.append( (' clang-cc ', ' ' + config.clang_cc + ' ') ) diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in new file mode 100644 index 000000000000..9dabafcde1f4 --- /dev/null +++ b/test/lit.site.cfg.in @@ -0,0 +1,10 @@ +## Autogenerated by LLVM/Clang configuration. +# Do not edit! +config.llvm_src_root = "@LLVM_SOURCE_DIR@" +config.llvm_obj_root = "@LLVM_BINARY_DIR@" +config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" +config.llvm_libs_dir = "@LLVM_LIBS_DIR@" +config.clang_obj_root = "@CLANG_BINARY_DIR@" + +# Let the main config do the real work. +lit.load_config(config, "@CLANG_SOURCE_DIR@/test/lit.cfg") |