diff options
Diffstat (limited to 'test')
190 files changed, 2906 insertions, 909 deletions
diff --git a/test/Analysis/CFDateGC.m b/test/Analysis/CFDateGC.m index 01cb4a4..34bc3c0 100644 --- a/test/Analysis/CFDateGC.m +++ b/test/Analysis/CFDateGC.m @@ -1,8 +1,8 @@ -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=basic %s -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=range %s -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -verify -fobjc-gc -disable-free %s -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify -fobjc-gc %s -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify -fobjc-gc %s +// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=basic %s -Wno-implicit-function-declaration +// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=range %s -Wno-implicit-function-declaration +// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -verify -fobjc-gc -disable-free %s -Wno-implicit-function-declaration +// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify -fobjc-gc %s -Wno-implicit-function-declaration +// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify -fobjc-gc %s -Wno-implicit-function-declaration //===----------------------------------------------------------------------===// // The following code is reduced using delta-debugging from @@ -36,6 +36,8 @@ static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef // Test cases. //===----------------------------------------------------------------------===// +CFAbsoluteTime CFAbsoluteTimeGetCurrent(); + CFAbsoluteTime f1_use_after_release() { CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); CFDateRef date = CFDateCreate(0, t); diff --git a/test/Analysis/NSString.m b/test/Analysis/NSString.m index fb44309..515b9f7 100644 --- a/test/Analysis/NSString.m +++ b/test/Analysis/NSString.m @@ -388,3 +388,19 @@ void test_synchronized(id x) { } } @end + +void testOSCompareAndSwapXXBarrier_parameter(NSString **old) { + NSString *s = [[NSString alloc] init]; // no-warning + if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) old)) + [s release]; + else + [*old release]; +} + +void testOSCompareAndSwapXXBarrier_parameter_no_direct_release(NSString **old) { + NSString *s = [[NSString alloc] init]; // no-warning + if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) old)) + [s release]; + else + return; +} diff --git a/test/Analysis/PR2599.m b/test/Analysis/PR2599.m index e866ee6..d260961 100644 --- a/test/Analysis/PR2599.m +++ b/test/Analysis/PR2599.m @@ -53,6 +53,8 @@ extern NSString * const NSXMLParserErrorDomain ; static char *lorem = "fooBarBaz"; +void NSLog(NSString *, ...); + int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSString *tmp1 = NSSTRINGWRAPPER(lorem, 6); // no-warning diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c index 947f63e..ef398bb 100644 --- a/test/Analysis/casts.c +++ b/test/Analysis/casts.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify %s +// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify %s // Test if the 'storage' region gets properly initialized after it is cast to // 'struct sockaddr *'. @@ -11,6 +12,8 @@ typedef __darwin_socklen_t socklen_t; struct sockaddr { sa_family_t sa_family; }; struct sockaddr_storage {}; +void getsockname(); + void f(int sock) { struct sockaddr_storage storage; struct sockaddr* sockaddr = (struct sockaddr*)&storage; @@ -45,3 +48,20 @@ void f2(const char *str) { if(!cl) cl = 'a'; } + +// Test cast VariableSizeArray to pointer does not crash. +void *memcpy(void *, void const *, unsigned long); +typedef unsigned char Byte; +void doit(char *data, int len) { + if (len) { + Byte buf[len]; + memcpy(buf, data, len); + } +} + +// PR 6013 and 6035 - Test that a cast of a pointer to long and then to int does not crash SValuator. +void pr6013_6035_test(void *p) { + unsigned int foo; + foo = ((long)(p)); + (void) foo; +} diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c index 63c9d0d..91f2b2a 100644 --- a/test/Analysis/dead-stores.c +++ b/test/Analysis/dead-stores.c @@ -17,6 +17,8 @@ void f2(void *b) { // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}} } +int f(); + void f3() { int r; if ((r = f()) != 0) { // no-warning diff --git a/test/Analysis/misc-ps-ranges.m b/test/Analysis/misc-ps-ranges.m index 760b4d7..df7e97c 100644 --- a/test/Analysis/misc-ps-ranges.m +++ b/test/Analysis/misc-ps-ranges.m @@ -21,3 +21,40 @@ int main(int argc, char* argv[]) { return *p; // no-warning } + +// PR 5969: the comparison of argc < 3 || argc > 4 should constraint the switch +// statement from having the 'default' branch taken. This previously reported a false +// positive with the use of 'v'. + +int pr5969(int argc, char *argv[]) { + + int v; + + if ((argc < 3) || (argc > 4)) return 0; + + switch(argc) { + case 3: + v = 33; + break; + case 4: + v = 44; + break; + } + + return v; // no-warning +} + +int pr5969_positive(int argc, char *argv[]) { + + int v; + + if ((argc < 3) || (argc > 4)) return 0; + + switch(argc) { + case 3: + v = 33; + break; + } + + return v; // expected-warning{{Undefined or garbage value returned to caller}} +} diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp index 225abb5..8b58131 100644 --- a/test/Analysis/misc-ps-region-store.cpp +++ b/test/Analysis/misc-ps-region-store.cpp @@ -34,6 +34,10 @@ int test3(Test3_Derived x) { return test3_aux(x); } +//===---------------------------------------------------------------------===// +// Test CFG support for C++ condition variables. +//===---------------------------------------------------------------------===// + int test_init_in_condition_aux(); int test_init_in_condition() { if (int x = test_init_in_condition_aux()) { // no-warning @@ -89,3 +93,42 @@ int test_init_in_condition_for() { *p = 0xDEADBEEF; // no-warning return 0; } + +//===---------------------------------------------------------------------===// +// Test handling of 'this' pointer. +//===---------------------------------------------------------------------===// + +class TestHandleThis { + int x; + + TestHandleThis(); + int foo(); + int null_deref_negative(); + int null_deref_positive(); +}; + +int TestHandleThis::foo() { + // Assume that 'x' is initialized. + return x + 1; // no-warning +} + +int TestHandleThis::null_deref_negative() { + x = 10; + if (x == 10) { + return 1; + } + int *p = 0; + *p = 0xDEADBEEF; // no-warning + return 0; +} + +int TestHandleThis::null_deref_positive() { + x = 10; + if (x == 9) { + return 1; + } + int *p = 0; + *p = 0xDEADBEEF; // expected-warning{{null pointer}} + return 0; +} + diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index 7f29c99..a88c26c 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -55,7 +55,7 @@ void checkaccess_union() { // 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); +void test2_help(struct test2_struct* p); char test2() { struct test2_struct s; @@ -387,7 +387,7 @@ void rdar_7332673_test1() { char value[1]; if ( *(value) != 1 ) {} // expected-warning{{The left operand of '!=' is a garbage value}} } -void rdar_rdar_7332673_test2_aux(char *x); +int rdar_7332673_test2_aux(char *x); void rdar_7332673_test2() { char *value; if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{Pass-by-value argument in function call is undefined}} @@ -631,7 +631,7 @@ typedef void (^RDar_7462324_Callback)(id obj); //===----------------------------------------------------------------------===// int rdar7468209_aux(); -void rdar7468209_aux2(); +void rdar7468209_aux_2(); void rdar7468209() { __block int x = 0; @@ -684,3 +684,49 @@ void pr4358(struct pr4358 *pnt) { } pr4358_aux(uninit); // no-warning } + +//===----------------------------------------------------------------------===// +// <rdar://problem/7526777> +// Test handling fields of values returned from function calls or +// message expressions. +//===----------------------------------------------------------------------===// + +typedef struct testReturn_rdar_7526777 { + int x; + int y; +} testReturn_rdar_7526777; + +@interface TestReturnStruct_rdar_7526777 +- (testReturn_rdar_7526777) foo; +@end + +int test_return_struct(TestReturnStruct_rdar_7526777 *x) { + return [x foo].x; +} + +testReturn_rdar_7526777 test_return_struct_2_aux_rdar_7526777(); + +int test_return_struct_2_rdar_7526777() { + return test_return_struct_2_aux_rdar_7526777().x; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7527292> Assertion failed: (Op == BinaryOperator::Add || +// Op == BinaryOperator::Sub) +// This test case previously triggered an assertion failure due to a discrepancy +// been the loaded/stored value in the array +//===----------------------------------------------------------------------===// + +_Bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue ); + +void rdar_7527292() { + static id Cache7527292[32]; + for (signed long idx = 0; + idx < 32; + idx++) { + id v = Cache7527292[idx]; + if (v && OSAtomicCompareAndSwapPtrBarrier(v, ((void*)0), (void * volatile *)(Cache7527292 + idx))) { + } + } +} + diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index 53b9b6f..9543a98 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -1,8 +1,12 @@ // NOTE: Use '-fobjc-gc' to test the analysis being run twice, and multiple reports are not issued. -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -fobjc-gc -analyzer-constraints=basic -verify -fblocks %s -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify -fblocks %s -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify -fblocks %s -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -fobjc-gc -analyzer-constraints=basic -verify -fblocks %s +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify -fblocks %s +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify -fblocks %s +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -fobjc-gc -analyzer-constraints=basic -verify -fblocks %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify -fblocks %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify -fblocks %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s typedef struct objc_ivar *Ivar; typedef struct objc_selector *SEL; @@ -87,16 +91,16 @@ void r6268365() { void divzeroassume(unsigned x, unsigned j) { x /= j; - if (j == 0) x /= 0; // no-warning - if (j == 0) x /= j; // no-warning - if (j == 0) x = x / 0; // no-warning + if (j == 0) x /= 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} + if (j == 0) x /= j; // no static-analyzer warning + if (j == 0) x = x / 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} } void divzeroassumeB(unsigned x, unsigned j) { x = x / j; - if (j == 0) x /= 0; // no-warning - if (j == 0) x /= j; // no-warning - if (j == 0) x = x / 0; // no-warning + if (j == 0) x /= 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} + if (j == 0) x /= j; // no static-analyzer warning + if (j == 0) x = x / 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} } // InitListExpr processing @@ -460,6 +464,8 @@ void test_block_cast() { (void (^)(void *))test_block_cast_aux(); // expected-warning{{expression result unused}} } +int OSAtomicCompareAndSwap32Barrier(); + // Test comparison of 'id' instance variable to a null void* constant after // performing an OSAtomicCompareAndSwap32Barrier. // This previously was a crash in RegionStoreManager. @@ -493,6 +499,8 @@ void test_invalidate_cast_int() { return; } +int ivar_getOffset(); + // 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) { @@ -793,3 +801,13 @@ void test_bad_msg(TestBadArg *p) { [p testBadArg:y]; // expected-warning{{Pass-by-value argument in message expression is undefined}} } +//===----------------------------------------------------------------------===// +// PR 6033 - Test emitting the correct output in a warning where we use '%' +// with operands that are undefined. +//===----------------------------------------------------------------------===// + +int pr6033(int x) { + int y; + return x % y; // expected-warning{{The right operand of '%' is a garbage value}} +} + diff --git a/test/Analysis/rdar-6442306-1.m b/test/Analysis/rdar-6442306-1.m index 1eae5d7..b3558a6 100644 --- a/test/Analysis/rdar-6442306-1.m +++ b/test/Analysis/rdar-6442306-1.m @@ -13,6 +13,8 @@ typedef struct { QuxSize size; } __Request__SetPortalSize_t; +double __Foo_READSWAP__double(double*); + static __inline__ bar_return_t __Beeble_check__Request__SetPortalSize_t(__attribute__((__unused__)) __Request__SetPortalSize_t *In0P) { if (In0P->Foo.int_rep != Foo_record.int_rep) { diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp new file mode 100644 index 0000000..a641b8e --- /dev/null +++ b/test/Analysis/reference.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s + +void f1() { + int const &i = 3; + int b = i; + + int *p = 0; + + if (b != 3) + *p = 1; // no-warning +} diff --git a/test/Analysis/retain-release-basic-store.m b/test/Analysis/retain-release-basic-store.m index 58321bb..2ef061a 100644 --- a/test/Analysis/retain-release-basic-store.m +++ b/test/Analysis/retain-release-basic-store.m @@ -86,6 +86,8 @@ struct foo { NSDate* f; }; +CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); + CFAbsoluteTime f4() { struct foo x; diff --git a/test/Analysis/retain-release-region-store.m b/test/Analysis/retain-release-region-store.m index 35dc6e7..3a0142b 100644 --- a/test/Analysis/retain-release-region-store.m +++ b/test/Analysis/retain-release-region-store.m @@ -93,6 +93,8 @@ typedef unsigned long NSUInteger; // Test to see if we *issue* an error when we store the pointer // to a struct. This differs from basic store. +CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); + struct foo { NSDate* f; }; diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index f5d985e..691e2a2 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -881,6 +881,8 @@ void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, // Test of handling objects whose references "escape" to containers. //===----------------------------------------------------------------------===// +void CFDictionaryAddValue(); + // <rdar://problem/6539791> void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) { CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); diff --git a/test/Analysis/security-syntax-checks-no-emit.c b/test/Analysis/security-syntax-checks-no-emit.c new file mode 100644 index 0000000..fbfeb1a --- /dev/null +++ b/test/Analysis/security-syntax-checks-no-emit.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple i686-pc-linux-gnu -analyze -warn-security-syntactic %s -verify + +// This file complements 'security-syntax-checks.m', but tests that we omit +// specific checks on platforms where they don't make sense. + +// Omit the 'rand' check since 'arc4random' is not available on Linux. +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(); // no-warning + drand48(); // no-warning + erand48(a); // no-warning + jrand48(a); // no-warning + lcong48(a); // no-warning + lrand48(); // no-warning + mrand48(); // no-warning + nrand48(a); // no-warning + rand_r(&b); // no-warning + random(); // no-warning +} diff --git a/test/Analysis/stack-addr-ps.c b/test/Analysis/stack-addr-ps.c index e58c780..315b900 100644 --- a/test/Analysis/stack-addr-ps.c +++ b/test/Analysis/stack-addr-ps.c @@ -68,3 +68,10 @@ ComparatorBlock test_return_block_neg(void) { return b; // no-warning } +// <rdar://problem/7523821> +int *rdar_7523821_f2() { + int a[3]; + return a; // expected-warning 2 {{ddress of stack memory associated with local variable 'a' returned}} +}; + + diff --git a/test/Analysis/uninit-vals-ps-region.c b/test/Analysis/uninit-vals-ps-region.c index ce86ad0..216856e 100644 --- a/test/Analysis/uninit-vals-ps-region.c +++ b/test/Analysis/uninit-vals-ps-region.c @@ -20,6 +20,7 @@ void f4() { // Test uninitialized value due to part of the structure being uninitialized. struct TestUninit { int x; int y; }; struct TestUninit test_uninit_aux(); +void test_unit_aux2(int); void test_uninit_pos() { struct TestUninit v1 = { 0, 0 }; struct TestUninit v2 = test_uninit_aux(); diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp new file mode 100644 index 0000000..7ecedd5 --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct X0 { + X0 f1(); + X0 f2(); +}; + +template<typename T> +struct X1 { + X1<T>(int); + (X1<T>)(float); + X1 f2(); + X1 f2(int); + X1 f2(float); +}; + +// Error recovery: out-of-line constructors whose names have template arguments. +template<typename T> X1<T>::X1<T>(int) { } // expected-error{{out-of-line constructor for 'X1' cannot have template arguments}} +template<typename T> (X1<T>::X1<T>)(float) { } // expected-error{{out-of-line constructor for 'X1' cannot have template arguments}} + +// Error recovery: out-of-line constructor names intended to be types +X0::X0 X0::f1() { return X0(); } // expected-error{{qualified reference to 'X0' is a constructor name rather than a type wherever a constructor can be declared}} + +struct X0::X0 X0::f2() { return X0(); } + +template<typename T> X1<T>::X1<T> X1<T>::f2() { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}} +template<typename T> X1<T>::X1<T> (X1<T>::f2)(int) { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}} +template<typename T> struct X1<T>::X1<T> (X1<T>::f2)(float) { } diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp index f2dc64b..23da98c 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp @@ -166,7 +166,8 @@ namespace test3 { template <class T> struct C : A<T> { using typename A<T>::type; - using typename A<T>::hiding; // expected-error {{'typename' keyword used on a non-type}} + using typename A<T>::hiding; // expected-note {{declared at}} \ + // expected-error {{'typename' keyword used on a non-type}} using typename A<T>::union_member; // expected-error {{'typename' keyword used on a non-type}} using typename A<T>::enumerator; // expected-error {{'typename' keyword used on a non-type}} @@ -175,7 +176,7 @@ namespace test3 { } void test7() { - Opaque0 _ = hiding; // expected-error {{expected '(' for function-style cast or type construction}} + Opaque0 _ = hiding; // expected-error {{does not refer to a value}} } }; diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp index 06c6695..c16ba20 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp @@ -1,9 +1,15 @@ // RUN: %clang_cc1 -verify %s -// XFAIL: * struct S { typedef struct A {} A; // expected-note {{previous definition is here}} typedef struct B B; typedef A A; // expected-error {{redefinition of 'A'}} + + struct C { }; + typedef struct C OtherC; + typedef OtherC C; + + typedef struct D { } D2; + typedef D2 D; }; diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp index a090418..cf3db51 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -struct Base { }; // expected-note{{candidate function}} -struct Derived : Base { }; // expected-note{{candidate function}} +struct Base { }; // expected-note{{candidate is the implicit copy constructor}} +struct Derived : Base { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}} struct Unrelated { }; struct Derived2 : Base { }; struct Diamond : Derived, Derived2 { }; diff --git a/test/CXX/special/class.ctor/p1.cpp b/test/CXX/special/class.ctor/p1.cpp new file mode 100644 index 0000000..9500a7d --- /dev/null +++ b/test/CXX/special/class.ctor/p1.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct X0 { + struct type { }; + + X0(); + X0(int); + (X0)(float); + X0 (f0)(int); + X0 (f0)(type); + + X0 f1(); + X0 f1(double); +}; + +X0::X0() { } +(X0::X0)(int) { } + +X0 (X0::f0)(int) { return X0(); } + +template<typename T> +struct X1 { + struct type { }; + + X1<T>(); + X1<T>(int); + (X1<T>)(float); + X1(float, float); + (X1)(double); + X1<T> (f0)(int); + X1<T> (f0)(type); + X1 (f1)(int); + X1 (f1)(type); + + template<typename U> X1(U); + X1 f2(); + X1 f2(int); +}; + +template<typename T> X1<T>::X1() { } +template<typename T> (X1<T>::X1)(double) { } +template<typename T> X1<T> X1<T>::f1(int) { return 0; } +template<typename T> X1<T> (X1<T>::f1)(type) { return 0; } 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 index aa53ebc..9fc4a58 100644 --- 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 @@ -14,7 +14,7 @@ struct InitOkay { InitOkay(int) { } }; -struct CannotInit { }; // expected-note{{candidate function}} +struct CannotInit { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}} int &returnInt() { return X<int>::value; } float &returnFloat() { return X<float>::value; } 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 index 3cefeb8..2eae112 100644 --- a/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp +++ b/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp @@ -12,7 +12,7 @@ struct X1 { X1(int); }; -struct X2 { }; // expected-note{{candidate function}} +struct X2 { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}} int& get_int() { return X0<int>::value; } X1& get_X1() { return X0<X1>::value; } diff --git a/test/CXX/temp/temp.decls/temp.mem/p5.cpp b/test/CXX/temp/temp.decls/temp.mem/p5.cpp new file mode 100644 index 0000000..098ffa4 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.mem/p5.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct A { + template <class T> operator T*(); +}; + +template <class T> A::operator T*() { return 0; } +template <> A::operator char*(){ return 0; } // specialization +template A::operator void*(); // explicit instantiation + +int main() { + A a; + int *ip; + ip = a.operator int*(); +} + +// PR5742 +namespace PR5742 { + template <class T> struct A { }; + template <class T> struct B { }; + + struct S { + template <class T> operator T(); + } s; + + void f() { + s.operator A<A<int> >(); + s.operator A<B<int> >(); + s.operator A<B<A<int> > >(); + } +} + +// PR5762 +class Foo { + public: + template <typename T> operator T(); + + template <typename T> + T As() { + return this->operator T(); + } + + template <typename T> + T As2() { + return operator T(); + } + + int AsInt() { + return this->operator int(); + } +}; + +template float Foo::As(); +template double Foo::As2(); + +// Partial ordering with conversion function templates. +struct X0 { + template<typename T> operator T*() { + T x; + x = 17; // expected-error{{read-only variable is not assignable}} + } + + template<typename T> operator T*() const; // expected-note{{explicit instantiation refers here}} + + template<typename T> operator const T*() const { + T x = T(); + return x; // expected-error{{cannot initialize return object of type 'char const *' with an lvalue of type 'char'}} + } +}; + +template X0::operator const char*() const; // expected-note{{'X0::operator char const *<char>' requested here}} +template X0::operator const int*(); // expected-note{{'X0::operator int const *<int const>' requested here}} +template X0::operator float*() const; // expected-error{{explicit instantiation of undefined function template}} + +void test_X0(X0 x0, const X0 &x0c) { + x0.operator const int*(); + x0.operator float *(); + x0c.operator const char*(); +} 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 2530f12..8fb736c 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 @@ -9,3 +9,36 @@ void g() { // Z is deduced to be double f("aa",3.0); // expected-error{{no matching}} } + +// PR5910 +namespace PR5910 { + template <typename T> + void Func() {} + + template <typename R> + void Foo(R (*fp)()); + + void Test() { + Foo(Func<int>); + } +} + +// PR5949 +namespace PR5949 { + struct Bar; + + template <class Container> + void quuz(const Container &cont) { + } + + template<typename T> + int Foo(Bar *b, void (*Baz)(const T &t), T * = 0) { + return 0; + } + + template<typename T> + int Quux(Bar *b, T * = 0) + { + return Foo<T>(b, quuz); + } +} 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 9fefbe1..19962c5 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 @@ -22,12 +22,14 @@ void test_f1(int i, const int ci, volatile int vi) { template<typename T, unsigned N> struct B { }; template<typename T, unsigned N> B<T, N> g0(T (&array)[N]); +template<typename T, unsigned N> B<T, N> g0b(const T (&array)[N]); void test_g0() { int array0[5]; B<int, 5> b0 = g0(array0); const int array1[] = { 1, 2, 3}; B<const int, 3> b1 = g0(array1); + B<int, 3> b2 = g0b(array1); } template<typename T> B<T, 0> g1(const A<T>&); @@ -48,6 +50,19 @@ void test_f2(int i, const int ci, volatile int vi) { A<volatile int> a2 = f2(vi); } +// PR5913 +template <typename T, int N> +void Foo(const T (&a)[N]) { + T x; + x = 0; +} + +const int a[1] = { 0 }; + +void Test() { + Foo(a); +} + // - The transformed A can be another pointer or pointer to member type that // can be converted to the deduced A via a qualification conversion (4.4). template<typename T> A<T> f3(T * * const * const); diff --git a/test/CXX/temp/temp.param/p3.cpp b/test/CXX/temp/temp.param/p3.cpp index 67d648e..8fcc2dc 100644 --- a/test/CXX/temp/temp.param/p3.cpp +++ b/test/CXX/temp/temp.param/p3.cpp @@ -15,7 +15,7 @@ template<template<class T> class Y> struct X1 { // could be interpreted as either a non-type template-parameter or a // type-parameter (because its identifier is the name of an already // existing class) is taken as a type-parameter. For example, -class T { /* ... */ }; // expected-note{{candidate function}} +class T { /* ... */ }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}} int i; template<class T, T i> struct X2 { diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp index 6e7f808..a5ecf5fc 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s struct NonDefaultConstructible { - NonDefaultConstructible(const NonDefaultConstructible&); // expected-note{{candidate function}} + NonDefaultConstructible(const NonDefaultConstructible&); // expected-note{{candidate constructor}} }; template<typename T, typename U> diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp index 3eaf896..772aef6 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -struct IntHolder { // expected-note{{here}} // expected-note 2{{candidate function}} - IntHolder(int); // expected-note 2{{candidate function}} +struct IntHolder { // expected-note{{here}} // expected-note 2{{candidate constructor (the implicit copy constructor)}} + IntHolder(int); // expected-note 2{{candidate constructor}} }; template<typename T, typename U> diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1.cpp index 626bdf1..b426339 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p1.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p1.cpp @@ -48,8 +48,8 @@ template void X1<int>::f<>(int&, int*); // expected-note{{instantiation}} // Explicitly instantiate members of a class template struct Incomplete; // expected-note{{forward declaration}} -struct NonDefaultConstructible { // expected-note{{candidate function}} - NonDefaultConstructible(int); // expected-note{{candidate function}} +struct NonDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor) not viable}} + NonDefaultConstructible(int); // expected-note{{candidate constructor}} }; template<typename T, typename U> diff --git a/test/CodeCompletion/Inputs/macros.h b/test/CodeCompletion/Inputs/macros.h new file mode 100644 index 0000000..98b5ac6 --- /dev/null +++ b/test/CodeCompletion/Inputs/macros.h @@ -0,0 +1,4 @@ +#define FOO +#define BAR(X, Y) X, Y +#define IDENTITY(X) X +#define WIBBLE(...) diff --git a/test/CodeCompletion/enum-switch-case-qualified.cpp b/test/CodeCompletion/enum-switch-case-qualified.cpp index d441269..b9efcb4 100644 --- a/test/CodeCompletion/enum-switch-case-qualified.cpp +++ b/test/CodeCompletion/enum-switch-case-qualified.cpp @@ -22,11 +22,11 @@ void test(enum N::C::Color color) { switch (color) { case // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:23:8 %s -o - | FileCheck -check-prefix=CC1 %s - // CHECK-CC1: Blue : 0 : [#enum M::N::C::Color#]N::C::Blue - // CHECK-CC1-NEXT: Green : 0 : [#enum M::N::C::Color#]N::C::Green - // CHECK-CC1-NEXT: Indigo : 0 : [#enum M::N::C::Color#]N::C::Indigo - // CHECK-CC1-NEXT: Orange : 0 : [#enum M::N::C::Color#]N::C::Orange - // CHECK-CC1-NEXT: Red : 0 : [#enum M::N::C::Color#]N::C::Red - // CHECK-CC1-NEXT: Violet : 0 : [#enum M::N::C::Color#]N::C::Violet - // CHECK-CC1: Yellow : 0 : [#enum M::N::C::Color#]N::C::Yellow + // CHECK-CC1: Blue : [#enum M::N::C::Color#]N::C::Blue + // CHECK-CC1-NEXT: Green : [#enum M::N::C::Color#]N::C::Green + // CHECK-CC1-NEXT: Indigo : [#enum M::N::C::Color#]N::C::Indigo + // CHECK-CC1-NEXT: Orange : [#enum M::N::C::Color#]N::C::Orange + // CHECK-CC1-NEXT: Red : [#enum M::N::C::Color#]N::C::Red + // CHECK-CC1-NEXT: Violet : [#enum M::N::C::Color#]N::C::Violet + // CHECK-CC1: Yellow : [#enum M::N::C::Color#]N::C::Yellow diff --git a/test/CodeCompletion/enum-switch-case.c b/test/CodeCompletion/enum-switch-case.c index 1a7c58f..0820726 100644 --- a/test/CodeCompletion/enum-switch-case.c +++ b/test/CodeCompletion/enum-switch-case.c @@ -20,9 +20,9 @@ void test(enum Color color) { break; // RUN: %clang_cc1 -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 + // CHECK-CC1: Blue + // CHECK-CC1-NEXT: Green + // CHECK-CC1-NEXT: Indigo + // CHECK-CC1-NEXT: Orange + // CHECK-CC1-NEXT: Violet diff --git a/test/CodeCompletion/enum-switch-case.cpp b/test/CodeCompletion/enum-switch-case.cpp index ee8faca..412f5f2 100644 --- a/test/CodeCompletion/enum-switch-case.cpp +++ b/test/CodeCompletion/enum-switch-case.cpp @@ -20,9 +20,9 @@ void test(enum N::Color color) { case // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:21:8 %s -o - | FileCheck -check-prefix=CC1 %s - // CHECK-CC1: Blue : 0 : [#enum N::Color#]N::Blue - // CHECK-CC1-NEXT: Green : 0 : [#enum N::Color#]N::Green - // CHECK-CC1-NEXT: Indigo : 0 : [#enum N::Color#]N::Indigo - // CHECK-CC1-NEXT: Orange : 0 : [#enum N::Color#]N::Orange - // CHECK-CC1-NEXT: Violet : 0 : [#enum N::Color#]N::Violet + // CHECK-CC1: Blue : [#enum N::Color#]N::Blue + // CHECK-CC1-NEXT: Green : [#enum N::Color#]N::Green + // CHECK-CC1-NEXT: Indigo : [#enum N::Color#]N::Indigo + // CHECK-CC1-NEXT: Orange : [#enum N::Color#]N::Orange + // CHECK-CC1-NEXT: Violet : [#enum N::Color#]N::Violet diff --git a/test/CodeCompletion/macros.c b/test/CodeCompletion/macros.c index 0ba2f06..6330d25 100644 --- a/test/CodeCompletion/macros.c +++ b/test/CodeCompletion/macros.c @@ -1,8 +1,3 @@ -#define FOO -#define BAR(X, Y) X, Y -#define IDENTITY(X) X -#define WIBBLE(...) - enum Color { Red, Green, Blue }; @@ -13,24 +8,31 @@ struct Point { }; void test(struct Point *p) { - // RUN: %clang_cc1 -fsyntax-only -code-completion-macros -code-completion-at=%s:17:14 %s -o - | FileCheck -check-prefix=CC1 %s + // RUN: %clang_cc1 -include %S/Inputs/macros.h -fsyntax-only -code-completion-macros -code-completion-at=%s:12:14 %s -o - | FileCheck -check-prefix=CC1 %s switch (p->IDENTITY(color)) { - // RUN: %clang_cc1 -fsyntax-only -code-completion-macros -code-completion-at=%s:19:9 %s -o - | FileCheck -check-prefix=CC2 %s + // RUN: %clang_cc1 -include %S/Inputs/macros.h -fsyntax-only -code-completion-macros -code-completion-at=%s:14:9 %s -o - | FileCheck -check-prefix=CC2 %s case } - // CC1: color - // CC1: x - // CC1: y - // CC1: z + + // Run the same tests, this time with macros loaded from the PCH file. + // RUN: %clang_cc1 -emit-pch -o %t %S/Inputs/macros.h + // RUN: %clang_cc1 -include-pch %t -fsyntax-only -code-completion-macros -code-completion-at=%s:12:14 %s -o - | FileCheck -check-prefix=CC1 %s + // RUN: %clang_cc1 -include-pch %t -fsyntax-only -code-completion-macros -code-completion-at=%s:14:9 %s -o - | FileCheck -check-prefix=CC2 %s + // CC1: BAR(<#X#>, <#Y#>) + // CC1: color // CC1: FOO // CC1: IDENTITY(<#X#>) // CC1: WIBBLE - // CC2: Blue - // CC2: Green - // CC2: Red + // CC1: x + // CC1: y + // CC1: z + // CC2: BAR(<#X#>, <#Y#>) + // CC2: Blue // CC2: FOO + // CC2: Green // CC2: IDENTITY(<#X#>) + // CC2: Red // CC2: WIBBLE } diff --git a/test/CodeCompletion/member-access.cpp b/test/CodeCompletion/member-access.cpp index 7d1637c..8f772c0 100644 --- a/test/CodeCompletion/member-access.cpp +++ b/test/CodeCompletion/member-access.cpp @@ -28,15 +28,15 @@ public: void test(const Proxy &p) { p-> // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:29:6 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s - // CHECK-CC1: member1 : 0 : [#int#][#Base1::#]member1 - // CHECK-CC1: member1 : 0 : [#int#][#Base2::#]member1 - // CHECK-CC1: member2 : 0 : [#float#][#Base1::#]member2 - // CHECK-CC1: member3 : 0 - // CHECK-CC1: member4 : 0 - // CHECK-CC1: memfun1 : 0 : [#void#][#Base3::#]memfun1(<#float#>) - // CHECK-CC1: memfun1 : 0 : [#void#][#Base3::#]memfun1(<#double#>)[# const#] - // CHECK-CC1: memfun2 : 0 : [#void#][#Base3::#]memfun2(<#int#>) - // CHECK-CC1: memfun3 : 0 : [#int#]memfun3(<#int#>) - // CHECK-CC1: memfun1 : 0 (Hidden) : [#void#]Base2::memfun1(<#int#>) - // CHECK-CC1: Base1 : 3 : Base1:: + // CHECK-CC1: Base1 : Base1:: + // CHECK-CC1: member1 : [#int#][#Base1::#]member1 + // CHECK-CC1: member1 : [#int#][#Base2::#]member1 + // CHECK-CC1: member2 : [#float#][#Base1::#]member2 + // CHECK-CC1: member3 + // CHECK-CC1: member4 + // CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#float#>) + // CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#double#>)[# const#] + // CHECK-CC1: memfun1 (Hidden) : [#void#]Base2::memfun1(<#int#>) + // CHECK-CC1: memfun2 : [#void#][#Base3::#]memfun2(<#int#>) + // CHECK-CC1: memfun3 : [#int#]memfun3(<#int#>) diff --git a/test/CodeCompletion/namespace-alias.cpp b/test/CodeCompletion/namespace-alias.cpp index 4511662..efbf996 100644 --- a/test/CodeCompletion/namespace-alias.cpp +++ b/test/CodeCompletion/namespace-alias.cpp @@ -12,9 +12,9 @@ namespace N2 { namespace New = // RUN: %clang_cc1 -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 + // CHECK-CC1: I1 + // CHECK-CC1: I4 + // CHECK-CC1: I5 + // CHECK-CC1: N2 + // CHECK-CC1-NEXT: N4 diff --git a/test/CodeCompletion/namespace.cpp b/test/CodeCompletion/namespace.cpp index 8a42112..ecd8480 100644 --- a/test/CodeCompletion/namespace.cpp +++ b/test/CodeCompletion/namespace.cpp @@ -9,6 +9,6 @@ namespace N2 { namespace // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:12 %s -o - | FileCheck -check-prefix=CC1 %s - // CHECK-CC1: I1 : 0 - // CHECK-CC1-NEXT: I5 : 0 + // CHECK-CC1: I1 + // CHECK-CC1-NEXT: I5 diff --git a/test/CodeCompletion/nested-name-specifier.cpp b/test/CodeCompletion/nested-name-specifier.cpp index 643418a..e09a14b 100644 --- a/test/CodeCompletion/nested-name-specifier.cpp +++ b/test/CodeCompletion/nested-name-specifier.cpp @@ -11,7 +11,7 @@ namespace N { N:: // RUN: %clang_cc1 -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 +// CHECK-CC1: A +// CHECK-CC1: B +// CHECK-CC1: M diff --git a/test/CodeCompletion/objc-message.m b/test/CodeCompletion/objc-message.m index a1ae271..a7b111f 100644 --- a/test/CodeCompletion/objc-message.m +++ b/test/CodeCompletion/objc-message.m @@ -24,12 +24,12 @@ void func() { [obj xx]; } // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:23:19 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s -// CHECK-CC1: categoryClassMethod : 0 -// CHECK-CC1: classMethod1:withKeyword: : 0 -// CHECK-CC1: classMethod2 : 0 -// CHECK-CC1: new : 0 -// CHECK-CC1: protocolClassMethod : 0 +// CHECK-CC1: categoryClassMethod +// CHECK-CC1: classMethod1:withKeyword: +// CHECK-CC1: classMethod2 +// CHECK-CC1: new +// CHECK-CC1: protocolClassMethod // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:24:8 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s -// CHECK-CC2: categoryInstanceMethod : 0 -// CHECK-CC2: instanceMethod1 : 0 -// CHECK-CC2: protocolInstanceMethod : 0 +// CHECK-CC2: categoryInstanceMethod +// CHECK-CC2: instanceMethod1 +// CHECK-CC2: protocolInstanceMethod diff --git a/test/CodeCompletion/operator.cpp b/test/CodeCompletion/operator.cpp index eef7fbd..05cd768 100644 --- a/test/CodeCompletion/operator.cpp +++ b/test/CodeCompletion/operator.cpp @@ -9,9 +9,9 @@ void f() { operator // RUN: %clang_cc1 -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 + // CHECK-CC1: + + // CHECK-CC1: Float + // CHECK-CC1: Integer + // CHECK-CC1: N + // CHECK-CC1: short + // CHECK-CC1: T diff --git a/test/CodeCompletion/ordinary-name.c b/test/CodeCompletion/ordinary-name.c index 7f5a05f..1580d01 100644 --- a/test/CodeCompletion/ordinary-name.c +++ b/test/CodeCompletion/ordinary-name.c @@ -5,7 +5,6 @@ typedef struct t TYPEDEF; void foo() { int y; // RUN: %clang_cc1 -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 + // CHECK-CC1: foo + // CHECK-CC1: y + // CHECK-CC1: TYPEDEF diff --git a/test/CodeCompletion/ordinary-name.cpp b/test/CodeCompletion/ordinary-name.cpp new file mode 100644 index 0000000..d938c79 --- /dev/null +++ b/test/CodeCompletion/ordinary-name.cpp @@ -0,0 +1,171 @@ +struct X { int x; }; +void z(int); +typedef struct t TYPEDEF; + +void foo() { + int y = 17; + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:6:14 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s + // CHECK-CC1: COMPLETION: bool + // CHECK-CC1-NEXT: COMPLETION: char + // CHECK-CC1-NEXT: COMPLETION: class + // CHECK-CC1-NEXT: COMPLETION: const + // CHECK-CC1-NEXT: COMPLETION: Pattern : const_cast<<#type-id#>>(<#expression#>) + // CHECK-CC1: COMPLETION: Pattern : delete <#expression#> + // CHECK-CC1-NEXT: COMPLETION: Pattern : delete[] <#expression#> + // CHECK-CC1-NEXT: COMPLETION: Pattern : do{<#statements#> + // CHECK-CC1: COMPLETION: double + // CHECK-CC1-NEXT: COMPLETION: Pattern : dynamic_cast<<#type-id#>>(<#expression#>) + // CHECK-CC1-NEXT: COMPLETION: enum + // CHECK-CC1-NEXT: COMPLETION: extern + // CHECK-CC1-NEXT: COMPLETION: false + // CHECK-CC1-NEXT: COMPLETION: float + // CHECK-CC1-NEXT: COMPLETION: foo : [#void#]foo() + // CHECK-CC1-NEXT: COMPLETION: Pattern : for(<#init-statement#>;<#condition#>;<#inc-expression#>){<#statements#> + // CHECK-CC1: COMPLETION: Pattern : goto <#identifier#>; + // CHECK-CC1-NEXT: COMPLETION: Pattern : if(<#condition#>){<#statements#> + // CHECK-CC1: COMPLETION: int + // CHECK-CC1-NEXT: COMPLETION: long + // CHECK-CC1-NEXT: COMPLETION: Pattern : new <#type-id#>(<#expressions#>) + // CHECK-CC1-NEXT: COMPLETION: Pattern : new <#type-id#>[<#size#>](<#expressions#>) + // CHECK-CC1-NEXT: COMPLETION: operator + // CHECK-CC1-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type-id#>>(<#expression#>) + // CHECK-CC1-NEXT: COMPLETION: Pattern : return; + // CHECK-CC1-NEXT: COMPLETION: short + // CHECK-CC1-NEXT: COMPLETION: signed + // CHECK-CC1-NEXT: COMPLETION: Pattern : sizeof(<#expression-or-type#>) + // CHECK-CC1-NEXT: COMPLETION: static + // CHECK-CC1-NEXT: COMPLETION: Pattern : static_cast<<#type-id#>>(<#expression#>) + // CHECK-CC1-NEXT: COMPLETION: struct + // CHECK-CC1-NEXT: COMPLETION: Pattern : switch(<#condition#>){ + // CHECK-CC1: COMPLETION: t : t + // CHECK-CC1-NEXT: COMPLETION: Pattern : throw <#expression#> + // CHECK-CC1-NEXT: COMPLETION: true + // CHECK-CC1-NEXT: COMPLETION: Pattern : try{<#statements#> + // CHECK-CC1: COMPLETION: TYPEDEF : TYPEDEF + // CHECK-CC1-NEXT: COMPLETION: typedef + // CHECK-CC1-NEXT: COMPLETION: Pattern : typeid(<#expression-or-type#>) + // CHECK-CC1-NEXT: COMPLETION: Pattern : typename <#qualified-id#> + // CHECK-CC1-NEXT: COMPLETION: Pattern : typeof(<#expression-or-type#>) + // CHECK-CC1-NEXT: COMPLETION: union + // CHECK-CC1-NEXT: COMPLETION: unsigned + // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>; + // CHECK-CC1-NEXT: COMPLETION: void + // CHECK-CC1-NEXT: COMPLETION: volatile + // CHECK-CC1-NEXT: COMPLETION: wchar_t + // CHECK-CC1-NEXT: COMPLETION: Pattern : while(<#condition#>){<#statements#> + // CHECK-CC1: COMPLETION: X : X + // CHECK-CC1-NEXT: COMPLETION: y : [#int#]y + // CHECK-CC1-NEXT: COMPLETION: z : [#void#]z(<#int#>) + + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:4:1 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s + // CHECK-CC2: COMPLETION: Pattern : asm(<#string-literal#>); + // CHECK-CC2-NEXT: COMPLETION: bool + // CHECK-CC2-NEXT: COMPLETION: char + // CHECK-CC2-NEXT: COMPLETION: class + // CHECK-CC2-NEXT: COMPLETION: const + // CHECK-CC2-NEXT: COMPLETION: double + // CHECK-CC2-NEXT: COMPLETION: enum + // CHECK-CC2-NEXT: COMPLETION: extern + // CHECK-CC2-NEXT: COMPLETION: float + // CHECK-CC2-NEXT: COMPLETION: inline + // CHECK-CC2-NEXT: COMPLETION: int + // CHECK-CC2-NEXT: COMPLETION: long + // CHECK-CC2-NEXT: COMPLETION: Pattern : namespace <#identifier#>{<#declarations#> + // CHECK-CC2: COMPLETION: Pattern : namespace <#identifier#> = <#identifier#>; + // CHECK-CC2-NEXT: COMPLETION: operator + // CHECK-CC2-NEXT: COMPLETION: short + // CHECK-CC2-NEXT: COMPLETION: signed + // CHECK-CC2-NEXT: COMPLETION: static + // CHECK-CC2-NEXT: COMPLETION: struct + // CHECK-CC2-NEXT: COMPLETION: t : t + // CHECK-CC2-NEXT: COMPLETION: Pattern : template <#declaration#>; + // CHECK-CC2-NEXT: COMPLETION: Pattern : template<<#parameters#>> + // CHECK-CC2-NEXT: COMPLETION: TYPEDEF : TYPEDEF + // CHECK-CC2-NEXT: COMPLETION: typedef + // CHECK-CC2-NEXT: COMPLETION: Pattern : typename <#qualified-id#> + // CHECK-CC2-NEXT: COMPLETION: Pattern : typeof(<#expression-or-type#>) + // CHECK-CC2-NEXT: COMPLETION: union + // CHECK-CC2-NEXT: COMPLETION: unsigned + // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>; + // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualified-id#>; + // CHECK-CC2-NEXT: COMPLETION: void + // CHECK-CC2-NEXT: COMPLETION: volatile + // CHECK-CC2-NEXT: COMPLETION: wchar_t + // CHECK-CC2-NEXT: COMPLETION: X : X + + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:1:19 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s + // CHECK-CC3: COMPLETION: bool + // CHECK-CC3-NEXT: COMPLETION: char + // CHECK-CC3-NEXT: COMPLETION: class + // CHECK-CC3-NEXT: COMPLETION: const + // CHECK-CC3-NEXT: COMPLETION: double + // CHECK-CC3-NEXT: COMPLETION: enum + // CHECK-CC3-NEXT: COMPLETION: explicit + // CHECK-CC3-NEXT: COMPLETION: extern + // CHECK-CC3-NEXT: COMPLETION: float + // CHECK-CC3-NEXT: COMPLETION: friend + // CHECK-CC3-NEXT: COMPLETION: inline + // CHECK-CC3-NEXT: COMPLETION: int + // CHECK-CC3-NEXT: COMPLETION: long + // CHECK-CC3-NEXT: COMPLETION: mutable + // CHECK-CC3-NEXT: COMPLETION: operator + // CHECK-CC3-NEXT: COMPLETION: Pattern : private: + // CHECK-CC3-NEXT: COMPLETION: Pattern : protected: + // CHECK-CC3-NEXT: COMPLETION: Pattern : public: + // CHECK-CC3-NEXT: COMPLETION: short + // CHECK-CC3-NEXT: COMPLETION: signed + // CHECK-CC3-NEXT: COMPLETION: static + // CHECK-CC3-NEXT: COMPLETION: struct + // CHECK-CC3-NEXT: COMPLETION: Pattern : template<<#parameters#>> + // CHECK-CC3-NEXT: COMPLETION: typedef + // CHECK-CC3-NEXT: COMPLETION: Pattern : typename <#qualified-id#> + // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof(<#expression-or-type#>) + // CHECK-CC3-NEXT: COMPLETION: union + // CHECK-CC3-NEXT: COMPLETION: unsigned + // CHECK-CC3-NEXT: COMPLETION: Pattern : using <#qualified-id#>; + // CHECK-CC3-NEXT: COMPLETION: virtual + // CHECK-CC3-NEXT: COMPLETION: void + // CHECK-CC3-NEXT: COMPLETION: volatile + // CHECK-CC3-NEXT: COMPLETION: wchar_t + // CHECK-CC3-NEXT: COMPLETION: X : X + + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:6:11 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s + // CHECK-CC4: COMPLETION: bool + // CHECK-CC4-NEXT: COMPLETION: char + // CHECK-CC4-NEXT: COMPLETION: class + // CHECK-CC4-NEXT: COMPLETION: const + // CHECK-CC4-NEXT: COMPLETION: Pattern : const_cast<<#type-id#>>(<#expression#>) + // CHECK-CC4-NEXT: COMPLETION: Pattern : delete <#expression#> + // CHECK-CC4-NEXT: COMPLETION: Pattern : delete[] <#expression#> + // CHECK-CC4-NEXT: COMPLETION: double + // CHECK-CC4-NEXT: COMPLETION: Pattern : dynamic_cast<<#type-id#>>(<#expression#>) + // CHECK-CC4-NEXT: COMPLETION: enum + // CHECK-CC4-NEXT: COMPLETION: false + // CHECK-CC4-NEXT: COMPLETION: float + // CHECK-CC4-NEXT: COMPLETION: foo : [#void#]foo() + // CHECK-CC4-NEXT: COMPLETION: int + // CHECK-CC4-NEXT: COMPLETION: long + // CHECK-CC4-NEXT: COMPLETION: Pattern : new <#type-id#>(<#expressions#>) + // CHECK-CC4-NEXT: COMPLETION: Pattern : new <#type-id#>[<#size#>](<#expressions#>) + // CHECK-CC4-NEXT: COMPLETION: operator + // CHECK-CC4-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type-id#>>(<#expression#>) + // CHECK-CC4-NEXT: COMPLETION: short + // CHECK-CC4-NEXT: COMPLETION: signed + // CHECK-CC4-NEXT: COMPLETION: Pattern : sizeof(<#expression-or-type#>) + // CHECK-CC4-NEXT: COMPLETION: Pattern : static_cast<<#type-id#>>(<#expression#>) + // CHECK-CC4-NEXT: COMPLETION: struct + // CHECK-CC4-NEXT: COMPLETION: t : t + // CHECK-CC4-NEXT: COMPLETION: Pattern : throw <#expression#> + // CHECK-CC4-NEXT: COMPLETION: true + // CHECK-CC4-NEXT: COMPLETION: TYPEDEF : TYPEDEF + // CHECK-CC4-NEXT: COMPLETION: Pattern : typeid(<#expression-or-type#>) + // CHECK-CC4-NEXT: COMPLETION: Pattern : typename <#qualified-id#> + // CHECK-CC4-NEXT: COMPLETION: Pattern : typeof(<#expression-or-type#>) + // CHECK-CC4-NEXT: COMPLETION: union + // CHECK-CC4-NEXT: COMPLETION: unsigned + // CHECK-CC4-NEXT: COMPLETION: void + // CHECK-CC4-NEXT: COMPLETION: volatile + // CHECK-CC4-NEXT: COMPLETION: wchar_t + // CHECK-CC4-NEXT: COMPLETION: X : X + // CHECK-CC4-NEXT: COMPLETION: y : [#int#]y + // CHECK-CC4-NEXT: COMPLETION: z : [#void#]z(<#int#>) diff --git a/test/CodeCompletion/tag.c b/test/CodeCompletion/tag.c index 554d381..6ad2988 100644 --- a/test/CodeCompletion/tag.c +++ b/test/CodeCompletion/tag.c @@ -8,5 +8,5 @@ void test() { enum X { x }; enum // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:9:7 %s -o - | FileCheck -check-prefix=CC1 %s - // CHECK-CC1: X : 0 - // CHECK-CC1: Y : 2 + // CHECK-CC1: X + // CHECK-CC1: Y diff --git a/test/CodeCompletion/tag.cpp b/test/CodeCompletion/tag.cpp index 17fb014..03fc0fd 100644 --- a/test/CodeCompletion/tag.cpp +++ b/test/CodeCompletion/tag.cpp @@ -16,10 +16,12 @@ namespace N { void test() { class // RUN: %clang_cc1 -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:: + // FIXME: the redundant Y is really annoying... it needs qualification to + // actually be useful. Here, it just looks redundant :( + // CHECK-CC1: A + // CHECK-CC1: M : M:: + // CHECK-CC1: N : N:: + // CHECK-CC1: X + // CHECK-CC1: Y + // CHECK-CC1: Y + // CHECK-CC1: Z diff --git a/test/CodeCompletion/truncation.c b/test/CodeCompletion/truncation.c index c770635..134139d 100644 --- a/test/CodeCompletion/truncation.c +++ b/test/CodeCompletion/truncation.c @@ -3,9 +3,9 @@ struct // RUN: %clang_cc1 -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 +// CHECK-CC1: X +// CHECK-CC1-NEXT: Y // RUN: %clang_cc1 -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 +// CHECK-CC2: X +// CHECK-CC2: Xa +// CHECK-CC2: Y diff --git a/test/CodeCompletion/using-namespace.cpp b/test/CodeCompletion/using-namespace.cpp index f8f31d8..eb1c2bd 100644 --- a/test/CodeCompletion/using-namespace.cpp +++ b/test/CodeCompletion/using-namespace.cpp @@ -13,8 +13,8 @@ namespace N2 { void foo() { using namespace // RUN: %clang_cc1 -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 + // CHECK-CC1: I1 + // CHECK-CC1: I4 + // CHECK-CC1: I5 + // CHECK-CC1: N2 + // CHECK-CC1-NEXT: N4 diff --git a/test/CodeCompletion/using.cpp b/test/CodeCompletion/using.cpp index ba4c9ce..b84aa26 100644 --- a/test/CodeCompletion/using.cpp +++ b/test/CodeCompletion/using.cpp @@ -15,10 +15,10 @@ namespace N2 { using // RUN: %clang_cc1 -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 + // CHECK-CC1: I1 + // CHECK-CC1: I4 + // CHECK-CC1: I5 + // CHECK-CC1: N2 + // CHECK-CC1: N3 + // CHECK-CC1-NEXT: N4 diff --git a/test/CodeGen/annotate.c b/test/CodeGen/annotate.c new file mode 100644 index 0000000..84d564a --- /dev/null +++ b/test/CodeGen/annotate.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +__attribute((annotate("foo"))) char foo; +void a(char *a) { + __attribute__((annotate("bar"))) static char bar; +} + +// CHECK: @llvm.global.annotations = appending global [2 x %0] diff --git a/test/CodeGen/complex.c b/test/CodeGen/complex.c index 8d9c68d..ca60610 100644 --- a/test/CodeGen/complex.c +++ b/test/CodeGen/complex.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm < %s +// RUN: %clang_cc1 -emit-llvm-only %s int main(void) { @@ -39,6 +39,25 @@ void test3() { g1 = D + g1; } +__complex__ int ci1, ci2; +__complex__ short cs; +int i; +void test3int() { + ci1 = ci1 + ci2; + ci1 = ci1 - ci2; + ci1 = ci1 * ci2; + ci1 = +-~ci1; + + i = __real ci1; + + cs += i; + // FIXME: Currently unsupported! + //D += cf; + cs /= ci1; + ci1 = ci1 + i; + ci1 = i + ci1; +} + void t1() { (__real__ cf) = 4.0; } @@ -59,3 +78,14 @@ void t5() { float _Complex x = t4(); } +void t6() { + g1++; + g1--; + ++g1; + --g1; + ci1++; + ci1--; + ++ci1; + --ci1; +} + diff --git a/test/CodeGen/ext-vector.c b/test/CodeGen/ext-vector.c index 6215323..daa1826 100644 --- a/test/CodeGen/ext-vector.c +++ b/test/CodeGen/ext-vector.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm %s -o %t +// RUN: %clang_cc1 -emit-llvm-only %s typedef __attribute__(( ext_vector_type(4) )) float float4; typedef __attribute__(( ext_vector_type(2) )) float float2; @@ -151,3 +151,12 @@ int4 test11a(); int test11() { return test11a().x; } + +int4 test12(int4 V) { + V.xyz = V.zyx; + return V; +} + +int4 test13(int4 *V) { + return V->zyxw; +} diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c index fe12f4a..a96176a 100644 --- a/test/CodeGen/libcalls.c +++ b/test/CodeGen/libcalls.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -emit-llvm -o %t %s -triple i386-unknown-unknown +// RUN: %clang_cc1 -fmath-errno -emit-llvm -o %t %s -triple i386-unknown-unknown // RUN: grep "declare " %t | count 6 // RUN: grep "declare " %t | grep "@llvm." | count 1 -// RUN: %clang_cc1 -fno-math-errno -emit-llvm -o %t %s -triple i386-unknown-unknown +// RUN: %clang_cc1 -emit-llvm -o %t %s -triple i386-unknown-unknown // RUN: grep "declare " %t | count 6 // RUN: grep "declare " %t | grep -v "@llvm." | count 0 diff --git a/test/CodeGen/object-size.c b/test/CodeGen/object-size.c index 4947c19..3920ec5 100644 --- a/test/CodeGen/object-size.c +++ b/test/CodeGen/object-size.c @@ -14,98 +14,108 @@ char *gp; int gi, gj; void test1() { - // CHECK: %call = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 4), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 59) + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 4), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 59) strcpy(&gbuf[4], "Hi there"); } void test2() { - // CHECK: %call = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 63) + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 63) strcpy(gbuf, "Hi there"); } void test3() { - // CHECK: %call = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i64 1, i64 37), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i64 1, i64 37), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) strcpy(&gbuf[100], "Hi there"); } void test4() { - // CHECK: %call = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 -1), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 -1), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) strcpy((char*)(void*)&gbuf[-1], "Hi there"); } void test5() { - // CHECK: %tmp = load i8** @gp - // CHECK-NEXT:%0 = call i64 @llvm.objectsize.i64(i8* %tmp, i1 false) - // CHECK-NEXT:%cmp = icmp ne i64 %0, -1 + // CHECK: = load i8** @gp + // CHECK-NEXT:= call i64 @llvm.objectsize.i64(i8* %{{.*}}, i1 false) strcpy(gp, "Hi there"); } void test6() { char buf[57]; - // CHECK: %call = call i8* @__strcpy_chk(i8* %arrayidx, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 53) + // CHECK: = call i8* @__strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 53) strcpy(&buf[4], "Hi there"); } void test7() { int i; // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy((++i, gbuf), "Hi there"); } void test8() { char *buf[50]; // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp1, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(buf[++gi], "Hi there"); } void test9() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %0, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy((char *)((++gi) + gj), "Hi there"); } char **p; void test10() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp1, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(*(++p), "Hi there"); } void test11() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(gp = gbuf, "Hi there"); } void test12() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %ptrincdec, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(++gp, "Hi there"); } void test13() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(gp++, "Hi there"); } void test14() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %ptrincdec, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(--gp, "Hi there"); } void test15() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{..*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(gp--, "Hi there"); } void test16() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp1, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(gp += 1, "Hi there"); } + +void test17() { + // CHECK: store i32 -1 + gi = __builtin_object_size(gp++, 0); + // CHECK: store i32 -1 + gi = __builtin_object_size(gp++, 1); + // CHECK: store i32 0 + gi = __builtin_object_size(gp++, 2); + // CHECK: store i32 0 + gi = __builtin_object_size(gp++, 3); +} diff --git a/test/CodeGenCXX/attr.cpp b/test/CodeGenCXX/attr.cpp index 8fd8641..1b214b7 100644 --- a/test/CodeGenCXX/attr.cpp +++ b/test/CodeGenCXX/attr.cpp @@ -15,6 +15,9 @@ class C { virtual void bar3() __attribute__((aligned(1024))); } c; +// CHECK:.align 1, 0x90 +// CHECK-NEXT:.globl __ZN1CC1Ev + void C::bar1() { } // CHECK:.align 1, 0x90 diff --git a/test/CodeGenCXX/condition.cpp b/test/CodeGenCXX/condition.cpp index eca07d8..a1b7a09 100644 --- a/test/CodeGenCXX/condition.cpp +++ b/test/CodeGenCXX/condition.cpp @@ -39,10 +39,10 @@ void if_destruct(int z) { // CHECK: call void @_ZN1XC1Ev if (X x = X()) Y y; - // CHECK: if.then + // CHECK: br // CHECK: call void @_ZN1YC1Ev // CHECK: call void @_ZN1YD1Ev - // CHECK: if.end + // CHECK: br // CHECK: call void @_ZN1XD1Ev } @@ -59,12 +59,12 @@ void switch_destruct(int z) { break; default: - // CHECK: sw.default: + // CHECK: {{sw.default:|:3}} // CHECK: store i32 19 z = 19; break; } - // CHECK: sw.epilog: + // CHECK: {{sw.epilog:|:4}} // CHECK: call void @_ZN16ConvertibleToIntD1Ev // CHECK: store i32 20 z = 20; @@ -74,18 +74,18 @@ int foo(); void while_destruct(int z) { // CHECK: define void @_Z14while_destructi - // CHECK: while.cond: + // CHECK: {{while.cond:|:1}} while (X x = X()) { // CHECK: call void @_ZN1XC1Ev - // CHECK: while.body: + // CHECK: {{while.body:|:3}} // CHECK: store i32 21 z = 21; - // CHECK: while.cleanup: + // CHECK: {{while.cleanup:|:4}} // CHECK: call void @_ZN1XD1Ev } - // CHECK: while.end + // CHECK: {{while.end|:6}} // CHECK: store i32 22 z = 22; } @@ -94,16 +94,16 @@ void for_destruct(int z) { // CHECK: define void @_Z12for_destruct // CHECK: call void @_ZN1YC1Ev for(Y y = Y(); X x = X(); ++z) - // CHECK: for.cond: + // CHECK: {{for.cond:|:1}} // CHECK: call void @_ZN1XC1Ev - // CHECK: for.body: + // CHECK: {{for.body:|:3}} // CHECK: store i32 23 z = 23; - // CHECK: for.inc: - // CHECK: br label %for.cond.cleanup - // CHECK: for.cond.cleanup: + // CHECK: {{for.inc:|:4}} + // CHECK: br label %{{for.cond.cleanup|7}} + // CHECK: {{for.cond.cleanup:|:7}} // CHECK: call void @_ZN1XD1Ev - // CHECK: for.end: + // CHECK: {{for.end:|:9}} // CHECK: call void @_ZN1YD1Ev // CHECK: store i32 24 z = 24; diff --git a/test/CodeGenCXX/constructor-template.cpp b/test/CodeGenCXX/constructor-template.cpp index a3576fd..a3f38a6 100644 --- a/test/CodeGenCXX/constructor-template.cpp +++ b/test/CodeGenCXX/constructor-template.cpp @@ -44,10 +44,10 @@ int main() { delete node; } -// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC1Ev: +// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC2Ev: // CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev: // CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev: -// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC1Ev: +// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC2Ev: // CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev: // CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev: diff --git a/test/CodeGenCXX/copy-assign-synthesis-3.cpp b/test/CodeGenCXX/copy-assign-synthesis-3.cpp index 0c876d0..73c2261 100644 --- a/test/CodeGenCXX/copy-assign-synthesis-3.cpp +++ b/test/CodeGenCXX/copy-assign-synthesis-3.cpp @@ -9,6 +9,8 @@ struct B { float b; int (A::*c)(); _Complex float d; + int e[10]; + A f[2]; }; void a(B& x, B& y) { x = y; diff --git a/test/CodeGenCXX/default-constructor-default-argument.cpp b/test/CodeGenCXX/default-constructor-default-argument.cpp index 971757d..f2c7f6d 100644 --- a/test/CodeGenCXX/default-constructor-default-argument.cpp +++ b/test/CodeGenCXX/default-constructor-default-argument.cpp @@ -5,4 +5,4 @@ struct A { A(int x = 2); }; struct B : public A {}; B x; -// CHECK: call void @_ZN1AC1Ei +// CHECK: call void @_ZN1AC2Ei diff --git a/test/CodeGenCXX/default-destructor-synthesis.cpp b/test/CodeGenCXX/default-destructor-synthesis.cpp index 098458d..71167a2 100644 --- a/test/CodeGenCXX/default-destructor-synthesis.cpp +++ b/test/CodeGenCXX/default-destructor-synthesis.cpp @@ -45,15 +45,14 @@ M gm; int main() {M m1;} -// CHECK-LP64: callq __ZN1MC1Ev -// CHECK-LP64: callq __ZN1MD1Ev // CHECK-LP64: .globl __ZN1MD1Ev // CHECK-LP64-NEXT: .weak_definition __ZN1MD1Ev // CHECK-LP64-NEXT: __ZN1MD1Ev: +// CHECK-LP64: callq __ZN1MC1Ev +// CHECK-LP64: callq __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: +// CHECK-LP32: call L__ZN1MC1Ev +// CHECK-LP32: call L__ZN1MD1Ev diff --git a/test/CodeGenCXX/deferred-global-init.cpp b/test/CodeGenCXX/deferred-global-init.cpp new file mode 100644 index 0000000..5701479 --- /dev/null +++ b/test/CodeGenCXX/deferred-global-init.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// PR5967 + +extern void* foo; +static void* const a = foo; +void* bar() { return a; } + +// CHECK: @a = internal global i8* null + +// CHECK: define internal void @__cxx_global_var_init +// CHECK: load i8** @foo +// CHECK: ret void + +// CHECK: define internal void @__cxx_global_initialization +// CHECK: call void @__cxx_global_var_init() +// CHECK: ret void diff --git a/test/CodeGenCXX/delete-two-arg.cpp b/test/CodeGenCXX/delete-two-arg.cpp index d6bdb09..5358747 100644 --- a/test/CodeGenCXX/delete-two-arg.cpp +++ b/test/CodeGenCXX/delete-two-arg.cpp @@ -3,4 +3,4 @@ struct A { void operator delete(void*,__typeof(sizeof(int))); int x; }; void a(A* x) { delete x; } -// CHECK: call void @_ZN1AdlEPvj(i8* %0, i32 4) +// CHECK: call void @_ZN1AdlEPvj(i8* %{{.*}}, i32 4) diff --git a/test/CodeGenCXX/dyncast.cpp b/test/CodeGenCXX/dyncast.cpp index a2d116a..054b972 100644 --- a/test/CodeGenCXX/dyncast.cpp +++ b/test/CodeGenCXX/dyncast.cpp @@ -59,356 +59,355 @@ void test1() { } // CHECK-LL: define void @_Z5test1v() nounwind { -// CHECK-LL-NEXT:entry: -// CHECK-LL-NEXT: %bp = alloca %class.test1_A*, align 8 -// CHECK-LL-NEXT: %ap = alloca %class.test1_A*, align 8 -// CHECK-LL-NEXT: %dp = alloca %class.test1_D*, align 8 -// CHECK-LL-NEXT: %ap37 = alloca %class.test1_A*, align 8 -// CHECK-LL-NEXT: %dp53 = alloca %class.test1_D*, align 8 -// CHECK-LL-NEXT: %ep1 = alloca %class.test1_E*, align 8 -// CHECK-LL-NEXT: %cdp = alloca %class.test1_D*, align 8 -// CHECK-LL-NEXT: %ep = alloca %class.test1_E*, align 8 -// CHECK-LL-NEXT: %vp = alloca i8*, align 8 -// CHECK-LL-NEXT: %cvp = alloca i8*, align 8 -// CHECK-LL-NEXT: br i1 false, label %cast.null, label %cast.notnull -// CHECK-LL: cast.notnull: -// CHECK-LL-NEXT: br label %cast.end -// CHECK-LL: cast.null: -// CHECK-LL-NEXT: br label %cast.end -// CHECK-LL: cast.end: -// CHECK-LL-NEXT: %0 = phi %class.test1_A* [ bitcast (%class.test1_D* @test1_d to %class.test1_A*), %cast.notnull ], [ null, %cast.null ] -// CHECK-LL-NEXT: store %class.test1_A* %0, %class.test1_A** %bp -// CHECK-LL-NEXT: br i1 false, label %cast.null2, label %cast.notnull1 -// CHECK-LL: cast.notnull1: -// CHECK-LL-NEXT: %vtable = load i8** bitcast (%class.test1_D* @test1_d to i8**) -// CHECK-LL-NEXT: %vbase.offset.ptr = getelementptr i8* %vtable, i64 -24 -// CHECK-LL-NEXT: %1 = bitcast i8* %vbase.offset.ptr to i64* -// CHECK-LL-NEXT: %vbase.offset = load i64* %1 -// CHECK-LL-NEXT: %add.ptr = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 %vbase.offset -// CHECK-LL-NEXT: %2 = bitcast i8* %add.ptr to %class.test1_A* -// CHECK-LL-NEXT: br label %cast.end3 -// CHECK-LL: cast.null2: -// CHECK-LL-NEXT: br label %cast.end3 -// CHECK-LL: cast.end3: -// CHECK-LL-NEXT: %3 = phi %class.test1_A* [ %2, %cast.notnull1 ], [ null, %cast.null2 ] -// CHECK-LL-NEXT: store %class.test1_A* %3, %class.test1_A** %ap -// CHECK-LL-NEXT: %tmp = load %class.test1_A** %bp -// CHECK-LL-NEXT: %4 = icmp ne %class.test1_A* %tmp, null -// CHECK-LL-NEXT: br i1 %4, label %5, label %9 -// CHECK-LL: ; <label>:5 -// CHECK-LL-NEXT: %6 = bitcast %class.test1_A* %tmp to i8* -// CHECK-LL-NEXT: %7 = call i8* @__dynamic_cast(i8* %6, i8* bitcast (%0* @_ZTI7test1_B to i8*), i8* bitcast (%1* @_ZTI7test1_D to i8*), i64 -1) ; <i8*> [#uses=1] -// CHECK-LL-NEXT: %8 = bitcast i8* %7 to %class.test1_D* -// CHECK-LL-NEXT: br label %10 -// CHECK-LL: ; <label>:9 -// CHECK-LL-NEXT: br label %10 -// CHECK-LL: ; <label>:10 -// CHECK-LL-NEXT: %11 = phi %class.test1_D* [ %8, %5 ], [ null, %9 ] -// CHECK-LL-NEXT: store %class.test1_D* %11, %class.test1_D** %dp -// CHECK-LL-NEXT: %tmp4 = load %class.test1_D** %dp -// CHECK-LL-NEXT: %cmp = icmp eq %class.test1_D* %tmp4, null -// CHECK-LL-NEXT: br i1 %cmp, label %if.then, label %if.else -// CHECK-LL: if.then: -// CHECK-LL-NEXT: %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 1) -// CHECK-LL-NEXT: br label %if.end -// CHECK-LL: if.else: -// CHECK-LL-NEXT: %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 1) -// CHECK-LL-NEXT: br label %if.end -// CHECK-LL: if.end: -// CHECK-LL-NEXT: %tmp6 = load %class.test1_A** %bp -// CHECK-LL-NEXT: %12 = icmp ne %class.test1_A* %tmp6, null -// CHECK-LL-NEXT: br i1 %12, label %13, label %17 -// CHECK-LL: ; <label>:13 -// CHECK-LL-NEXT: %14 = bitcast %class.test1_A* %tmp6 to i8* -// CHECK-LL-NEXT: %15 = call i8* @__dynamic_cast(i8* %14, i8* bitcast ({{.*}} @_ZTI7test1_B to i8*), i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i64 -1) -// CHECK-LL-NEXT: %16 = bitcast i8* %15 to %class.test1_A* -// CHECK-LL-NEXT: br label %18 -// CHECK-LL: ; <label>:17 -// CHECK-LL-NEXT: br label %18 -// CHECK-LL: ; <label>:18 -// CHECK-LL-NEXT: %19 = phi %class.test1_A* [ %16, %13 ], [ null, %17 ] -// CHECK-LL-NEXT: store %class.test1_A* %19, %class.test1_A** %ap -// CHECK-LL-NEXT: %tmp7 = load %class.test1_A** %ap -// CHECK-LL-NEXT: %cmp8 = icmp eq %class.test1_A* %tmp7, null -// CHECK-LL-NEXT: br i1 %cmp8, label %if.then9, label %if.else11 -// CHECK-LL: if.then9: -// CHECK-LL-NEXT: %call10 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 2) -// CHECK-LL-NEXT: br label %if.end13 -// CHECK-LL: if.else11: -// CHECK-LL-NEXT: %call12 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 2) -// CHECK-LL-NEXT: br label %if.end13 -// CHECK-LL: if.end13: -// CHECK-LL-NEXT: %tmp14 = load %class.test1_A** %ap -// CHECK-LL-NEXT: %20 = icmp ne %class.test1_A* %tmp14, null -// CHECK-LL-NEXT: br i1 %20, label %21, label %25 -// CHECK-LL: ; <label>:21 -// CHECK-LL-NEXT: %22 = bitcast %class.test1_A* %tmp14 to i8* -// CHECK-LL-NEXT: %23 = call i8* @__dynamic_cast({{.*}} %22, i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_B to i8*), i64 -1) -// CHECK-LL-NEXT: %24 = bitcast i8* %23 to %class.test1_A* -// CHECK-LL-NEXT: br label %26 -// CHECK-LL: ; <label>:25 -// CHECK-LL-NEXT: br label %26 -// CHECK-LL: ; <label>:26 -// CHECK-LL-NEXT: %27 = phi %class.test1_A* [ %24, %21 ], [ null, %25 ] -// CHECK-LL-NEXT: store %class.test1_A* %27, %class.test1_A** %bp -// CHECK-LL-NEXT: %tmp15 = load %class.test1_A** %bp -// CHECK-LL-NEXT: %cmp16 = icmp eq %class.test1_A* %tmp15, null -// CHECK-LL-NEXT: br i1 %cmp16, label %if.then17, label %if.else19 -// CHECK-LL: if.then17: -// CHECK-LL-NEXT: %call18 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 3) -// CHECK-LL-NEXT: br label %if.end21 -// CHECK-LL: if.else19: -// CHECK-LL-NEXT: %call20 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 3) -// CHECK-LL-NEXT: br label %if.end21 -// CHECK-LL: if.end21: -// CHECK-LL-NEXT: br i1 false, label %cast.null27, label %cast.notnull22 -// CHECK-LL: cast.notnull22: -// CHECK-LL-NEXT: %vtable23 = load i8** bitcast (%class.test1_D* @test1_d to i8**) -// CHECK-LL-NEXT: %vbase.offset.ptr24 = getelementptr i8* %vtable23, i64 -24 -// CHECK-LL-NEXT: %28 = bitcast i8* %vbase.offset.ptr24 to i64* -// CHECK-LL-NEXT: %vbase.offset25 = load i64* %28 -// CHECK-LL-NEXT: %add.ptr26 = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 %vbase.offset25 -// CHECK-LL-NEXT: %29 = bitcast i8* %add.ptr26 to %class.test1_A* -// CHECK-LL-NEXT: br label %cast.end28 -// CHECK-LL: cast.null27: -// CHECK-LL-NEXT: br label %cast.end28 -// CHECK-LL: cast.end28: -// CHECK-LL-NEXT: %30 = phi %class.test1_A* [ %29, %cast.notnull22 ], [ null, %cast.null27 ] -// CHECK-LL-NEXT: store %class.test1_A* %30, %class.test1_A** %ap -// CHECK-LL-NEXT: %tmp29 = load %class.test1_A** %ap -// CHECK-LL-NEXT: %cmp30 = icmp ne %class.test1_A* %tmp29, null -// CHECK-LL-NEXT: br i1 %cmp30, label %if.then31, label %if.else33 -// CHECK-LL: if.then31: -// CHECK-LL-NEXT: %call32 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 4) -// CHECK-LL-NEXT: br label %if.end35 -// CHECK-LL: if.else33: -// CHECK-LL-NEXT: %call34 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 4) -// CHECK-LL-NEXT: br label %if.end35 -// CHECK-LL: if.end35: -// CHECK-LL-NEXT: br i1 false, label %cast.null43, label %cast.notnull38 -// CHECK-LL: cast.notnull38: -// CHECK-LL-NEXT: %vtable39 = load i8** bitcast (%class.test1_F* @test1_f to i8**) -// CHECK-LL-NEXT: %vbase.offset.ptr40 = getelementptr i8* %vtable39, i64 -24 -// CHECK-LL-NEXT: %31 = bitcast i8* %vbase.offset.ptr40 to i64* -// CHECK-LL-NEXT: %vbase.offset41 = load i64* %31 -// CHECK-LL-NEXT: %add.ptr42 = getelementptr i8* getelementptr inbounds (%class.test1_F* @test1_f, i32 0, i32 0, i32 0), i64 %vbase.offset41 -// CHECK-LL-NEXT: %32 = bitcast i8* %add.ptr42 to %class.test1_A* -// CHECK-LL-NEXT: br label %cast.end44 -// CHECK-LL: cast.null43: -// CHECK-LL-NEXT: br label %cast.end44 -// CHECK-LL: cast.end44: -// CHECK-LL-NEXT: %33 = phi %class.test1_A* [ %32, %cast.notnull38 ], [ null, %cast.null43 ] -// CHECK-LL-NEXT: store %class.test1_A* %33, %class.test1_A** %ap37 -// CHECK-LL-NEXT: %tmp45 = load %class.test1_A** %ap37 -// CHECK-LL-NEXT: %cmp46 = icmp ne %class.test1_A* %tmp45, null -// CHECK-LL-NEXT: br i1 %cmp46, label %if.then47, label %if.else49 -// CHECK-LL: if.then47: -// CHECK-LL-NEXT: %call48 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 6) -// CHECK-LL-NEXT: br label %if.end51 -// CHECK-LL: if.else49: -// CHECK-LL-NEXT: %call50 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 6) -// CHECK-LL-NEXT: br label %if.end51 -// CHECK-LL: if.end51: -// CHECK-LL-NEXT: %tmp54 = load %class.test1_A** %ap37 -// CHECK-LL-NEXT: %34 = icmp ne %class.test1_A* %tmp54, null -// CHECK-LL-NEXT: br i1 %34, label %35, label %39 -// CHECK-LL: ; <label>:35 -// CHECK-LL-NEXT: %36 = bitcast %class.test1_A* %tmp54 to i8* -// CHECK-LL-NEXT: %37 = call i8* @__dynamic_cast(i8* %36, i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_D to i8*), i64 -1) -// CHECK-LL-NEXT: %38 = bitcast i8* %37 to %class.test1_D* -// CHECK-LL-NEXT: br label %40 -// CHECK-LL: ; <label>:39 -// CHECK-LL-NEXT: br label %40 -// CHECK-LL: ; <label>:40 -// CHECK-LL-NEXT: %41 = phi %class.test1_D* [ %38, %35 ], [ null, %39 ] -// CHECK-LL-NEXT: store %class.test1_D* %41, %class.test1_D** %dp53 -// CHECK-LL-NEXT: %tmp55 = load %class.test1_D** %dp53 -// CHECK-LL-NEXT: %cmp56 = icmp eq %class.test1_D* %tmp55, null -// CHECK-LL-NEXT: br i1 %cmp56, label %if.then57, label %if.else59 -// CHECK-LL: if.then57: -// CHECK-LL-NEXT: %call58 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 7) -// CHECK-LL-NEXT: br label %if.end61 -// CHECK-LL: if.else59: -// CHECK-LL-NEXT: %call60 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 7) -// CHECK-LL-NEXT: br label %if.end61 -// CHECK-LL: if.end61: -// CHECK-LL-NEXT: %tmp63 = load %class.test1_A** %ap37 -// CHECK-LL-NEXT: %42 = icmp ne %class.test1_A* %tmp63, null -// CHECK-LL-NEXT: br i1 %42, label %43, label %47 -// CHECK-LL: ; <label>:43 -// CHECK-LL-NEXT: %44 = bitcast %class.test1_A* %tmp63 to i8* -// CHECK-LL-NEXT: %45 = call i8* @__dynamic_cast(i8* %44, i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_E to i8*), i64 -1) -// CHECK-LL-NEXT: %46 = bitcast i8* %45 to %class.test1_E* -// CHECK-LL-NEXT: br label %48 -// CHECK-LL: ; <label>:47 -// CHECK-LL-NEXT: br label %48 -// CHECK-LL: ; <label>:48 -// CHECK-LL-NEXT: %49 = phi %class.test1_E* [ %46, %43 ], [ null, %47 ] -// CHECK-LL-NEXT: store %class.test1_E* %49, %class.test1_E** %ep1 -// CHECK-LL-NEXT: %tmp64 = load %class.test1_E** %ep1 -// CHECK-LL-NEXT: %cmp65 = icmp ne %class.test1_E* %tmp64, null -// CHECK-LL-NEXT: br i1 %cmp65, label %if.then66, label %if.else68 -// CHECK-LL: if.then66: -// CHECK-LL-NEXT: %call67 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 8) -// CHECK-LL-NEXT: br label %if.end70 -// CHECK-LL: if.else68: -// CHECK-LL-NEXT: %call69 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 8) -// CHECK-LL-NEXT: br label %if.end70 -// CHECK-LL: if.end70: -// CHECK-LL-NEXT: store %class.test1_D* @test1_d, %class.test1_D** %dp -// CHECK-LL-NEXT: %tmp71 = load %class.test1_D** %dp -// CHECK-LL-NEXT: %cmp72 = icmp eq %class.test1_D* %tmp71, @test1_d -// CHECK-LL-NEXT: br i1 %cmp72, label %if.then73, label %if.else75 -// CHECK-LL: if.then73: -// CHECK-LL-NEXT: %call74 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 9) -// CHECK-LL-NEXT: br label %if.end77 -// CHECK-LL: if.else75: -// CHECK-LL-NEXT: %call76 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 9) -// CHECK-LL-NEXT: br label %if.end77 -// CHECK-LL: if.end77: -// CHECK-LL-NEXT: store %class.test1_D* @test1_d, %class.test1_D** %cdp -// CHECK-LL-NEXT: %tmp79 = load %class.test1_D** %cdp -// CHECK-LL-NEXT: %cmp80 = icmp eq %class.test1_D* %tmp79, @test1_d -// CHECK-LL-NEXT: br i1 %cmp80, label %if.then81, label %if.else83 -// CHECK-LL: if.then81: -// CHECK-LL-NEXT: %call82 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 10) -// CHECK-LL-NEXT: br label %if.end85 -// CHECK-LL: if.else83: -// CHECK-LL-NEXT: %call84 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 10) -// CHECK-LL-NEXT: br label %if.end85 -// CHECK-LL: if.end85: -// CHECK-LL-NEXT: br i1 false, label %50, label %53 -// CHECK-LL: ; <label>:50 -// CHECK-LL-NEXT: %51 = call i8* @__dynamic_cast(i8* null, i8* bitcast ({{.*}}* @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_D to i8*), i64 -1) -// CHECK-LL-NEXT: %52 = bitcast i8* %51 to %class.test1_D* -// CHECK-LL-NEXT: br label %54 -// CHECK-LL: ; <label>:53 -// CHECK-LL-NEXT: br label %54 -// CHECK-LL: ; <label>:54 -// CHECK-LL-NEXT: %55 = phi %class.test1_D* [ %52, %50 ], [ null, %53 ] -// CHECK-LL-NEXT: store %class.test1_D* %55, %class.test1_D** %dp -// CHECK-LL-NEXT: %tmp86 = load %class.test1_D** %dp -// CHECK-LL-NEXT: %cmp87 = icmp eq %class.test1_D* %tmp86, null -// CHECK-LL-NEXT: br i1 %cmp87, label %if.then88, label %if.else90 -// CHECK-LL: if.then88: -// CHECK-LL-NEXT: %call89 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 11) -// CHECK-LL-NEXT: br label %if.end92 -// CHECK-LL: if.else90: -// CHECK-LL-NEXT: %call91 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 11) -// CHECK-LL-NEXT: br label %if.end92 -// CHECK-LL: if.end92: -// CHECK-LL-NEXT: br i1 false, label %cast.null98, label %cast.notnull93 -// CHECK-LL: cast.notnull93: -// CHECK-LL-NEXT: %vtable94 = load i8** bitcast (%class.test1_D* @test1_d to i8**) -// CHECK-LL-NEXT: %vbase.offset.ptr95 = getelementptr i8* %vtable94, i64 -24 -// CHECK-LL-NEXT: %56 = bitcast i8* %vbase.offset.ptr95 to i64* -// CHECK-LL-NEXT: %vbase.offset96 = load i64* %56 -// CHECK-LL-NEXT: %add.ptr97 = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 %vbase.offset96 -// CHECK-LL-NEXT: %57 = bitcast i8* %add.ptr97 to %class.test1_A* -// CHECK-LL-NEXT: br label %cast.end99 -// CHECK-LL: cast.null98: -// CHECK-LL-NEXT: br label %cast.end99 -// CHECK-LL: cast.end99: -// CHECK-LL-NEXT: %58 = phi %class.test1_A* [ %57, %cast.notnull93 ], [ null, %cast.null98 ] -// CHECK-LL-NEXT: store %class.test1_A* %58, %class.test1_A** %ap -// CHECK-LL-NEXT: %tmp100 = load %class.test1_A** %ap -// CHECK-LL-NEXT: br i1 false, label %cast.null106, label %cast.notnull101 -// CHECK-LL: cast.notnull101: -// CHECK-LL-NEXT: %vtable102 = load i8** bitcast (%class.test1_D* @test1_d to i8**) -// CHECK-LL-NEXT: %vbase.offset.ptr103 = getelementptr i8* %vtable102, i64 -24 -// CHECK-LL-NEXT: %59 = bitcast i8* %vbase.offset.ptr103 to i64* -// CHECK-LL-NEXT: %vbase.offset104 = load i64* %59 -// CHECK-LL-NEXT: %add.ptr105 = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 %vbase.offset104 -// CHECK-LL-NEXT: %60 = bitcast i8* %add.ptr105 to %class.test1_A* -// CHECK-LL-NEXT: br label %cast.end107 -// CHECK-LL: cast.null106: -// CHECK-LL-NEXT: br label %cast.end107 -// CHECK-LL: cast.end107: -// CHECK-LL-NEXT: %61 = phi %class.test1_A* [ %60, %cast.notnull101 ], [ null, %cast.null106 ] -// CHECK-LL-NEXT: %cmp108 = icmp eq %class.test1_A* %tmp100, %61 -// CHECK-LL-NEXT: br i1 %cmp108, label %if.then109, label %if.else111 -// CHECK-LL: if.then109: -// CHECK-LL-NEXT: %call110 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 12) -// CHECK-LL-NEXT: br label %if.end113 -// CHECK-LL: if.else111: -// CHECK-LL-NEXT: %call112 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 12) -// CHECK-LL-NEXT: br label %if.end113 -// CHECK-LL: if.end113: -// CHECK-LL-NEXT: br i1 false, label %cast.null116, label %cast.notnull115 -// CHECK-LL: cast.notnull115: -// CHECK-LL-NEXT: br label %cast.end117 -// CHECK-LL: cast.null116: -// CHECK-LL-NEXT: br label %cast.end117 -// CHECK-LL: cast.end117: -// CHECK-LL-NEXT: %62 = phi %class.test1_E* [ bitcast (%class.test1_F* @test1_f to %class.test1_E*), %cast.notnull115 ], [ null, %cast.null116 ] -// CHECK-LL-NEXT: store %class.test1_E* %62, %class.test1_E** %ep -// CHECK-LL-NEXT: %tmp118 = load %class.test1_E** %ep -// CHECK-LL-NEXT: br i1 false, label %cast.null120, label %cast.notnull119 -// CHECK-LL: cast.notnull119: -// CHECK-LL-NEXT: br label %cast.end121 -// CHECK-LL: cast.null120: -// CHECK-LL-NEXT: br label %cast.end121 -// CHECK-LL: cast.end121: -// CHECK-LL-NEXT: %63 = phi %class.test1_E* [ bitcast (%class.test1_F* @test1_f to %class.test1_E*), %cast.notnull119 ], [ null, %cast.null120 ] -// CHECK-LL-NEXT: %cmp122 = icmp eq %class.test1_E* %tmp118, %63 -// CHECK-LL-NEXT: br i1 %cmp122, label %if.then123, label %if.else125 -// CHECK-LL: if.then123: -// CHECK-LL-NEXT: %call124 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 13) -// CHECK-LL-NEXT: br label %if.end127 -// CHECK-LL: if.else125: -// CHECK-LL-NEXT: %call126 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 13) -// CHECK-LL-NEXT: br label %if.end127 -// CHECK-LL: if.end127: -// CHECK-LL-NEXT: %tmp129 = load %class.test1_A** %ap -// CHECK-LL-NEXT: %64 = icmp ne %class.test1_A* %tmp129, null -// CHECK-LL-NEXT: br i1 %64, label %65, label %70 -// CHECK-LL: ; <label>:65 -// CHECK-LL-NEXT: %66 = bitcast %class.test1_A* %tmp129 to i64** -// CHECK-LL-NEXT: %vtable130 = load i64** %66 -// CHECK-LL-NEXT: %67 = getelementptr inbounds i64* %vtable130, i64 -2 -// CHECK-LL-NEXT: %"offset to top" = load i64* %67 -// CHECK-LL-NEXT: %68 = bitcast %class.test1_A* %tmp129 to i8* -// CHECK-LL-NEXT: %69 = getelementptr inbounds i8* %68, i64 %"offset to top" -// CHECK-LL-NEXT: br label %71 -// CHECK-LL: ; <label>:70 -// CHECK-LL-NEXT: br label %71 -// CHECK-LL: ; <label>:71 -// CHECK-LL-NEXT: %72 = phi i8* [ %69, %65 ], [ null, %70 ] -// CHECK-LL-NEXT: store i8* %72, i8** %vp -// CHECK-LL-NEXT: %tmp131 = load i8** %vp -// CHECK-LL-NEXT: %cmp132 = icmp eq i8* %tmp131, getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0) -// CHECK-LL-NEXT: br i1 %cmp132, label %if.then133, label %if.else135 -// CHECK-LL: if.then133: -// CHECK-LL-NEXT: %call134 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 14) -// CHECK-LL-NEXT: br label %if.end137 -// CHECK-LL: if.else135: -// CHECK-LL-NEXT: %call136 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 14) -// CHECK-LL-NEXT: br label %if.end137 -// CHECK-LL: if.end137: -// CHECK-LL-NEXT: %tmp139 = load %class.test1_A** %ap -// CHECK-LL-NEXT: %73 = icmp ne %class.test1_A* %tmp139, null -// CHECK-LL-NEXT: br i1 %73, label %74, label %79 -// CHECK-LL: ; <label>:74 -// CHECK-LL-NEXT: %75 = bitcast %class.test1_A* %tmp139 to i64** -// CHECK-LL-NEXT: %vtable140 = load i64** %75 -// CHECK-LL-NEXT: %76 = getelementptr inbounds i64* %vtable140, i64 -2 -// CHECK-LL-NEXT: %"offset to top141" = load i64* %76 -// CHECK-LL-NEXT: %77 = bitcast %class.test1_A* %tmp139 to i8* -// CHECK-LL-NEXT: %78 = getelementptr inbounds i8* %77, i64 %"offset to top141" -// CHECK-LL-NEXT: br label %80 -// CHECK-LL: ; <label>:79 -// CHECK-LL-NEXT: br label %80 -// CHECK-LL: ; <label>:80 -// CHECK-LL-NEXT: %81 = phi i8* [ %78, %74 ], [ null, %79 ] -// CHECK-LL-NEXT: store i8* %81, i8** %cvp -// CHECK-LL-NEXT: %tmp142 = load i8** %cvp -// CHECK-LL-NEXT: %cmp143 = icmp eq i8* %tmp142, getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0) -// CHECK-LL-NEXT: br i1 %cmp143, label %if.then144, label %if.else146 -// CHECK-LL: if.then144: -// CHECK-LL-NEXT: %call145 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 15) -// CHECK-LL-NEXT: br label %if.end148 -// CHECK-LL: if.else146: -// CHECK-LL-NEXT: %call147 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 15) -// CHECK-LL-NEXT: br label %if.end148 -// CHECK-LL: if.end148: +// CHECK-LL: [[bp:%.*]] = alloca %class.test1_A*, align 8 +// CHECK-LL-NEXT: [[ap:%.*]] = alloca %class.test1_A*, align 8 +// CHECK-LL-NEXT: [[dp:%.*]] = alloca %class.test1_D*, align 8 +// CHECK-LL-NEXT: [[ap37:%.*]] = alloca %class.test1_A*, align 8 +// CHECK-LL-NEXT: [[dp53:%.*]] = alloca %class.test1_D*, align 8 +// CHECK-LL-NEXT: [[ep1:%.*]] = alloca %class.test1_E*, align 8 +// CHECK-LL-NEXT: [[cdp:%.*]] = alloca %class.test1_D*, align 8 +// CHECK-LL-NEXT: [[ep:%.*]] = alloca %class.test1_E*, align 8 +// CHECK-LL-NEXT: [[vp:%.*]] = alloca i8*, align 8 +// CHECK-LL-NEXT: [[cvp:%.*]] = alloca i8*, align 8 +// CHECK-LL-NEXT: br i1 false, label %[[castnull:.*]], label %[[castnotnull:.*]] +// CHECK-LL: [[castnotnull]] +// CHECK-LL-NEXT: br label %[[castend:.*]] +// CHECK-LL: [[castnull]] +// CHECK-LL-NEXT: br label %[[castend]] +// CHECK-LL: [[castend]] +// CHECK-LL-NEXT: [[v0:%.*]] = phi %class.test1_A* [ bitcast (%class.test1_D* @test1_d to %class.test1_A*), %[[castnotnull]] ], [ null, %[[castnull]] ] +// CHECK-LL-NEXT: store %class.test1_A* [[v0]], %class.test1_A** [[bp]] +// CHECK-LL-NEXT: br i1 false, label %[[castnull2:.*]], label %[[castnotnull1:.*]] +// CHECK-LL: [[castnotnull1]] +// CHECK-LL-NEXT: [[vtable:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**) +// CHECK-LL-NEXT: [[vbaseoffsetptr:%.*]] = getelementptr i8* [[vtable]], i64 -24 +// CHECK-LL-NEXT: [[v1:%.*]] = bitcast i8* [[vbaseoffsetptr]] to i64* +// CHECK-LL-NEXT: [[vbaseoffset:%.*]] = load i64* [[v1]] +// CHECK-LL-NEXT: [[addptr:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset:.*]] +// CHECK-LL-NEXT: [[v2:%.*]] = bitcast i8* [[addptr]] to %class.test1_A* +// CHECK-LL-NEXT: br label %[[castend3:.*]] +// CHECK-LL: [[castnull2]] +// CHECK-LL-NEXT: br label %[[castend3]] +// CHECK-LL: [[castend3]] +// CHECK-LL-NEXT: [[v3:%.*]] = phi %class.test1_A* [ [[v2]], %[[castnotnull1]] ], [ null, %[[castnull2]] ] +// CHECK-LL-NEXT: store %class.test1_A* [[v3]], %class.test1_A** [[ap]] +// CHECK-LL-NEXT: [[tmp:%.*]] = load %class.test1_A** [[bp]] +// CHECK-LL-NEXT: [[v4:%.*]] = icmp ne %class.test1_A* [[tmp]], null +// CHECK-LL-NEXT: br i1 [[v4]], label %[[v5:.*]], label %[[v9:.*]] +// CHECK-LL: ; <label>:[[v5]] +// CHECK-LL-NEXT: [[v6:%.*]] = bitcast %class.test1_A* [[tmp]] to i8* +// CHECK-LL-NEXT: [[v7:%.*]] = call i8* @__dynamic_cast(i8* [[v6]], i8* bitcast (%0* @_ZTI7test1_B to i8*), i8* bitcast (%1* @_ZTI7test1_D to i8*), i64 -1) ; <i8*> [#uses=1] +// CHECK-LL-NEXT: [[v8:%.*]] = bitcast i8* [[v7]] to %class.test1_D* +// CHECK-LL-NEXT: br label %[[v10:.*]] +// CHECK-LL: ; <label>:[[v9]] +// CHECK-LL-NEXT: br label %[[v10]] +// CHECK-LL: ; <label>:[[v10]] +// CHECK-LL-NEXT: [[v11:%.*]] = phi %class.test1_D* [ [[v8]], %[[v5]] ], [ null, %[[v9]] ] +// CHECK-LL-NEXT: store %class.test1_D* [[v11]], %class.test1_D** [[dp]] +// CHECK-LL-NEXT: [[tmp4:%.*]] = load %class.test1_D** [[dp]] +// CHECK-LL-NEXT: [[cmp:%.*]] = icmp eq %class.test1_D* [[tmp4]], null +// CHECK-LL-NEXT: br i1 [[cmp]], label %[[ifthen:.*]], label %[[ifelse:.*]] +// CHECK-LL: [[ifthen]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 1) +// CHECK-LL-NEXT: br label %[[ifend:.*]] +// CHECK-LL: [[ifelse]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 1) +// CHECK-LL-NEXT: br label %[[ifend]] +// CHECK-LL: [[ifend]] +// CHECK-LL-NEXT: [[tmp6:%.*]] = load %class.test1_A** [[bp]] +// CHECK-LL-NEXT: [[v12:%.*]] = icmp ne %class.test1_A* [[tmp6]], null +// CHECK-LL-NEXT: br i1 [[v12]], label %[[v13:.*]], label %[[v17:.*]] +// CHECK-LL: ; <label>:[[v13]] +// CHECK-LL-NEXT: [[v14:%.*]] = bitcast %class.test1_A* [[tmp6]] to i8* +// CHECK-LL-NEXT: [[v15:%.*]] = call i8* @__dynamic_cast(i8* [[v14]], i8* bitcast ({{.*}} @_ZTI7test1_B to i8*), i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i64 -1) +// CHECK-LL-NEXT: [[v16:%.*]] = bitcast i8* [[v15]] to %class.test1_A* +// CHECK-LL-NEXT: br label %[[v18:.*]] +// CHECK-LL: ; <label>:[[v17]] +// CHECK-LL-NEXT: br label %[[v18]] +// CHECK-LL: ; <label>:[[v18]] +// CHECK-LL-NEXT: [[v19:%.*]] = phi %class.test1_A* [ [[v16]], %[[v13]] ], [ null, %[[v17]] ] +// CHECK-LL-NEXT: store %class.test1_A* [[v19]], %class.test1_A** [[ap]] +// CHECK-LL-NEXT: [[tmp7:%.*]] = load %class.test1_A** [[ap]] +// CHECK-LL-NEXT: [[cmp8:%.*]] = icmp eq %class.test1_A* [[tmp7]], null +// CHECK-LL-NEXT: br i1 [[cmp8]], label %[[ifthen9:.*]], label %[[ifelse11:.*]] +// CHECK-LL: [[ifthen9]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 2) +// CHECK-LL-NEXT: br label %[[ifend13:.*]] +// CHECK-LL: [[ifelse11]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 2) +// CHECK-LL-NEXT: br label %[[ifend13]] +// CHECK-LL: [[ifend13]] +// CHECK-LL-NEXT: [[tmp14:%.*]] = load %class.test1_A** [[ap]] +// CHECK-LL-NEXT: [[v20:%.*]] = icmp ne %class.test1_A* [[tmp14]], null +// CHECK-LL-NEXT: br i1 [[v20]], label %[[v21:.*]], label %[[v25:.*]] +// CHECK-LL: ; <label>:[[v21]] +// CHECK-LL-NEXT: [[v22:%.*]] = bitcast %class.test1_A* [[tmp14]] to i8* +// CHECK-LL-NEXT: [[v23:%.*]] = call i8* @__dynamic_cast({{.*}} [[v22]], i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_B to i8*), i64 -1) +// CHECK-LL-NEXT: [[v24:%.*]] = bitcast i8* [[v23]] to %class.test1_A* +// CHECK-LL-NEXT: br label %[[v26:.*]] +// CHECK-LL: ; <label>:[[v25]] +// CHECK-LL-NEXT: br label %[[v26]] +// CHECK-LL: ; <label>:[[v26]] +// CHECK-LL-NEXT: [[v27:%.*]] = phi %class.test1_A* [ [[v24]], %[[v21]] ], [ null, %[[v25]] ] +// CHECK-LL-NEXT: store %class.test1_A* [[v27]], %class.test1_A** [[bp]] +// CHECK-LL-NEXT: [[tmp15:%.*]] = load %class.test1_A** [[bp]] +// CHECK-LL-NEXT: [[cmp16:%.*]] = icmp eq %class.test1_A* [[tmp15]], null +// CHECK-LL-NEXT: br i1 [[cmp16]], label %[[ifthen17:.*]], label %[[ifelse19:.*]] +// CHECK-LL: [[ifthen17]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 3) +// CHECK-LL-NEXT: br label %[[ifend21:.*]] +// CHECK-LL: [[ifelse19]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 3) +// CHECK-LL-NEXT: br label %[[ifend21]] +// CHECK-LL: [[ifend21]] +// CHECK-LL-NEXT: br i1 false, label %[[castnull27:.*]], label %[[castnotnull22:.*]] +// CHECK-LL: [[castnotnull22]] +// CHECK-LL-NEXT: [[vtable23:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**) +// CHECK-LL-NEXT: [[vbaseoffsetptr24:%.*]] = getelementptr i8* [[vtable23]], i64 -24 +// CHECK-LL-NEXT: [[v28:%.*]] = bitcast i8* [[vbaseoffsetptr24]] to i64* +// CHECK-LL-NEXT: [[vbaseoffset25:%.*]] = load i64* [[v28]] +// CHECK-LL-NEXT: [[addptr26:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset25]] +// CHECK-LL-NEXT: [[v29:%.*]] = bitcast i8* [[addptr26]] to %class.test1_A* +// CHECK-LL-NEXT: br label %[[castend28:.*]] +// CHECK-LL: [[castnull27]] +// CHECK-LL-NEXT: br label %[[castend28]] +// CHECK-LL: [[castend28]] +// CHECK-LL-NEXT: [[v30:%.*]] = phi %class.test1_A* [ [[v29]], %[[castnotnull22]] ], [ null, %[[castnull27]] ] +// CHECK-LL-NEXT: store %class.test1_A* [[v30]], %class.test1_A** [[ap]] +// CHECK-LL-NEXT: [[tmp29:%.*]] = load %class.test1_A** [[ap]] +// CHECK-LL-NEXT: [[cmp30:%.*]] = icmp ne %class.test1_A* [[tmp29]], null +// CHECK-LL-NEXT: br i1 [[cmp30]], label %[[ifthen31:.*]], label %[[ifelse33:.*]] +// CHECK-LL: [[ifthen31]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 4) +// CHECK-LL-NEXT: br label %[[ifend35:.*]] +// CHECK-LL: [[ifelse33]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 4) +// CHECK-LL-NEXT: br label %[[ifend35]] +// CHECK-LL: [[ifend35]] +// CHECK-LL-NEXT: br i1 false, label %[[castnull43:.*]], label %[[castnotnull38:.*]] +// CHECK-LL: [[castnotnull38]] +// CHECK-LL-NEXT: [[vtable39:%.*]] = load i8** bitcast (%class.test1_F* @test1_f to i8**) +// CHECK-LL-NEXT: [[vbaseoffsetptr40:%.*]] = getelementptr i8* [[vtable39]], i64 -24 +// CHECK-LL-NEXT: [[v31:%.*]] = bitcast i8* [[vbaseoffsetptr40]] to i64* +// CHECK-LL-NEXT: [[vbaseoffset41:%.*]] = load i64* [[v31]] +// CHECK-LL-NEXT: [[addptr42:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_F* @test1_f, i32 0, i32 0, i32 0), i64 [[vbaseoffset41]] +// CHECK-LL-NEXT: [[v32:%.*]] = bitcast i8* [[addptr42]] to %class.test1_A* +// CHECK-LL-NEXT: br label %[[castend44:.*]] +// CHECK-LL: [[castnull43]] +// CHECK-LL-NEXT: br label %[[castend44]] +// CHECK-LL: [[castend44]] +// CHECK-LL-NEXT: [[v33:%.*]] = phi %class.test1_A* [ [[v32]], %[[castnotnull38]] ], [ null, %[[castnull43]] ] +// CHECK-LL-NEXT: store %class.test1_A* [[v33]], %class.test1_A** [[ap37]] +// CHECK-LL-NEXT: [[tmp45:%.*]] = load %class.test1_A** [[ap37]] +// CHECK-LL-NEXT: [[cmp46:%.*]] = icmp ne %class.test1_A* [[tmp45]], null +// CHECK-LL-NEXT: br i1 [[cmp46]], label %[[ifthen47:.*]], label %[[ifelse49:.*]] +// CHECK-LL: [[ifthen47]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 6) +// CHECK-LL-NEXT: br label %[[ifend51:.*]] +// CHECK-LL: [[ifelse49]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 6) +// CHECK-LL-NEXT: br label %[[ifend51]] +// CHECK-LL: [[ifend51]] +// CHECK-LL-NEXT: [[tmp54:%.*]] = load %class.test1_A** [[ap37]] +// CHECK-LL-NEXT: [[v34:%.*]] = icmp ne %class.test1_A* [[tmp54]], null +// CHECK-LL-NEXT: br i1 [[v34]], label %[[v35:.*]], label %[[v39:.*]] +// CHECK-LL: ; <label>:[[v35]] +// CHECK-LL-NEXT: [[v36:%.*]] = bitcast %class.test1_A* [[tmp54]] to i8* +// CHECK-LL-NEXT: [[v37:%.*]] = call i8* @__dynamic_cast(i8* [[v36]], i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_D to i8*), i64 -1) +// CHECK-LL-NEXT: [[v38:%.*]] = bitcast i8* [[v37]] to %class.test1_D* +// CHECK-LL-NEXT: br label %[[v40:.*]] +// CHECK-LL: ; <label>:[[v39]] +// CHECK-LL-NEXT: br label %[[v40]] +// CHECK-LL: ; <label>:[[v40]] +// CHECK-LL-NEXT: [[v41:%.*]] = phi %class.test1_D* [ [[v38]], %[[v35]] ], [ null, %[[v39]] ] +// CHECK-LL-NEXT: store %class.test1_D* [[v41]], %class.test1_D** [[dp53]] +// CHECK-LL-NEXT: [[tmp55:%.*]] = load %class.test1_D** [[dp53]] +// CHECK-LL-NEXT: [[cmp56:%.*]] = icmp eq %class.test1_D* [[tmp55]], null +// CHECK-LL-NEXT: br i1 [[cmp56]], label %[[ifthen57:.*]], label %[[ifelse59:.*]] +// CHECK-LL: [[ifthen57]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 7) +// CHECK-LL-NEXT: br label %[[ifend61:.*]] +// CHECK-LL: [[ifelse59]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 7) +// CHECK-LL-NEXT: br label %[[ifend61]] +// CHECK-LL: [[ifend61]] +// CHECK-LL-NEXT: [[tmp63:%.*]] = load %class.test1_A** [[ap37]] +// CHECK-LL-NEXT: [[v42:%.*]] = icmp ne %class.test1_A* [[tmp63]], null +// CHECK-LL-NEXT: br i1 [[v42]], label %[[v43:.*]], label %[[v47:.*]] +// CHECK-LL: ; <label>:[[v43]] +// CHECK-LL-NEXT: [[v44:%.*]] = bitcast %class.test1_A* [[tmp63]] to i8* +// CHECK-LL-NEXT: [[v45:%.*]] = call i8* @__dynamic_cast(i8* [[v44]], i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_E to i8*), i64 -1) +// CHECK-LL-NEXT: [[v46:%.*]] = bitcast i8* [[v45]] to %class.test1_E* +// CHECK-LL-NEXT: br label %[[v48:.*]] +// CHECK-LL: ; <label>:[[v47]] +// CHECK-LL-NEXT: br label %[[v48]] +// CHECK-LL: ; <label>:[[v48]] +// CHECK-LL-NEXT: [[v49:%.*]] = phi %class.test1_E* [ [[v46]], %[[v43]] ], [ null, %[[v47]] ] +// CHECK-LL-NEXT: store %class.test1_E* [[v49]], %class.test1_E** [[ep1]] +// CHECK-LL-NEXT: [[tmp64:%.*]] = load %class.test1_E** [[ep1]] +// CHECK-LL-NEXT: [[cmp65:%.*]] = icmp ne %class.test1_E* [[tmp64]], null +// CHECK-LL-NEXT: br i1 [[cmp65]], label %[[ifthen66:.*]], label %[[ifelse68:.*]] +// CHECK-LL: [[ifthen66]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 8) +// CHECK-LL-NEXT: br label %[[ifend70:.*]] +// CHECK-LL: [[ifelse68]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 8) +// CHECK-LL-NEXT: br label %[[ifend70]] +// CHECK-LL: [[ifend70]] +// CHECK-LL-NEXT: store %class.test1_D* @test1_d, %class.test1_D** [[dp]] +// CHECK-LL-NEXT: [[tmp71:%.*]] = load %class.test1_D** [[dp]] +// CHECK-LL-NEXT: [[cmp72:%.*]] = icmp eq %class.test1_D* [[tmp71]], @test1_d +// CHECK-LL-NEXT: br i1 [[cmp72]], label %[[ifthen73:.*]], label %[[ifelse75:.*]] +// CHECK-LL: [[ifthen73]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 9) +// CHECK-LL-NEXT: br label %[[ifend77:.*]] +// CHECK-LL: [[ifelse75]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 9) +// CHECK-LL-NEXT: br label %[[ifend77]] +// CHECK-LL: [[ifend77]] +// CHECK-LL-NEXT: store %class.test1_D* @test1_d, %class.test1_D** [[cdp]] +// CHECK-LL-NEXT: [[tmp79:%.*]] = load %class.test1_D** [[cdp]] +// CHECK-LL-NEXT: [[cmp80:%.*]] = icmp eq %class.test1_D* [[tmp79]], @test1_d +// CHECK-LL-NEXT: br i1 [[cmp80]], label %[[ifthen81:.*]], label %[[ifelse83:.*]] +// CHECK-LL: [[ifthen81]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 10) +// CHECK-LL-NEXT: br label %[[ifend85:.*]] +// CHECK-LL: [[ifelse83]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 10) +// CHECK-LL-NEXT: br label %[[ifend85]] +// CHECK-LL: [[ifend85]] +// CHECK-LL-NEXT: br i1 false, label %[[v50:.*]], label %[[v53:.*]] +// CHECK-LL: ; <label>:[[v50]] +// CHECK-LL-NEXT: [[v51:%.*]] = call i8* @__dynamic_cast(i8* null, i8* bitcast ({{.*}}* @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_D to i8*), i64 -1) +// CHECK-LL-NEXT: [[v52:%.*]] = bitcast i8* [[v51]] to %class.test1_D* +// CHECK-LL-NEXT: br label %[[v54:.*]] +// CHECK-LL: ; <label>:[[v53]] +// CHECK-LL-NEXT: br label %[[v54]] +// CHECK-LL: ; <label>:[[v54]] +// CHECK-LL-NEXT: [[v55:%.*]] = phi %class.test1_D* [ [[v52]], %[[v50]] ], [ null, %[[v53]] ] +// CHECK-LL-NEXT: store %class.test1_D* [[v55]], %class.test1_D** [[dp]] +// CHECK-LL-NEXT: [[tmp86:%.*]] = load %class.test1_D** [[dp]] +// CHECK-LL-NEXT: [[cmp87:%.*]] = icmp eq %class.test1_D* [[tmp86]], null +// CHECK-LL-NEXT: br i1 [[cmp87]], label %[[ifthen88:.*]], label %[[ifelse90:.*]] +// CHECK-LL: [[ifthen88]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 11) +// CHECK-LL-NEXT: br label %[[ifend92:.*]] +// CHECK-LL: [[ifelse90]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 11) +// CHECK-LL-NEXT: br label %[[ifend92]] +// CHECK-LL: [[ifend92]] +// CHECK-LL-NEXT: br i1 false, label %[[castnull98:.*]], label %[[castnotnull93:.*]] +// CHECK-LL: [[castnotnull93]] +// CHECK-LL-NEXT: [[vtable94:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**) +// CHECK-LL-NEXT: [[vbaseoffsetptr95:%.*]] = getelementptr i8* [[vtable94]], i64 -24 +// CHECK-LL-NEXT: [[v56:%.*]] = bitcast i8* [[vbaseoffsetptr95]] to i64* +// CHECK-LL-NEXT: [[vbaseoffset96:%.*]] = load i64* [[v56]] +// CHECK-LL-NEXT: [[addptr97:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset96]] +// CHECK-LL-NEXT: [[v57:%.*]] = bitcast i8* [[addptr97]] to %class.test1_A* +// CHECK-LL-NEXT: br label %[[castend99:.*]] +// CHECK-LL: [[castnull98]] +// CHECK-LL-NEXT: br label %[[castend99]] +// CHECK-LL: [[castend99]] +// CHECK-LL-NEXT: [[v58:%.*]] = phi %class.test1_A* [ [[v57]], %[[castnotnull93]] ], [ null, %[[castnull98]] ] +// CHECK-LL-NEXT: store %class.test1_A* [[v58]], %class.test1_A** [[ap]] +// CHECK-LL-NEXT: [[tmp100:%.*]] = load %class.test1_A** [[ap]] +// CHECK-LL-NEXT: br i1 false, label %[[castnull106:.*]], label %[[castnotnull101:.*]] +// CHECK-LL: [[castnotnull101]] +// CHECK-LL-NEXT: [[vtable102:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**) +// CHECK-LL-NEXT: [[vbaseoffsetptr103:%.*]] = getelementptr i8* [[vtable102]], i64 -24 +// CHECK-LL-NEXT: [[v59:%.*]] = bitcast i8* [[vbaseoffsetptr103]] to i64* +// CHECK-LL-NEXT: [[vbaseoffset104:%.*]] = load i64* [[v59]] +// CHECK-LL-NEXT: [[addptr105:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset104]] +// CHECK-LL-NEXT: [[v60:%.*]] = bitcast i8* [[addptr105]] to %class.test1_A* +// CHECK-LL-NEXT: br label %[[castend107:.*]] +// CHECK-LL: [[castnull106]] +// CHECK-LL-NEXT: br label %[[castend107]] +// CHECK-LL: [[castend107]] +// CHECK-LL-NEXT: [[v61:%.*]] = phi %class.test1_A* [ [[v60]], %[[castnotnull101]] ], [ null, %[[castnull106]] ] +// CHECK-LL-NEXT: [[cmp108:%.*]] = icmp eq %class.test1_A* [[tmp100]], [[v61]] +// CHECK-LL-NEXT: br i1 [[cmp108]], label %[[ifthen109:.*]], label %[[ifelse111:.*]] +// CHECK-LL: [[ifthen109]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 12) +// CHECK-LL-NEXT: br label %[[ifend113:.*]] +// CHECK-LL: [[ifelse111]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 12) +// CHECK-LL-NEXT: br label %[[ifend113]] +// CHECK-LL: [[ifend113]] +// CHECK-LL-NEXT: br i1 false, label %[[castnull116:.*]], label %[[castnotnull115:.*]] +// CHECK-LL: [[castnotnull115]] +// CHECK-LL-NEXT: br label %[[castend117:.*]] +// CHECK-LL: [[castnull116]] +// CHECK-LL-NEXT: br label %[[castend117]] +// CHECK-LL: [[castend117]] +// CHECK-LL-NEXT: [[v62:%.*]] = phi %class.test1_E* [ bitcast (%class.test1_F* @test1_f to %class.test1_E*), %[[castnotnull115]] ], [ null, %[[castnull116]] ] +// CHECK-LL-NEXT: store %class.test1_E* [[v62]], %class.test1_E** [[ep]] +// CHECK-LL-NEXT: [[tmp118:%.*]] = load %class.test1_E** [[ep]] +// CHECK-LL-NEXT: br i1 false, label %[[castnull120:.*]], label %[[castnotnull119:.*]] +// CHECK-LL: [[castnotnull119]] +// CHECK-LL-NEXT: br label %[[castend121:.*]] +// CHECK-LL: [[castnull120]] +// CHECK-LL-NEXT: br label %[[castend121]] +// CHECK-LL: [[castend121]] +// CHECK-LL-NEXT: [[v63:%.*]] = phi %class.test1_E* [ bitcast (%class.test1_F* @test1_f to %class.test1_E*), %[[castnotnull119]] ], [ null, %[[castnull120]] ] +// CHECK-LL-NEXT: [[cmp122:%.*]] = icmp eq %class.test1_E* [[tmp118]], [[v63]] +// CHECK-LL-NEXT: br i1 [[cmp122]], label %[[ifthen123:.*]], label %[[ifelse125:.*]] +// CHECK-LL: [[ifthen123]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 13) +// CHECK-LL-NEXT: br label %[[ifend127:.*]] +// CHECK-LL: [[ifelse125]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 13) +// CHECK-LL-NEXT: br label %[[ifend127]] +// CHECK-LL: [[ifend127]] +// CHECK-LL-NEXT: [[tmp129:%.*]] = load %class.test1_A** [[ap]] +// CHECK-LL-NEXT: [[v64:%.*]] = icmp ne %class.test1_A* [[tmp129]], null +// CHECK-LL-NEXT: br i1 [[v64]], label %[[v65:.*]], label %[[v70:.*]] +// CHECK-LL: ; <label>:[[v65]] +// CHECK-LL-NEXT: [[v66:%.*]] = bitcast %class.test1_A* [[tmp129]] to i64** +// CHECK-LL-NEXT: [[vtable130:%.*]] = load i64** [[v66]] +// CHECK-LL-NEXT: [[v67:%.*]] = getelementptr inbounds i64* [[vtable130]], i64 -2 +// CHECK-LL-NEXT: [[offsettotop:%.*]] = load i64* [[v67]] +// CHECK-LL-NEXT: [[v68:%.*]] = bitcast %class.test1_A* [[tmp129]] to i8* +// CHECK-LL-NEXT: [[v69:%.*]] = getelementptr inbounds i8* [[v68]], i64 [[offsettotop]] +// CHECK-LL-NEXT: br label %[[v71:.*]] +// CHECK-LL: ; <label>:[[v70]] +// CHECK-LL-NEXT: br label %[[v71]] +// CHECK-LL: ; <label>:[[v71]] +// CHECK-LL-NEXT: [[v72:%.*]] = phi i8* [ [[v69]], %[[v65]] ], [ null, %[[v70]] ] +// CHECK-LL-NEXT: store i8* [[v72]], i8** [[vp]] +// CHECK-LL-NEXT: [[tmp131:%.*]] = load i8** [[vp]] +// CHECK-LL-NEXT: [[cmp132:%.*]] = icmp eq i8* [[tmp131]], getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0) +// CHECK-LL-NEXT: br i1 [[cmp132]], label %[[ifthen133:.*]], label %[[ifelse135:.*]] +// CHECK-LL: [[ifthen133]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 14) +// CHECK-LL-NEXT: br label %[[ifend137:.*]] +// CHECK-LL: [[ifelse135]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 14) +// CHECK-LL-NEXT: br label %[[ifend137]] +// CHECK-LL: [[ifend137]] +// CHECK-LL-NEXT: [[tmp139:%.*]] = load %class.test1_A** [[ap]] +// CHECK-LL-NEXT: [[v73:%.*]] = icmp ne %class.test1_A* [[tmp139]], null +// CHECK-LL-NEXT: br i1 [[v73]], label %[[v74:.*]], label %[[v79:.*]] +// CHECK-LL: ; <label>:[[v74]] +// CHECK-LL-NEXT: [[v75:%.*]] = bitcast %class.test1_A* [[tmp139]] to i64** +// CHECK-LL-NEXT: [[vtable140:%.*]] = load i64** [[v75]] +// CHECK-LL-NEXT: [[v76:%.*]] = getelementptr inbounds i64* [[vtable140]], i64 -2 +// CHECK-LL-NEXT: [[offsettotop141:%.*]] = load i64* [[v76]] +// CHECK-LL-NEXT: [[v77:%.*]] = bitcast %class.test1_A* [[tmp139]] to i8* +// CHECK-LL-NEXT: [[v78:%.*]] = getelementptr inbounds i8* [[v77]], i64 [[offsettotop141]] +// CHECK-LL-NEXT: br label %[[v80:.*]] +// CHECK-LL: ; <label>:[[v79]] +// CHECK-LL-NEXT: br label %[[v80]] +// CHECK-LL: ; <label>:[[v80]] +// CHECK-LL-NEXT: [[v81:%.*]] = phi i8* [ [[v78]], %[[v74]] ], [ null, %[[v79]] ] +// CHECK-LL-NEXT: store i8* [[v81]], i8** [[cvp]] +// CHECK-LL-NEXT: [[tmp142:%.*]] = load i8** [[cvp]] +// CHECK-LL-NEXT: [[cmp143:%.*]] = icmp eq i8* [[tmp142]], getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0) +// CHECK-LL-NEXT: br i1 [[cmp143]], label %[[ifthen144:.*]], label %[[ifelse146:.*]] +// CHECK-LL: [[ifthen144]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 15) +// CHECK-LL-NEXT: br label %[[ifend148:.*]] +// CHECK-LL: [[ifelse146]] +// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 15) +// CHECK-LL-NEXT: br label %[[ifend148]] +// CHECK-LL: [[ifend148]] // CHECK-LL-NEXT: ret void diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp index dd798f4..d233525 100644 --- a/test/CodeGenCXX/eh.cpp +++ b/test/CodeGenCXX/eh.cpp @@ -10,14 +10,13 @@ void test1() { } // CHECK: define void @_Z5test1v() nounwind { -// CHECK-NEXT:entry: -// CHECK-NEXT: %exception.ptr = alloca i8* -// CHECK-NEXT: %exception = call i8* @__cxa_allocate_exception(i64 8) -// CHECK-NEXT: store i8* %exception, i8** %exception.ptr -// CHECK-NEXT: %0 = bitcast i8* %exception to %struct.test1_D* -// CHECK-NEXT: %tmp = bitcast %struct.test1_D* %0 to i8* -// CHECK-NEXT: call void @llvm.memcpy.i64(i8* %tmp, i8* bitcast (%struct.test1_D* @d1 to i8*), i64 8, i32 8) -// CHECK-NEXT: call void @__cxa_throw(i8* %exception, i8* bitcast (%0* @_ZTI7test1_D to i8*), i8* null) noreturn +// CHECK: %{{exception.ptr|1}} = alloca i8* +// CHECK-NEXT: %{{exception|2}} = call i8* @__cxa_allocate_exception(i64 8) +// CHECK-NEXT: store i8* %{{exception|2}}, i8** %{{exception.ptr|1}} +// CHECK-NEXT: %{{0|3}} = bitcast i8* %{{exception|2}} to %struct.test1_D* +// CHECK-NEXT: %{{tmp|4}} = bitcast %struct.test1_D* %{{0|3}} to i8* +// CHECK-NEXT: call void @llvm.memcpy.i64(i8* %{{tmp|4}}, i8* bitcast (%struct.test1_D* @d1 to i8*), i64 8, i32 8) +// CHECK-NEXT: call void @__cxa_throw(i8* %{{exception|2}}, i8* bitcast (%0* @_ZTI7test1_D to i8*), i8* null) noreturn // CHECK-NEXT: unreachable @@ -33,14 +32,13 @@ void test2() { } // CHECK: define void @_Z5test2v() nounwind { -// CHECK-NEXT:entry: -// CHECK-NEXT: %exception.ptr = alloca i8* -// CHECK-NEXT: %exception = call i8* @__cxa_allocate_exception(i64 16) -// CHECK-NEXT: store i8* %exception, i8** %exception.ptr -// CHECK-NEXT: %0 = bitcast i8* %exception to %struct.test2_D* -// CHECK: invoke void @_ZN7test2_DC1ERKS_(%struct.test2_D* %0, %struct.test2_D* @d2) -// CHECK-NEXT: to label %invoke.cont unwind label %terminate.handler -// CHECK: call void @__cxa_throw(i8* %exception, i8* bitcast (%0* @_ZTI7test2_D to i8*), i8* null) noreturn +// CHECK: %{{exception.ptr|1}} = alloca i8* +// CHECK-NEXT: %{{exception|2}} = call i8* @__cxa_allocate_exception(i64 16) +// CHECK-NEXT: store i8* %{{exception|2}}, i8** %{{\1}} +// CHECK-NEXT: %{{0|3}} = bitcast i8* %{{exception|2}} to %struct.test2_D* +// CHECK: invoke void @_ZN7test2_DC1ERKS_(%struct.test2_D* %{{0|3}}, %struct.test2_D* @d2) +// CHECK-NEXT: to label %{{invoke.cont|8}} unwind label %{{terminate.handler|4}} +// CHECK: call void @__cxa_throw(i8* %{{exception|2}}, i8* bitcast (%{{0|3}}* @_ZTI7test2_D to i8*), i8* null) noreturn // CHECK-NEXT: unreachable @@ -55,13 +53,12 @@ void test3() { } // CHECK: define void @_Z5test3v() nounwind { -// CHECK-NEXT: entry: -// CHECK-NEXT: %exception.ptr = alloca i8* -// CHECK-NEXT: %exception = call i8* @__cxa_allocate_exception(i64 8) -// CHECK-NEXT: store i8* %exception, i8** %exception.ptr -// CHECK-NEXT: %0 = bitcast i8* %exception to %struct.test3_D** -// CHECK-NEXT: store %struct.test3_D* null, %struct.test3_D** %0 -// CHECK-NEXT: call void @__cxa_throw(i8* %exception, i8* bitcast (%1* @_ZTIPV7test3_D to i8*), i8* null) noreturn +// CHECK: %{{exception.ptr|1}} = alloca i8* +// CHECK-NEXT: %{{exception|2}} = call i8* @__cxa_allocate_exception(i64 8) +// CHECK-NEXT: store i8* %{{exception|2}}, i8** %{{exception.ptr|1}} +// CHECK-NEXT: %{{0|3}} = bitcast i8* %{{exception|2}} to %struct.test3_D** +// CHECK-NEXT: store %struct.test3_D* null, %struct.test3_D** +// CHECK-NEXT: call void @__cxa_throw(i8* %{{exception|2}}, i8* bitcast (%1* @_ZTIPV7test3_D to i8*), i8* null) noreturn // CHECK-NEXT: unreachable @@ -70,6 +67,5 @@ void test4() { } // CHECK: define void @_Z5test4v() nounwind { -// CHECK-NEXT: entry: -// CHECK-NEXT: call void @__cxa_rethrow() noreturn +// CHECK: call void @__cxa_rethrow() noreturn // CHECK-NEXT: unreachable diff --git a/test/CodeGenCXX/expr.cpp b/test/CodeGenCXX/expr.cpp index 6d641dc..d92cfb4 100644 --- a/test/CodeGenCXX/expr.cpp +++ b/test/CodeGenCXX/expr.cpp @@ -10,3 +10,7 @@ void test1() { char *xpto; while ( true && xpto[0] ); } + +// PR5514 +int a; +void test2() { ++a+=10; } diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index e8770df..5947587 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -308,4 +308,9 @@ template class Alloc<char>; } // CHECK: define void @_Z1fU13block_pointerFiiiE -void f(int (^)(int, int)) { }
\ No newline at end of file +void f(int (^)(int, int)) { } + +// PR5869 +// CHECK: define internal void @_ZL2f2v +static void f2() {} +void f3() { f2(); } diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp index 149b560..2454dda 100644 --- a/test/CodeGenCXX/member-function-pointers.cpp +++ b/test/CodeGenCXX/member-function-pointers.cpp @@ -128,3 +128,14 @@ namespace BoolMemberPointer { } } +// PR5940 +namespace PR5940 { + class foo { + public: + virtual void baz(void); + }; + + void foo::baz(void) { + void (foo::*ptr)(void) = &foo::baz; + } +} diff --git a/test/CodeGenCXX/reference-init.cpp b/test/CodeGenCXX/reference-init.cpp index 1bfb28a..6c2c6a3 100644 --- a/test/CodeGenCXX/reference-init.cpp +++ b/test/CodeGenCXX/reference-init.cpp @@ -7,3 +7,10 @@ struct nsXPTParamInfo { void a(XPTParamDescriptor *params) { const nsXPTParamInfo& paramInfo = params[0]; } + +// CodeGen of reference initialized const arrays. +namespace PR5911 { + template <typename T, int N> int f(const T (&a)[N]) { return N; } + int iarr[] = { 1 }; + int test() { return f(iarr); } +} diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp index 259fd03..f7f4c9f 100644 --- a/test/CodeGenCXX/virt.cpp +++ b/test/CodeGenCXX/virt.cpp @@ -153,7 +153,7 @@ void test12_foo() { // CHECK-LPLL64: call void % // CHECK-LPLL64: call void % // CHECK-LPLL64: call void % -// CHECK-LPLL64: call void @_ZN8test12_A3fooEv(%class.test14* %tmp11) +// CHECK-LPLL64: call void @_ZN8test12_A3fooEv(%class.test14* %{{.*}}) struct test6_B2 { virtual void funcB2(); char b[1000]; }; @@ -769,55 +769,53 @@ struct test16_D : test16_NV1, virtual test16_B2 { // FIXME: This is the wrong thunk, but until these issues are fixed, better // than nothing. // CHECK-LPLL64:define weak %class.test8_D* @_ZTcvn16_n72_v16_n32_N8test16_D4foo1Ev(%class.test8_D*) -// CHECK-LPLL64:entry: -// CHECK-LPLL64: %retval = alloca %class.test8_D* +// CHECK-LPLL64: %{{retval|2}} = alloca %class.test8_D* // CHECK-LPLL64: %.addr = alloca %class.test8_D* // CHECK-LPLL64: store %class.test8_D* %0, %class.test8_D** %.addr -// CHECK-LPLL64: %this = load %class.test8_D** %.addr -// CHECK-LPLL64: %1 = bitcast %class.test8_D* %this to i8* -// CHECK-LPLL64: %2 = getelementptr inbounds i8* %1, i64 -16 -// CHECK-LPLL64: %3 = bitcast i8* %2 to %class.test8_D* -// CHECK-LPLL64: %4 = bitcast %class.test8_D* %3 to i8* -// CHECK-LPLL64: %5 = bitcast %class.test8_D* %3 to i64** -// CHECK-LPLL64: %vtable = load i64** %5 -// CHECK-LPLL64: %6 = getelementptr inbounds i64* %vtable, i64 -9 -// CHECK-LPLL64: %7 = load i64* %6 -// CHECK-LPLL64: %8 = getelementptr i8* %4, i64 %7 -// CHECK-LPLL64: %9 = bitcast i8* %8 to %class.test8_D* -// CHECK-LPLL64: %call = call %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%class.test8_D* %9) -// CHECK-LPLL64: store %class.test8_D* %call, %class.test8_D** %retval -// CHECK-LPLL64: %10 = load %class.test8_D** %retval -// CHECK-LPLL64: ret %class.test8_D* %10 +// CHECK-LPLL64: %{{this|3}} = load %class.test8_D** %.addr +// CHECK-LPLL64: %{{1|4}} = bitcast %class.test8_D* %{{this|3}} to i8* +// CHECK-LPLL64: %{{2|5}} = getelementptr inbounds i8* %{{1|4}}, i64 -16 +// CHECK-LPLL64: %{{3|6}} = bitcast i8* %{{2|5}} to %class.test8_D* +// CHECK-LPLL64: %{{4|7}} = bitcast %class.test8_D* %{{3|6}} to i8* +// CHECK-LPLL64: %{{5|8}} = bitcast %class.test8_D* %3 to i64** +// CHECK-LPLL64: %{{vtable|9}} = load i64** %{{5|8}} +// CHECK-LPLL64: %{{6|10}} = getelementptr inbounds i64* %{{vtable|9}}, i64 -9 +// CHECK-LPLL64: %{{7|11}} = load i64* %{{6|10}} +// CHECK-LPLL64: %{{8|12}} = getelementptr i8* %{{4|7}}, i64 %{{7|11}} +// CHECK-LPLL64: %{{9|13}} = bitcast i8* %{{8|12}} to %class.test8_D* +// CHECK-LPLL64: %{{call|14}} = call %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%class.test8_D* %{{9|13}}) +// CHECK-LPLL64: store %class.test8_D* %{{call|14}}, %class.test8_D** %{{retval|2}} +// CHECK-LPLL64: %{{10|15}} = load %class.test8_D** %{{retval|2}} +// CHECK-LPLL64: ret %class.test8_D* %{{10|15}} // CHECK-LPLL64:} -// CHECK-LPLL64:define weak %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%class.test8_D*) -// CHECK-LPLL64:entry: -// CHECK-LPLL64: %retval = alloca %class.test8_D* +// CHECK-LPLL64:define weak %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%{{class.test8_D|.*}}*) +// CHECK-LPLL64: %{{retval|2}} = alloca %class.test8_D* // CHECK-LPLL64: %.addr = alloca %class.test8_D* // CHECK-LPLL64: store %class.test8_D* %0, %class.test8_D** %.addr -// CHECK-LPLL64: %this = load %class.test8_D** %.addr -// CHECK-LPLL64: %call = call %class.test8_D* @_ZN8test16_D4foo1Ev(%class.test8_D* %this) -// CHECK-LPLL64: %1 = icmp ne %class.test8_D* %call, null -// CHECK-LPLL64: br i1 %1, label %2, label %12 -// CHECK-LPLL64:; <label>:2 -// CHECK-LPLL64: %3 = bitcast %class.test8_D* %call to i8* -// CHECK-LPLL64: %4 = getelementptr inbounds i8* %3, i64 16 -// CHECK-LPLL64: %5 = bitcast i8* %4 to %class.test8_D* -// CHECK-LPLL64: %6 = bitcast %class.test8_D* %5 to i8* -// CHECK-LPLL64: %7 = bitcast %class.test8_D* %5 to i64** -// CHECK-LPLL64: %vtable = load i64** %7 -// CHECK-LPLL64: %8 = getelementptr inbounds i64* %vtable, i64 -4 -// CHECK-LPLL64: %9 = load i64* %8 -// CHECK-LPLL64: %10 = getelementptr i8* %6, i64 %9 -// CHECK-LPLL64: %11 = bitcast i8* %10 to %class.test8_D* -// CHECK-LPLL64: br label %13 -// CHECK-LPLL64:; <label>:12 -// CHECK-LPLL64: br label %13 -// CHECK-LPLL64:; <label>:13 -// CHECK-LPLL64: %14 = phi %class.test8_D* [ %11, %2 ], [ %call, %12 ] -// CHECK-LPLL64: store %class.test8_D* %14, %class.test8_D** %retval -// CHECK-LPLL64: %15 = load %class.test8_D** %retval -// CHECK-LPLL64: ret %class.test8_D* %15 +// CHECK-LPLL64: %{{this|3}} = load %class.test8_D** %.addr +// CHECK-LPLL64: %{{call|4}} = call %class.test8_D* @_ZN8test16_D4foo1Ev(%class.test8_D* %{{this|3}}) +// CHECK-LPLL64: %{{1|5}} = icmp ne %class.test8_D* %{{call|4}}, null +// CHECK-LPLL64: br i1 %{{1|5}}, label %{{2|6}}, label %{{12|17}} +// CHECK-LPLL64:; <label>:{{2|6}} +// CHECK-LPLL64: %{{3|7}} = bitcast %class.test8_D* %{{call|4}} to i8* +// CHECK-LPLL64: %{{4|8}} = getelementptr inbounds i8* %{{3|7}}, i64 16 +// CHECK-LPLL64: %{{5|9}} = bitcast i8* %4 to %class.test8_D* +// CHECK-LPLL64: %{{6|10}} = bitcast %class.test8_D* %{{5|9}} to i8* +// CHECK-LPLL64: %{{7|11}} = bitcast %class.test8_D* %{{5|9}} to i64** +// CHECK-LPLL64: %{{vtable|12}} = load i64** %{{7|11}} +// CHECK-LPLL64: %{{8|13}} = getelementptr inbounds i64* %vtable, i64 -4 +// CHECK-LPLL64: %{{9|14}} = load i64* %{{8|13}} +// CHECK-LPLL64: %{{10|15}} = getelementptr i8* %{{6|10}}, i64 %{{9|14}} +// CHECK-LPLL64: %{{11|16}} = bitcast i8* %{{10|15}} to %class.test8_D* +// CHECK-LPLL64: br label %{{13|18}} +// CHECK-LPLL64:; <label>:{{12|17}} +// CHECK-LPLL64: br label %{{13|18}} +// CHECK-LPLL64:; <label>:{{13|18}} +// CHECK-LPLL64: %{{14|19}} = phi %class.test8_D* [ %{{11|16}}, %{{2|6}} ], [ %{{call|4}}, %{{12|17}} ] +// CHECK-LPLL64: store %class.test8_D* %{{14|19}}, %class.test8_D** %{{retval|2}} +// CHECK-LPLL64: %{{15|20}} = load %class.test8_D** %{{retval|2}} +// CHECK-LPLL64: ret %class.test8_D* %{{15|20}} // CHECK-LPLL64:} diff --git a/test/CodeGenCXX/virtual-destructor-calls.cpp b/test/CodeGenCXX/virtual-destructor-calls.cpp index ecfcad2..01ca144 100644 --- a/test/CodeGenCXX/virtual-destructor-calls.cpp +++ b/test/CodeGenCXX/virtual-destructor-calls.cpp @@ -8,15 +8,15 @@ struct B : A { virtual ~B(); }; +// Complete dtor. +// CHECK: define void @_ZN1BD1Ev +// CHECK: call void @_ZN1AD2Ev + // Deleting dtor. // CHECK: define void @_ZN1BD0Ev // CHECK: call void @_ZN1AD2Ev // check: call void @_ZdlPv -// Complete dtor. -// CHECK: define void @_ZN1BD1Ev -// CHECK: call void @_ZN1AD2Ev - // Base dtor. // CHECK: define void @_ZN1BD2Ev // CHECK: call void @_ZN1AD2Ev diff --git a/test/CodeGenCXX/vtable-key-function.cpp b/test/CodeGenCXX/vtable-key-function.cpp index 90e8ea6..97a546f 100644 --- a/test/CodeGenCXX/vtable-key-function.cpp +++ b/test/CodeGenCXX/vtable-key-function.cpp @@ -13,3 +13,21 @@ struct A { A::A() { } A::A(int) { } } + +// Make sure that we don't assert when building the vtable for a class +// template specialization or explicit instantiation with a key +// function. +template<typename T> +struct Base { + virtual ~Base(); +}; + +template<typename T> +struct Derived : public Base<T> { }; + +template<> +struct Derived<char> : public Base<char> { + virtual void anchor(); +}; + +void Derived<char>::anchor() { } diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp index 6d3cf24..63e17431 100644 --- a/test/CodeGenCXX/vtable-linkage.cpp +++ b/test/CodeGenCXX/vtable-linkage.cpp @@ -30,6 +30,55 @@ void D::f() { } static struct : D { } e; +// The destructor is the key function. +template<typename T> +struct E { + virtual ~E(); +}; + +template<typename T> E<T>::~E() { } + +// Anchor is the key function +template<> +struct E<char> { + virtual void anchor(); +}; + +void E<char>::anchor() { } + +template struct E<short>; +extern template struct E<int>; + +void use_E() { + E<int> ei; + (void)ei; + E<long> el; + (void)el; +} + +// No key function +template<typename T> +struct F { + virtual void foo() { } +}; + +// No key function +template<> +struct F<char> { + virtual void foo() { } +}; + +template struct F<short>; +extern template struct F<int>; + +void use_F(F<char> &fc) { + F<int> fi; + (void)fi; + F<long> fl; + (void)fl; + fc.foo(); +} + // B has a key function that is not defined in this translation unit so its vtable // has external linkage. // CHECK: @_ZTV1B = external constant @@ -45,6 +94,50 @@ static struct : D { } e; // CHECK: @_ZTI1D = constant // CHECK: @_ZTV1D = constant +// E<char> is an explicit specialization with a key function defined +// in this translation unit, so its vtable should have external +// linkage. +// CHECK: @_ZTS1EIcE = constant +// CHECK: @_ZTI1EIcE = constant +// CHECK: @_ZTV1EIcE = constant + +// E<short> is an explicit template instantiation with a key function +// defined in this translation unit, so its vtable should have +// weak_odr linkage. +// CHECK: @_ZTS1EIsE = weak_odr constant +// CHECK: @_ZTI1EIsE = weak_odr constant +// CHECK: @_ZTV1EIsE = weak_odr constant + +// F<short> is an explicit template instantiation without a key +// function, so its vtable should have weak_odr linkage +// CHECK: @_ZTS1FIsE = weak_odr constant +// CHECK: @_ZTI1FIsE = weak_odr constant +// CHECK: @_ZTV1FIsE = weak_odr constant + +// E<long> is an implicit template instantiation with a key function +// defined in this translation unit, so its vtable should have +// weak_odr linkage. +// CHECK: @_ZTS1EIlE = weak_odr constant +// CHECK: @_ZTI1EIlE = weak_odr constant +// CHECK: @_ZTV1EIlE = weak_odr constant + +// F<long> is an implicit template instantiation with no key function, +// so its vtable should have weak_odr linkage. +// CHECK: @_ZTS1FIlE = weak_odr constant +// CHECK: @_ZTI1FIlE = weak_odr constant +// CHECK: @_ZTV1FIlE = weak_odr constant + +// F<int> is an explicit template instantiation declaration without a +// key function, so its vtable should have weak_odr linkage. +// CHECK: @_ZTS1FIiE = weak_odr constant +// CHECK: @_ZTI1FIiE = weak_odr constant +// CHECK: @_ZTV1FIiE = weak_odr constant + +// E<int> is an explicit template instantiation declaration. It has a +// key function that is not instantiated, so we should only reference +// its vtable, not define it. +// CHECK: @_ZTV1EIiE = external constant + // The anonymous struct for e has no linkage, so the vtable should have // internal linkage. // CHECK: @"_ZTS3$_0" = internal constant @@ -56,3 +149,5 @@ static struct : D { } e; // CHECK: @_ZTSN12_GLOBAL__N_11AE = internal constant // CHECK: @_ZTIN12_GLOBAL__N_11AE = internal constant // CHECK: @_ZTVN12_GLOBAL__N_11AE = internal constant + + diff --git a/test/Coverage/ast-printing.c b/test/Coverage/ast-printing.c index 182bd4d..bbbc366 100644 --- a/test/Coverage/ast-printing.c +++ b/test/Coverage/ast-printing.c @@ -2,5 +2,6 @@ // RUN: %clang_cc1 -ast-print %s // RUN: %clang_cc1 -ast-dump %s // RUN: %clang_cc1 -ast-print-xml -o %t %s +// RUN: %clang_cc1 -print-decl-contexts %s #include "c-language-features.inc" diff --git a/test/Coverage/ast-printing.cpp b/test/Coverage/ast-printing.cpp index e86e799..ce0a569 100644 --- a/test/Coverage/ast-printing.cpp +++ b/test/Coverage/ast-printing.cpp @@ -2,5 +2,7 @@ // RUN: %clang_cc1 -ast-print %s // RUN: %clang_cc1 -ast-dump %s // FIXME: %clang_cc1 -ast-print-xml -o %t %s +// RUN: %clang_cc1 -print-decl-contexts %s +// RUN: %clang_cc1 -dump-record-layouts %s #include "cxx-language-features.inc" diff --git a/test/Coverage/c-language-features.inc b/test/Coverage/c-language-features.inc index bcf4127..3548132 100644 --- a/test/Coverage/c-language-features.inc +++ b/test/Coverage/c-language-features.inc @@ -179,3 +179,12 @@ void f8(x) // Function which inputs an array void f9(int x[]) { } + +// Object literals. +void f10() { + struct f10_s0 { + char iv0[10]; + } x; + + x = (struct f10_s0) { .iv0 = "name" }; +} diff --git a/test/Driver/analyze.c b/test/Driver/analyze.c index 2f850bc..359b0e0 100644 --- a/test/Driver/analyze.c +++ b/test/Driver/analyze.c @@ -6,4 +6,3 @@ // CHECK: "-analyze" // CHECK: "-target-feature" "+sse" -// CHECK: "-fno-math-errno" diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c index c4ea430..f1d6759 100644 --- a/test/Driver/clang_f_opts.c +++ b/test/Driver/clang_f_opts.c @@ -1,11 +1,11 @@ -// RUN: %clang -### -S -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fno-math-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS1 %s -// RUN: %clang -### -S -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fno-math-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS2 %s +// RUN: %clang -### -S -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS1 %s +// RUN: %clang -### -S -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS2 %s // RUN: %clang -### -fshort-enums %s 2>&1 | FileCheck -check-prefix=CHECK-SHORT-ENUMS %s // CHECK-OPTIONS1: -fblocks // CHECK-OPTIONS1: -fpascal-strings -// CHECK-OPTIONS2: -fno-math-errno +// CHECK-OPTIONS2: -fmath-errno // CHECK-OPTIONS2: -fno-builtin // CHECK-OPTIONS2: -fshort-wchar // CHECK-OPTIONS2: -fno-common diff --git a/test/FixIt/typo.c b/test/FixIt/typo.c index 0777551..72e3d65 100644 --- a/test/FixIt/typo.c +++ b/test/FixIt/typo.c @@ -1,17 +1,18 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsyntax-only -fixit -o - | %clang_cc1 -fsyntax-only -pedantic -Werror -x c - +// RUN: %clang_cc1 -fsyntax-only -fixit -o - %s | %clang_cc1 -fsyntax-only -pedantic -Werror -x c - struct Point { float x, y; }; struct Rectangle { - struct Point top_left, bottom_right; + struct Point top_left, // expected-note{{'top_left' declared here}} + bottom_right; }; enum Color { Red, Green, Blue }; struct Window { - struct Rectangle bounds; + struct Rectangle bounds; // expected-note{{'bounds' declared here}} enum Color color; }; diff --git a/test/FixIt/typo.cpp b/test/FixIt/typo.cpp index 12bfc71..c057025 100644 --- a/test/FixIt/typo.cpp +++ b/test/FixIt/typo.cpp @@ -1,15 +1,15 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsyntax-only -fixit -o - | %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ - +// RUN: %clang_cc1 -fsyntax-only -fixit -o - %s | %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ - namespace std { - template<typename T> class basic_string { - int find(const char *substr); - static const int npos = -1; + template<typename T> class basic_string { // expected-note 2{{'basic_string' declared here}} + int find(const char *substr); // expected-note{{'find' declared here}} + static const int npos = -1; // expected-note{{'npos' declared here}} }; - typedef basic_string<char> string; + typedef basic_string<char> string; // expected-note 2{{'string' declared here}} } -namespace otherstd { +namespace otherstd { // expected-note 2{{'otherstd' declared here}} using namespace std; } @@ -21,8 +21,9 @@ tring str2; // expected-error{{unknown type name 'tring'; did you mean 'string'? ::other_std::string str3; // expected-error{{no member named 'other_std' in the global namespace; did you mean 'otherstd'?}} -float area(float radius, float pi) { - return radious * pi; // expected-error{{use of undeclared identifier 'radious'; did you mean 'radius'?}} +float area(float radius, // expected-note{{'radius' declared here}} + float pi) { + return radious * pi; // expected-error{{did you mean 'radius'?}} } bool test_string(std::string s) { @@ -35,9 +36,19 @@ bool test_string(std::string s) { } struct Base { }; -struct Derived : public Base { - int member; +struct Derived : public Base { // expected-note{{base class 'struct Base' specified here}} + int member; // expected-note 3{{'member' declared here}} Derived() : base(), // expected-error{{initializer 'base' does not name a non-static data member or base class; did you mean the base class 'Base'?}} ember() { } // expected-error{{initializer 'ember' does not name a non-static data member or base class; did you mean the member 'member'?}} + + int getMember() const { + return ember; // expected-error{{use of undeclared identifier 'ember'; did you mean 'member'?}} + } + + int &getMember(); }; + +int &Derived::getMember() { + return ember; // expected-error{{use of undeclared identifier 'ember'; did you mean 'member'?}} +} diff --git a/test/FixIt/typo.m b/test/FixIt/typo.m index 2516849..4c3ee5f 100644 --- a/test/FixIt/typo.m +++ b/test/FixIt/typo.m @@ -1,9 +1,89 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsyntax-only -fixit -o - | %clang_cc1 -fsyntax-only -pedantic -Werror -x objective-c - +// FIXME: the test below isn't testing quite what we want... +// RUN: %clang_cc1 -fsyntax-only -fixit -o - %s | %clang_cc1 -fsyntax-only -pedantic -Werror -x objective-c - @interface NSString ++ (int)method:(int)x; @end void test() { + // FIXME: not providing fix-its NSstring *str = @"A string"; // expected-error{{use of undeclared identifier 'NSstring'; did you mean 'NSString'?}} } + +@protocol P1 +@property int *sprop; // expected-note{{'sprop' declared here}} +@end + +@interface A +{ + int his_ivar; // expected-note 2{{'his_ivar' declared here}} + float wibble; +} + +@property int his_prop; // expected-note{{'his_prop' declared here}} +@end + +@interface B : A <P1> +{ + int her_ivar; // expected-note 2{{'her_ivar' declared here}} +} + +@property int her_prop; // expected-note{{'her_prop' declared here}} +- (void)inst_method1:(int)a; ++ (void)class_method1; +@end + +@implementation A +@synthesize his_prop = his_ivar; +@end + +@implementation B +@synthesize her_prop = her_ivar; + +-(void)inst_method1:(int)a { + herivar = a; // expected-error{{use of undeclared identifier 'herivar'; did you mean 'her_ivar'?}} + hisivar = a; // expected-error{{use of undeclared identifier 'hisivar'; did you mean 'his_ivar'?}} + self->herivar = a; // expected-error{{'B' does not have a member named 'herivar'; did you mean 'her_ivar'?}} + self->hisivar = a; // expected-error{{'B' does not have a member named 'hisivar'; did you mean 'his_ivar'?}} + self.hisprop = 0; // expected-error{{property 'hisprop' not found on object of type 'B *'; did you mean 'his_prop'?}} + self.herprop = 0; // expected-error{{property 'herprop' not found on object of type 'B *'; did you mean 'her_prop'?}} + self.s_prop = 0; // expected-error{{property 's_prop' not found on object of type 'B *'; did you mean 'sprop'?}} +} + ++(void)class_method1 { +} +@end + +void test_message_send(B* b) { + // FIXME: Not providing fix-its + [NSstring method:17]; // expected-error{{use of undeclared identifier 'NSstring'; did you mean 'NSString'?}} +} + +@interface Collide // expected-note{{'Collide' declared here}} +{ +@public + int value; // expected-note{{'value' declared here}} +} + +@property int value; // expected-note{{'value' declared here}} +@end + +@implementation Collide +@synthesize value = value; +@end + +void test2(Collide *a) { + a.valu = 17; // expected-error{{property 'valu' not found on object of type 'Collide *'; did you mean 'value'?}} + a->vale = 17; // expected-error{{'Collide' does not have a member named 'vale'; did you mean 'value'?}} +} + +@interface Derived : Collid // expected-error{{cannot find interface declaration for 'Collid', superclass of 'Derived'; did you mean 'Collide'?}} +@end + +@protocol NetworkSocket // expected-note{{'NetworkSocket' declared here}} +- (int)send:(void*)buffer bytes:(int)bytes; +@end + +@interface IPv8 <Network_Socket> // expected-error{{cannot find protocol declaration for 'Network_Socket'; did you mean 'NetworkSocket'?}} +@end diff --git a/test/Frontend/macros.c b/test/Frontend/macros.c new file mode 100644 index 0000000..3170797 --- /dev/null +++ b/test/Frontend/macros.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -DA= -DB=1 -verify -fsyntax-only %s + +int a[(B A) == 1 ? 1 : -1]; + diff --git a/test/Index/TestClassDecl.m b/test/Index/TestClassDecl.m index 5cccf92..fb97de1 100644 --- a/test/Index/TestClassDecl.m +++ b/test/Index/TestClassDecl.m @@ -19,8 +19,8 @@ void function(Foo * arg) // CHECK-scan: {start_line=8 start_col=1 end_line=8 end_col=7} Invalid Cursor => NotImplemented // CHECK-scan: {start_line=8 start_col=8 end_line=8 end_col=10} ObjCClassRef=Foo:8:1 // CHECK-scan: {start_line=8 start_col=11 end_line=9 end_col=1} Invalid Cursor => NoDeclFound -// CHECK-scan: {start_line=10 start_col=1 end_line=11 end_col=1} ObjCInterfaceDecl=Foo:10:1 -// CHECK-scan: {start_line=11 start_col=2 end_line=12 end_col=1} Invalid Cursor => NoDeclFound +// CHECK-scan: {start_line=10 start_col=1 end_line=11 end_col=4} ObjCInterfaceDecl=Foo:10:1 +// CHECK-scan: {start_line=11 start_col=5 end_line=12 end_col=1} Invalid Cursor => NoDeclFound // CHECK-scan: {start_line=13 start_col=1 end_line=13 end_col=4} FunctionDecl=function:13:6 // CHECK-scan: {start_line=13 start_col=5 end_line=13 end_col=5} Invalid Cursor => NoDeclFound // CHECK-scan: {start_line=13 start_col=6 end_line=13 end_col=14} FunctionDecl=function:13:6 @@ -30,23 +30,9 @@ void function(Foo * arg) // CHECK-scan: {start_line=13 start_col=20 end_line=13 end_col=20} FunctionDecl=function:13:6 // CHECK-scan: {start_line=13 start_col=21 end_line=13 end_col=23} ParmDecl=arg:13:21 // CHECK-scan: {start_line=13 start_col=24 end_line=16 end_col=1} FunctionDecl=function:13:6 -// CHECK-scan: {start_line=16 start_col=2 end_line=52 end_col=1} Invalid Cursor => NoDeclFound +// CHECK-scan: {start_line=16 start_col=2 end_line=38 end_col=1} Invalid Cursor => NoDeclFound - - - - - - - - - - - - - - -// CHECK-load: TestClassDecl.m:10:12: ObjCInterfaceDecl=Foo:10:1 [Context=TestClassDecl.m] -// CHECK-load: TestClassDecl.m:13:6: FunctionDefn=function [Context=TestClassDecl.m] -// CHECK-load: TestClassDecl.m:13:21: ParmDecl=arg:13:21 [Context=function] +// CHECK-load: TestClassDecl.m:10:12: ObjCInterfaceDecl=Foo:10:1 [Context=TestClassDecl.m] [Extent=10:1:11:4] +// CHECK-load: TestClassDecl.m:13:6: FunctionDefn=function [Context=TestClassDecl.m] [Extent=13:6:16:1] +// CHECK-load: TestClassDecl.m:13:21: ParmDecl=arg:13:21 [Context=function] [Extent=13:21:13:23] diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m index 6ee50ae..8a1e4d1 100644 --- a/test/Index/c-index-api-loadTU-test.m +++ b/test/Index/c-index-api-loadTU-test.m @@ -1,22 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -emit-pch -x objective-c %s -o %t.ast // RUN: c-index-test -test-load-tu %t.ast all | FileCheck %s - - - - - - - - - - - - - - - - @interface Foo { } @@ -58,28 +42,6 @@ enum { someEnum }; -// CHECK: c-index-api-loadTU-test.m:20:12: ObjCInterfaceDecl=Foo:20:1 [Context=c-index-api-loadTU-test.m] -// CHECK: c-index-api-loadTU-test.m:24:1: ObjCInstanceMethodDecl=foo:24:1 [Context=Foo] -// CHECK: c-index-api-loadTU-test.m:25:1: ObjCClassMethodDecl=fooC:25:1 [Context=Foo] -// CHECK: c-index-api-loadTU-test.m:29:12: ObjCInterfaceDecl=Bar:29:1 [Context=c-index-api-loadTU-test.m] -// CHECK: c-index-api-loadTU-test.m:29:18: ObjCSuperClassRef=Foo:29:1 [Context=Bar] -// CHECK: c-index-api-loadTU-test.m:35:1: ObjCCategoryDecl=FooCat:35:1 [Context=c-index-api-loadTU-test.m] -// CHECK: c-index-api-loadTU-test.m:20:1: ObjCClassRef=Foo:35:1 [Context=FooCat] -// CHECK: c-index-api-loadTU-test.m:36:1: ObjCInstanceMethodDecl=catMethodWithFloat::36:1 [Context=FooCat] -// CHECK: c-index-api-loadTU-test.m:37:1: ObjCInstanceMethodDecl=floatMethod:37:1 [Context=FooCat] -// CHECK: c-index-api-loadTU-test.m:40:1: ObjCProtocolDecl=Proto:40:1 [Context=c-index-api-loadTU-test.m] -// CHECK: c-index-api-loadTU-test.m:41:1: ObjCInstanceMethodDecl=pMethod:41:1 [Context=Proto] -// CHECK: c-index-api-loadTU-test.m:44:1: ObjCProtocolDecl=SubP:44:1 [Context=c-index-api-loadTU-test.m] -// CHECK: c-index-api-loadTU-test.m:40:1: ObjCProtocolRef=Proto:40:1 [Context=SubP] -// CHECK: c-index-api-loadTU-test.m:45:1: ObjCInstanceMethodDecl=spMethod:45:1 [Context=SubP] -// CHECK: c-index-api-loadTU-test.m:48:12: ObjCInterfaceDecl=Baz:48:1 [Context=c-index-api-loadTU-test.m] -// CHECK: c-index-api-loadTU-test.m:48:18: ObjCSuperClassRef=Bar:48:1 [Context=Baz] -// CHECK: c-index-api-loadTU-test.m:44:1: ObjCProtocolRef=SubP:44:1 [Context=Baz] -// CHECK: c-index-api-loadTU-test.m:50:9: ObjCIvarDecl=_anIVar:50:9 [Context=Baz] -// CHECK: c-index-api-loadTU-test.m:53:1: ObjCInstanceMethodDecl=bazMethod:53:1 [Context=Baz] -// CHECK: c-index-api-loadTU-test.m:57:1: EnumDecl=:57:1 [Context=c-index-api-loadTU-test.m] -// CHECK: c-index-api-loadTU-test.m:58:3: EnumConstantDecl=someEnum:58:3 [Context=] - int main (int argc, const char * argv[]) { Baz * bee; id a = [bee foo]; @@ -91,10 +53,33 @@ int main (int argc, const char * argv[]) { main(someEnum, (const char **)bee); } -// CHECK: c-index-api-loadTU-test.m:83:5: FunctionDefn=main [Context=c-index-api-loadTU-test.m] -// CHECK: c-index-api-loadTU-test.m:83:15: ParmDecl=argc:83:15 [Context=main] -// CHECK: c-index-api-loadTU-test.m:83:34: ParmDecl=argv:83:34 [Context=main] -// CHECK: c-index-api-loadTU-test.m:84:8: VarDecl=bee:84:8 [Context=main] -// CHECK: c-index-api-loadTU-test.m:85:5: VarDecl=a:85:5 [Context=main] -// CHECK: c-index-api-loadTU-test.m:86:12: VarDecl=c:86:12 [Context=main] -// CHECK: c-index-api-loadTU-test.m:87:13: VarDecl=d:87:13 [Context=main] +// CHECK: c-index-api-loadTU-test.m:4:12: ObjCInterfaceDecl=Foo:4:1 [Context=c-index-api-loadTU-test.m] [Extent=4:1:11:4] +// CHECK: c-index-api-loadTU-test.m:8:1: ObjCInstanceMethodDecl=foo:8:1 [Context=Foo] [Extent=8:1:8:6] +// CHECK: c-index-api-loadTU-test.m:9:1: ObjCClassMethodDecl=fooC:9:1 [Context=Foo] [Extent=9:1:9:7] +// CHECK: c-index-api-loadTU-test.m:13:12: ObjCInterfaceDecl=Bar:13:1 [Context=c-index-api-loadTU-test.m] [Extent=13:1:17:4] +// CHECK: c-index-api-loadTU-test.m:13:18: ObjCSuperClassRef=Foo:13:1 [Context=Bar] [Extent=13:1:17:4] +// CHECK: c-index-api-loadTU-test.m:19:1: ObjCCategoryDecl=FooCat:19:1 [Context=c-index-api-loadTU-test.m] [Extent=19:1:22:4] +// CHECK: c-index-api-loadTU-test.m:4:1: ObjCClassRef=Foo:19:1 [Context=FooCat] [Extent=19:1:22:4] +// CHECK: c-index-api-loadTU-test.m:20:1: ObjCInstanceMethodDecl=catMethodWithFloat::20:1 [Context=FooCat] [Extent=20:1:20:40] +// CHECK: c-index-api-loadTU-test.m:21:1: ObjCInstanceMethodDecl=floatMethod:21:1 [Context=FooCat] [Extent=21:1:21:22] +// CHECK: c-index-api-loadTU-test.m:24:1: ObjCProtocolDecl=Proto:24:1 [Context=c-index-api-loadTU-test.m] [Extent=24:1:26:4] +// CHECK: c-index-api-loadTU-test.m:25:1: ObjCInstanceMethodDecl=pMethod:25:1 [Context=Proto] [Extent=25:1:25:10] +// CHECK: c-index-api-loadTU-test.m:28:1: ObjCProtocolDecl=SubP:28:1 [Context=c-index-api-loadTU-test.m] [Extent=28:1:30:4] +// CHECK: c-index-api-loadTU-test.m:24:1: ObjCProtocolRef=Proto:24:1 [Context=SubP] [Extent=24:1:26:4] +// CHECK: c-index-api-loadTU-test.m:29:1: ObjCInstanceMethodDecl=spMethod:29:1 [Context=SubP] [Extent=29:1:29:11] +// CHECK: c-index-api-loadTU-test.m:32:12: ObjCInterfaceDecl=Baz:32:1 [Context=c-index-api-loadTU-test.m] [Extent=32:1:39:4] +// CHECK: c-index-api-loadTU-test.m:32:18: ObjCSuperClassRef=Bar:32:1 [Context=Baz] [Extent=32:1:39:4] +// CHECK: c-index-api-loadTU-test.m:28:1: ObjCProtocolRef=SubP:28:1 [Context=Baz] [Extent=28:1:30:4] +// CHECK: c-index-api-loadTU-test.m:34:9: ObjCIvarDecl=_anIVar:34:9 [Context=Baz] [Extent=34:9:34:15] +// CHECK: c-index-api-loadTU-test.m:37:1: ObjCInstanceMethodDecl=bazMethod:37:1 [Context=Baz] [Extent=37:1:37:20] +// CHECK: c-index-api-loadTU-test.m:41:1: EnumDecl=:41:1 [Context=c-index-api-loadTU-test.m] [Extent=41:1:43:1] +// CHECK: c-index-api-loadTU-test.m:42:3: EnumConstantDecl=someEnum:42:3 [Context=] [Extent=42:3:42:10] +// CHECK: c-index-api-loadTU-test.m:45:5: FunctionDefn=main [Context=c-index-api-loadTU-test.m] [Extent=45:5:54:1] +// CHECK: c-index-api-loadTU-test.m:45:15: ParmDecl=argc:45:15 [Context=main] [Extent=45:15:45:18] +// CHECK: c-index-api-loadTU-test.m:45:34: ParmDecl=argv:45:34 [Context=main] [Extent=45:34:45:37] +// CHECK: c-index-api-loadTU-test.m:46:8: VarDecl=bee:46:8 [Context=main] [Extent=46:8:46:10] +// CHECK: c-index-api-loadTU-test.m:47:5: VarDecl=a:47:5 [Context=main] [Extent=47:5:47:17] +// CHECK: c-index-api-loadTU-test.m:48:12: VarDecl=c:48:12 [Context=main] [Extent=48:12:48:25] +// CHECK: c-index-api-loadTU-test.m:49:13: VarDecl=d:49:13 [Context=main] [Extent=49:13:49:13] + + diff --git a/test/Index/c-index-getCursor-test.m b/test/Index/c-index-getCursor-test.m index 23ae218..03ab5a8 100644 --- a/test/Index/c-index-getCursor-test.m +++ b/test/Index/c-index-getCursor-test.m @@ -57,10 +57,10 @@ int main (int argc, const char * argv[]) { // CHECK: {start_line=7 start_col=1 end_line=7 end_col=6} ObjCInstanceMethodDecl=foo:7:1 // CHECK: {start_line=7 start_col=7 end_line=7 end_col=7} ObjCInterfaceDecl=Foo:3:1 // CHECK: {start_line=8 start_col=1 end_line=8 end_col=7} ObjCClassMethodDecl=fooC:8:1 -// CHECK: {start_line=8 start_col=8 end_line=10 end_col=1} ObjCInterfaceDecl=Foo:3:1 -// CHECK: {start_line=10 start_col=2 end_line=11 end_col=1} Invalid Cursor => NoDeclFound -// CHECK: {start_line=12 start_col=1 end_line=16 end_col=1} ObjCInterfaceDecl=Bar:12:1 -// CHECK: {start_line=16 start_col=2 end_line=17 end_col=1} Invalid Cursor => NoDeclFound +// CHECK: {start_line=8 start_col=8 end_line=10 end_col=4} ObjCInterfaceDecl=Foo:3:1 +// CHECK: {start_line=10 start_col=5 end_line=11 end_col=1} Invalid Cursor => NoDeclFound +// CHECK: {start_line=12 start_col=1 end_line=16 end_col=4} ObjCInterfaceDecl=Bar:12:1 +// CHECK: {start_line=16 start_col=5 end_line=17 end_col=1} Invalid Cursor => NoDeclFound // CHECK: {start_line=18 start_col=1 end_line=18 end_col=24} ObjCCategoryDecl=FooCat:18:1 // CHECK: {start_line=19 start_col=1 end_line=19 end_col=28} ObjCInstanceMethodDecl=catMethodWithFloat::19:1 // CHECK: {start_line=19 start_col=29 end_line=19 end_col=33} ParmDecl=fArg:19:36 @@ -69,24 +69,24 @@ int main (int argc, const char * argv[]) { // CHECK: {start_line=19 start_col=40 end_line=19 end_col=40} ObjCInstanceMethodDecl=catMethodWithFloat::19:1 // CHECK: {start_line=19 start_col=41 end_line=19 end_col=41} ObjCCategoryDecl=FooCat:18:1 // CHECK: {start_line=20 start_col=1 end_line=20 end_col=22} ObjCInstanceMethodDecl=floatMethod:20:1 -// CHECK: {start_line=20 start_col=23 end_line=21 end_col=1} ObjCCategoryDecl=FooCat:18:1 -// CHECK: {start_line=21 start_col=2 end_line=22 end_col=1} Invalid Cursor => NoDeclFound +// CHECK: {start_line=20 start_col=23 end_line=21 end_col=4} ObjCCategoryDecl=FooCat:18:1 +// CHECK: {start_line=21 start_col=5 end_line=22 end_col=1} Invalid Cursor => NoDeclFound // CHECK: {start_line=23 start_col=1 end_line=23 end_col=16} ObjCProtocolDecl=Proto:23:1 // CHECK: {start_line=24 start_col=1 end_line=24 end_col=10} ObjCInstanceMethodDecl=pMethod:24:1 -// CHECK: {start_line=24 start_col=11 end_line=25 end_col=1} ObjCProtocolDecl=Proto:23:1 -// CHECK: {start_line=25 start_col=2 end_line=26 end_col=1} Invalid Cursor => NoDeclFound +// CHECK: {start_line=24 start_col=11 end_line=25 end_col=4} ObjCProtocolDecl=Proto:23:1 +// CHECK: {start_line=25 start_col=5 end_line=26 end_col=1} Invalid Cursor => NoDeclFound // CHECK: {start_line=27 start_col=1 end_line=27 end_col=23} ObjCProtocolDecl=SubP:27:1 // CHECK: {start_line=28 start_col=1 end_line=28 end_col=11} ObjCInstanceMethodDecl=spMethod:28:1 -// CHECK: {start_line=28 start_col=12 end_line=29 end_col=1} ObjCProtocolDecl=SubP:27:1 -// CHECK: {start_line=29 start_col=2 end_line=30 end_col=1} Invalid Cursor => NoDeclFound +// CHECK: {start_line=28 start_col=12 end_line=29 end_col=4} ObjCProtocolDecl=SubP:27:1 +// CHECK: {start_line=29 start_col=5 end_line=30 end_col=1} Invalid Cursor => NoDeclFound // CHECK: {start_line=31 start_col=1 end_line=33 end_col=4} ObjCInterfaceDecl=Baz:31:1 // CHECK: {start_line=33 start_col=5 end_line=33 end_col=7} Invalid Cursor => NotImplemented // CHECK: {start_line=33 start_col=8 end_line=33 end_col=8} ObjCInterfaceDecl=Baz:31:1 // CHECK: {start_line=33 start_col=9 end_line=33 end_col=15} Invalid Cursor => NotImplemented // CHECK: {start_line=33 start_col=16 end_line=35 end_col=1} ObjCInterfaceDecl=Baz:31:1 // CHECK: {start_line=36 start_col=1 end_line=36 end_col=20} ObjCInstanceMethodDecl=bazMethod:36:1 -// CHECK: {start_line=36 start_col=21 end_line=38 end_col=1} ObjCInterfaceDecl=Baz:31:1 -// CHECK: {start_line=38 start_col=2 end_line=39 end_col=1} Invalid Cursor => NoDeclFound +// CHECK: {start_line=36 start_col=21 end_line=38 end_col=4} ObjCInterfaceDecl=Baz:31:1 +// CHECK: {start_line=38 start_col=5 end_line=39 end_col=1} Invalid Cursor => NoDeclFound // CHECK: {start_line=40 start_col=1 end_line=41 end_col=2} EnumDecl=:40:1 // CHECK: {start_line=41 start_col=3 end_line=41 end_col=10} EnumConstantDecl=someEnum:41:3 // CHECK: {start_line=41 start_col=11 end_line=42 end_col=1} EnumDecl=:40:1 diff --git a/test/Index/code-completion.cpp b/test/Index/code-completion.cpp index 55d068a..7fd4376 100644 --- a/test/Index/code-completion.cpp +++ b/test/Index/code-completion.cpp @@ -34,20 +34,20 @@ void test_overloaded() { } // CHECK-MEMBER: FieldDecl:{ResultType double}{TypedText member} +// CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member} +// CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member} // CHECK-MEMBER: FunctionDecl:{ResultType void}{Informative Y::}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i}}{RightParen )} -// CHECK-MEMBER: EnumConstantDecl:{ResultType enum X::E}{Informative E::}{TypedText Val1} -// CHECK-MEMBER: FunctionDecl:{ResultType void}{Informative X::}{TypedText ~X}{LeftParen (}{RightParen )} -// CHECK-MEMBER: FunctionDecl:{ResultType void}{Informative Y::}{TypedText ~Y}{LeftParen (}{RightParen )} -// CHECK-MEMBER: FunctionDecl:{ResultType void}{TypedText ~Z}{LeftParen (}{RightParen )} // CHECK-MEMBER: FunctionDecl:{ResultType int}{TypedText operator int}{LeftParen (}{RightParen )}{Informative const} // CHECK-MEMBER: FunctionDecl:{ResultType struct Z &}{TypedText operator=}{LeftParen (}{Placeholder struct Z const &}{RightParen )} -// CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member} -// CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member} // CHECK-MEMBER: FunctionDecl:{ResultType struct X &}{Text X::}{TypedText operator=}{LeftParen (}{Placeholder struct X const &}{RightParen )} // CHECK-MEMBER: FunctionDecl:{ResultType struct Y &}{Text Y::}{TypedText operator=}{LeftParen (}{Placeholder struct Y const &}{RightParen )} +// CHECK-MEMBER: EnumConstantDecl:{ResultType enum X::E}{Informative E::}{TypedText Val1} // CHECK-MEMBER: StructDecl:{TypedText X}{Text ::} // CHECK-MEMBER: StructDecl:{TypedText Y}{Text ::} // CHECK-MEMBER: StructDecl:{TypedText Z}{Text ::} +// CHECK-MEMBER: FunctionDecl:{ResultType void}{Informative X::}{TypedText ~X}{LeftParen (}{RightParen )} +// CHECK-MEMBER: FunctionDecl:{ResultType void}{Informative Y::}{TypedText ~Y}{LeftParen (}{RightParen )} +// CHECK-MEMBER: FunctionDecl:{ResultType void}{TypedText ~Z}{LeftParen (}{RightParen )} // CHECK-OVERLOAD: NotImplemented:{ResultType int &}{Text overloaded}{LeftParen (}{Text struct Z z}{Comma , }{CurrentParameter int second}{RightParen )} // CHECK-OVERLOAD: NotImplemented:{ResultType float &}{Text overloaded}{LeftParen (}{Text int i}{Comma , }{CurrentParameter long second}{RightParen )} diff --git a/test/Index/complete-at-directives.m b/test/Index/complete-at-directives.m index 68d1ef4..1d0a471 100644 --- a/test/Index/complete-at-directives.m +++ b/test/Index/complete-at-directives.m @@ -1,16 +1,16 @@ /* Run lines are at the end, since line/column matter in this test. */ -@interface MyClass { } +@interface MyClass { @public } @end @implementation MyClass @end // RUN: c-index-test -code-completion-at=%s:2:2 %s | FileCheck -check-prefix=CHECK-CC1 %s -// CHECK-CC1: {TypedText class}{Text }{Placeholder identifier}{Text ;} -// CHECK-CC1: {TypedText compatibility_alias}{Text }{Placeholder alias}{Text }{Placeholder class} -// CHECK-CC1: {TypedText implementation}{Text }{Placeholder class} -// CHECK-CC1: {TypedText interface}{Text }{Placeholder class} -// CHECK-CC1: {TypedText protocol}{Text }{Placeholder protocol} +// CHECK-CC1: {TypedText class}{HorizontalSpace }{Placeholder identifier}{SemiColon ;} +// CHECK-CC1: {TypedText compatibility_alias}{HorizontalSpace }{Placeholder alias}{HorizontalSpace }{Placeholder class} +// CHECK-CC1: {TypedText implementation}{HorizontalSpace }{Placeholder class} +// CHECK-CC1: {TypedText interface}{HorizontalSpace }{Placeholder class} +// CHECK-CC1: {TypedText protocol}{HorizontalSpace }{Placeholder protocol} // RUN: c-index-test -code-completion-at=%s:3:2 %s | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: {TypedText end} @@ -19,6 +19,41 @@ // CHECK-CC2: {TypedText required} // RUN: c-index-test -code-completion-at=%s:6:2 %s | FileCheck -check-prefix=CHECK-CC3 %s -// CHECK-CC3: {TypedText dynamic}{Text }{Placeholder property} +// CHECK-CC3: {TypedText dynamic}{HorizontalSpace }{Placeholder property} // CHECK-CC3: {TypedText end} -// CHECK-CC3: {TypedText synthesize}{Text }{Placeholder property} +// CHECK-CC3: {TypedText synthesize}{HorizontalSpace }{Placeholder property} + +// RUN: c-index-test -code-completion-at=%s:2:1 %s | FileCheck -check-prefix=CHECK-CC4 %s +// CHECK-CC4: NotImplemented:{TypedText @class}{HorizontalSpace }{Placeholder identifier}{SemiColon ;} +// CHECK-CC4: NotImplemented:{TypedText @compatibility_alias}{HorizontalSpace }{Placeholder alias}{HorizontalSpace }{Placeholder class} +// CHECK-CC4: NotImplemented:{TypedText @implementation}{HorizontalSpace }{Placeholder class} +// CHECK-CC4: NotImplemented:{TypedText @interface}{HorizontalSpace }{Placeholder class} +// CHECK-CC4: NotImplemented:{TypedText @protocol}{HorizontalSpace }{Placeholder protocol} +// CHECK-CC4: NotImplemented:{TypedText _Bool} +// CHECK-CC4: TypedefDecl:{TypedText Class} +// CHECK-CC4: TypedefDecl:{TypedText id} +// CHECK-CC4: TypedefDecl:{TypedText SEL} + +// RUN: c-index-test -code-completion-at=%s:3:1 %s | FileCheck -check-prefix=CHECK-CC5 %s +// CHECK-CC5: {TypedText @end} +// CHECK-CC5: {TypedText @optional} +// CHECK-CC5: {TypedText @property} +// CHECK-CC5: {TypedText @required} +// CHECK-CC5: NotImplemented:{TypedText _Bool} +// CHECK-CC5: TypedefDecl:{TypedText Class} +// CHECK-CC5: TypedefDecl:{TypedText id} +// CHECK-CC5: ObjCInterfaceDecl:{TypedText MyClass} +// CHECK-CC5: TypedefDecl:{TypedText SEL} + +// RUN: c-index-test -code-completion-at=%s:2:23 %s | FileCheck -check-prefix=CHECK-CC6 %s +// CHECK-CC6: NotImplemented:{TypedText package} +// CHECK-CC6: NotImplemented:{TypedText private} +// CHECK-CC6: NotImplemented:{TypedText protected} +// CHECK-CC6: NotImplemented:{TypedText public} + +// RUN: c-index-test -code-completion-at=%s:2:22 %s | FileCheck -check-prefix=CHECK-CC7 %s +// CHECK-CC7: NotImplemented:{TypedText @package} +// CHECK-CC7: NotImplemented:{TypedText @private} +// CHECK-CC7: NotImplemented:{TypedText @protected} +// CHECK-CC7: NotImplemented:{TypedText @public} +// CHECK-CC7: NotImplemented:{TypedText _Bool} diff --git a/test/Index/complete-at-exprstmt.m b/test/Index/complete-at-exprstmt.m index 82c3983..e8efc3c 100644 --- a/test/Index/complete-at-exprstmt.m +++ b/test/Index/complete-at-exprstmt.m @@ -1,6 +1,6 @@ /* The run lines are below, because this test is line- and column-number sensitive. */ -@interface MyClass { } +@interface MyClass { int ivar; } - (int)myMethod:(int)arg; @end @@ -13,11 +13,25 @@ // CHECK-CC1: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )} // CHECK-CC1: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )} // CHECK-CC1: {TypedText selector}{LeftParen (}{Placeholder selector}{RightParen )} -// CHECK-CC1: {TypedText synchronized}{Text }{LeftParen (}{Placeholder expression}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }} -// CHECK-CC1: {TypedText throw}{Text }{Placeholder expression}{Text ;} +// CHECK-CC1: {TypedText synchronized}{HorizontalSpace }{LeftParen (}{Placeholder expression}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }} +// CHECK-CC1: {TypedText throw}{HorizontalSpace }{Placeholder expression}{SemiColon ;} // CHECK-CC1: {TypedText try}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @catch}{LeftParen (}{Placeholder parameter}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @finally}{LeftBrace {}{Placeholder statements}{RightBrace }} // RUN: c-index-test -code-completion-at=%s:9:19 %s | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )} // CHECK-CC2: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )} // CHECK-CC2: {TypedText selector}{LeftParen (}{Placeholder selector}{RightParen )} - +// RUN: c-index-test -code-completion-at=%s:9:3 %s | FileCheck -check-prefix=CHECK-CC3 %s +// CHECK-CC3: NotImplemented:{TypedText @encode}{LeftParen (}{Placeholder type-name}{RightParen )} +// CHECK-CC3: NotImplemented:{TypedText @protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )} +// CHECK-CC3: NotImplemented:{TypedText @selector}{LeftParen (}{Placeholder selector}{RightParen )} +// CHECK-CC3: NotImplemented:{TypedText @synchronized}{HorizontalSpace }{LeftParen (}{Placeholder expression}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }} +// CHECK-CC3: NotImplemented:{TypedText @throw}{HorizontalSpace }{Placeholder expression}{SemiColon ;} +// CHECK-CC3: NotImplemented:{TypedText @try}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @catch}{LeftParen (}{Placeholder parameter}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @finally}{LeftBrace {}{Placeholder statements}{RightBrace }} +// CHECK-CC3: NotImplemented:{ResultType SEL}{TypedText _cmd} +// CHECK-CC3: ParmDecl:{ResultType int}{TypedText arg} +// CHECK-CC3: TypedefDecl:{TypedText Class} +// CHECK-CC3: TypedefDecl:{TypedText id} +// CHECK-CC3: ObjCIvarDecl:{ResultType int}{TypedText ivar} +// CHECK-CC3: ObjCInterfaceDecl:{TypedText MyClass} +// CHECK-CC3: TypedefDecl:{TypedText SEL} +// CHECK-CC3: NotImplemented:{ResultType MyClass *}{TypedText self} diff --git a/test/Index/complete-objc-message.m b/test/Index/complete-objc-message.m index a7b37fd..096ed24 100644 --- a/test/Index/complete-objc-message.m +++ b/test/Index/complete-objc-message.m @@ -105,7 +105,7 @@ void f(Ellipsis *e) { // RUN: c-index-test -code-completion-at=%s:23:19 %s | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: {TypedText categoryClassMethod} -// CHECK-CC1: {TypedText classMethod1:}{Placeholder (id)a}{Text withKeyword:}{Placeholder (int)b} +// CHECK-CC1: {TypedText classMethod1:}{Placeholder (id)a}{HorizontalSpace }{Text withKeyword:}{Placeholder (int)b} // CHECK-CC1: {TypedText classMethod2} // CHECK-CC1: {TypedText new} // CHECK-CC1: {TypedText protocolClassMethod} @@ -117,10 +117,10 @@ void f(Ellipsis *e) { // CHECK-CC3: ObjCClassMethodDecl:{ResultType int}{TypedText MyClassMethod:}{Placeholder (id)obj} // CHECK-CC3: ObjCClassMethodDecl:{ResultType int}{TypedText MyPrivateMethod} // RUN: c-index-test -code-completion-at=%s:65:16 %s | FileCheck -check-prefix=CHECK-CC4 %s -// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{Text second:}{Placeholder (id)y} +// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{HorizontalSpace }{Text second:}{Placeholder (id)y} // CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyPrivateInstMethod} // RUN: c-index-test -code-completion-at=%s:74:9 %s | FileCheck -check-prefix=CHECK-CC5 %s -// CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{Text second:}{Placeholder (id)y} +// CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{HorizontalSpace }{Text second:}{Placeholder (id)y} // CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod} // RUN: c-index-test -code-completion-at=%s:82:8 %s | FileCheck -check-prefix=CHECK-CC6 %s // CHECK-CC6: ObjCInstanceMethodDecl:{ResultType id}{TypedText protocolInstanceMethod:}{Placeholder (int)value} @@ -128,21 +128,20 @@ void f(Ellipsis *e) { // RUN: c-index-test -code-completion-at=%s:95:8 %s | FileCheck -check-prefix=CHECK-CC7 %s // CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method} // CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i} -// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2} -// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj} -// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{Text SomeArg:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj} -// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2} +// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text Arg2:}{Placeholder (int)i2} +// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj} +// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text SomeArg:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj} +// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text Arg2:}{Placeholder (int)i2} // RUN: c-index-test -code-completion-at=%s:95:17 %s | FileCheck -check-prefix=CHECK-CC8 %s // CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText } -// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2} -// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj} -// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText SomeArg:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj} +// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text Arg2:}{Placeholder (int)i2} +// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj} +// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText SomeArg:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj} // RUN: c-index-test -code-completion-at=%s:95:24 %s | FileCheck -check-prefix=CHECK-CC9 %s // CHECK-CC9: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText Arg2:}{Placeholder (int)i2} // CHECK-CC9: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText OtherArg:}{Placeholder (id)obj} // RUN: c-index-test -code-completion-at=%s:61:11 %s | FileCheck -check-prefix=CHECK-CCA %s // CHECK-CCA: {ResultType SEL}{TypedText _cmd} -// CHECK-CCA: {ResultType Class}{TypedText self} // CHECK-CCA: TypedefDecl:{TypedText Class} // CHECK-CCA: ObjCInterfaceDecl:{TypedText Foo} // CHECK-CCA: FunctionDecl:{ResultType void}{TypedText func}{LeftParen (}{RightParen )} @@ -150,6 +149,7 @@ void f(Ellipsis *e) { // CHECK-CCA: ObjCInterfaceDecl:{TypedText MyClass} // CHECK-CCA: ObjCInterfaceDecl:{TypedText MySubClass} // CHECK-CCA: TypedefDecl:{TypedText SEL} +// CHECK-CCA: {ResultType Class}{TypedText self} // CHECK-CCA: {TypedText super} // RUN: c-index-test -code-completion-at=%s:103:6 %s | FileCheck -check-prefix=CHECK-CCB %s // CHECK-CCB: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i}{Placeholder , ...} diff --git a/test/Index/complete-tabs.c b/test/Index/complete-tabs.c new file mode 100644 index 0000000..f3313bf --- /dev/null +++ b/test/Index/complete-tabs.c @@ -0,0 +1,9 @@ +// Test code-completion in the presence of tabs +struct Point { int x, y; }; + +void f(struct Point *p) { + p-> + +// RUN: c-index-test -code-completion-at=%s:5:5 %s | FileCheck -check-prefix=CHECK-CC1 %s +// CHECK-CC1: {TypedText x} +// CHECK-CC1: {TypedText y} diff --git a/test/Lexer/has_feature_cxx0x.cpp b/test/Lexer/has_feature_cxx0x.cpp new file mode 100644 index 0000000..7ea4c2c --- /dev/null +++ b/test/Lexer/has_feature_cxx0x.cpp @@ -0,0 +1,101 @@ +// RUN: %clang -E -std=c++0x %s -o - | FileCheck --check-prefix=CHECK-0X %s +// RUN: %clang -E %s -o - | FileCheck --check-prefix=CHECK-NO-0X %s + +#if __has_feature(cxx_lambdas) +int lambdas(); +#else +int no_lambdas(); +#endif + +// CHECK-0X: no_lambdas +// CHECK-NO-0X: no_lambdas + + +#if __has_feature(cxx_nullptr) +int has_nullptr(); +#else +int no_nullptr(); +#endif + +// CHECK-0X: no_nullptr +// CHECK-NO-0X: no_nullptr + + +#if __has_feature(cxx_concepts) +int concepts(); +#else +int no_concepts(); +#endif + +// CHECK-0X: no_concepts +// CHECK-NO-0X: no_concepts + + +#if __has_feature(cxx_decltype) +int has_decltype(); +#else +int no_decltype(); +#endif + +// CHECK-0X: has_decltype +// CHECK-NO-0X: no_decltype + + +#if __has_feature(cxx_auto_type) +int auto_type(); +#else +int no_auto_type(); +#endif + +// CHECK-0X: auto_type +// CHECK-NO-0X: no_auto_type + + +#if __has_feature(cxx_attributes) +int attributes(); +#else +int no_attributes(); +#endif + +// CHECK-0X: attributes +// CHECK-NO-0X: no_attributes + + +#if __has_feature(cxx_static_assert) +int has_static_assert(); +#else +int no_static_assert(); +#endif + +// CHECK-0X: has_static_assert +// CHECK-NO-0X: no_static_assert + + +#if __has_feature(cxx_deleted_functions) +int deleted_functions(); +#else +int no_deleted_functions(); +#endif + +// CHECK-0X: deleted_functions +// CHECK-NO-0X: no_deleted_functions + + +#if __has_feature(cxx_rvalue_references) +int rvalue_references(); +#else +int no_rvalue_references(); +#endif + +// CHECK-0X: no_rvalue_references +// CHECK-NO-0X: no_rvalue_references + + +#if __has_feature(cxx_variadic_templates) +int variadic_templates(); +#else +int no_variadic_templates(); +#endif + +// CHECK-0X: no_variadic_templates +// CHECK-NO-0X: no_variadic_templates diff --git a/test/Lexer/hexfloat.cpp b/test/Lexer/hexfloat.cpp new file mode 100644 index 0000000..5a62556 --- /dev/null +++ b/test/Lexer/hexfloat.cpp @@ -0,0 +1,8 @@ +//RUN: %clang_cc1 -fsyntax-only -verify +//RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ +float f = 0x1p+1; // expected-warning {{incompatible with C++0x}} +#else +float f = 0x1p+1; // expected-warning {{invalid suffix}} +#endif diff --git a/test/Lexer/numeric-literal-trash.c b/test/Lexer/numeric-literal-trash.c index 1d7c87b..5407ba9 100644 --- a/test/Lexer/numeric-literal-trash.c +++ b/test/Lexer/numeric-literal-trash.c @@ -4,7 +4,7 @@ - +int ec(int, int); void x() { diff --git a/test/Misc/tabstop.c b/test/Misc/tabstop.c new file mode 100644 index 0000000..3fabda7 --- /dev/null +++ b/test/Misc/tabstop.c @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -ftabstop 3 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=3 -strict-whitespace %s +// RUN: %clang_cc1 -ftabstop 4 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=4 -strict-whitespace %s +// RUN: %clang_cc1 -ftabstop 5 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=5 -strict-whitespace %s + +// tab + void* a = 1; + +// tab tab + void* b = 1; + +// 3x space tab + void* c = 1; + +// tab at column 10 +void* d = 1; + +//CHECK-3: {{^ void\* a = 1;}} +//CHECK-3: {{^ void\* b = 1;}} +//CHECK-3: {{^ void\* c = 1;}} +//CHECK-3: {{^void\* d = 1;}} + +//CHECK-4: {{^ void\* a = 1;}} +//CHECK-4: {{^ void\* b = 1;}} +//CHECK-4: {{^ void\* c = 1;}} +//CHECK-4: {{^void\* d = 1;}} + +//CHECK-5: {{^ void\* a = 1;}} +//CHECK-5: {{^ void\* b = 1;}} +//CHECK-5: {{^ void\* c = 1;}} +//CHECK-5: {{^void\* d = 1;}} diff --git a/test/Parser/cxx0x-literal-operators.cpp b/test/Parser/cxx0x-literal-operators.cpp index 830754e..30b2903 100644 --- a/test/Parser/cxx0x-literal-operators.cpp +++ b/test/Parser/cxx0x-literal-operators.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s -void operator "" (); // expected-error {{expected identifier}} -void operator "k" foo(); // expected-error {{string literal after 'operator' must be '""'}} -void operator "" tester (int); +void operator "" (const char *); // expected-error {{expected identifier}} +void operator "k" foo(const char *); // expected-error {{string literal after 'operator' must be '""'}} +void operator "" tester (const char *); diff --git a/test/Preprocessor/foo.framework/Headers/bar.h b/test/Preprocessor/foo.framework/Headers/bar.h new file mode 100644 index 0000000..574e851 --- /dev/null +++ b/test/Preprocessor/foo.framework/Headers/bar.h @@ -0,0 +1,3 @@ + +int y; + diff --git a/test/Preprocessor/foo.framework/Headers/foo.h b/test/Preprocessor/foo.framework/Headers/foo.h new file mode 100644 index 0000000..b08d948 --- /dev/null +++ b/test/Preprocessor/foo.framework/Headers/foo.h @@ -0,0 +1,6 @@ +// This should warn: published framework headers should always +// #import headers within the framework with framework paths. +#include "bar.h" + +int x; + diff --git a/test/Preprocessor/framework-include.m b/test/Preprocessor/framework-include.m new file mode 100644 index 0000000..7e50f18 --- /dev/null +++ b/test/Preprocessor/framework-include.m @@ -0,0 +1,5 @@ +// RUN: %clang -E -F%S %s 2>&1 | grep "published framework headers should always #import headers within the framework with framework paths" + +// rdar://7520940 +#include <foo/foo.h> + diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c index 5796b11..a1485b6 100644 --- a/test/Preprocessor/init.c +++ b/test/Preprocessor/init.c @@ -420,7 +420,7 @@ // MSP430:#define __LDBL_MIN_10_EXP__ (-307) // MSP430:#define __LDBL_MIN_EXP__ (-1021) // MSP430:#define __LDBL_MIN__ 2.2250738585072014e-308 -// MSP430:#define __LONG_LONG_MAX__ 2147483647LL +// MSP430:#define __LONG_LONG_MAX__ 9223372036854775807LL // MSP430:#define __LONG_MAX__ 2147483647L // MSP430:#define __MSP430__ 1 // MSP430:#define __NO_INLINE__ 1 diff --git a/test/Preprocessor/stdint.c b/test/Preprocessor/stdint.c index 5f0842a..e701494 100644 --- a/test/Preprocessor/stdint.c +++ b/test/Preprocessor/stdint.c @@ -380,15 +380,15 @@ // MSP430:INT_FAST32_MAX_ 2147483647L // MSP430:UINT_FAST32_MAX_ 4294967295UL // -// MSP430:INT64_MAX_ INT64_MAX -// MSP430:INT64_MIN_ INT64_MIN -// MSP430:UINT64_MAX_ UINT64_MAX -// MSP430:INT_LEAST64_MIN_ INT_LEAST64_MIN -// MSP430:INT_LEAST64_MAX_ INT_LEAST64_MAX -// MSP430:UINT_LEAST64_MAX_ UINT_LEAST64_MAX -// MSP430:INT_FAST64_MIN_ INT_FAST64_MIN -// MSP430:INT_FAST64_MAX_ INT_FAST64_MAX -// MSP430:UINT_FAST64_MAX_ UINT_FAST64_MAX +// MSP430:INT64_MAX_ 9223372036854775807LL +// MSP430:INT64_MIN_ (-9223372036854775807LL -1) +// MSP430:UINT64_MAX_ 18446744073709551615ULL +// MSP430:INT_LEAST64_MIN_ (-9223372036854775807LL -1) +// MSP430:INT_LEAST64_MAX_ 9223372036854775807LL +// MSP430:UINT_LEAST64_MAX_ 18446744073709551615ULL +// MSP430:INT_FAST64_MIN_ (-9223372036854775807LL -1) +// MSP430:INT_FAST64_MAX_ 9223372036854775807LL +// MSP430:UINT_FAST64_MAX_ 18446744073709551615ULL // // MSP430:INTPTR_MIN_ (-32767 -1) // MSP430:INTPTR_MAX_ 32767 @@ -415,8 +415,8 @@ // MSP430:UINT16_C_(0) 0U // MSP430:INT32_C_(0) 0L // MSP430:UINT32_C_(0) 0UL -// MSP430:INT64_C_(0) INT64_C(0) -// MSP430:UINT64_C_(0) UINT64_C(0) +// MSP430:INT64_C_(0) 0LL +// MSP430:UINT64_C_(0) 0ULL // // MSP430:INTMAX_C_(0) 0L // MSP430:UINTMAX_C_(0) 0UL diff --git a/test/Rewriter/rewrite-anonymous-union.m b/test/Rewriter/rewrite-anonymous-union.m new file mode 100644 index 0000000..579a068 --- /dev/null +++ b/test/Rewriter/rewrite-anonymous-union.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -rewrite-objc -o - %s +// rdar://6948022 + +typedef unsigned int uint32_t; + +typedef struct { + union { + uint32_t daysOfWeek; + uint32_t dayOfMonth; + }; + uint32_t nthOccurrence; +} OSPatternSpecificData; + +@interface NSNumber ++ (NSNumber *)numberWithLong:(long)value; +@end + +@interface OSRecurrence { + OSPatternSpecificData _pts; +} +- (void)_setTypeSpecificInfoOnRecord; +@end + +@implementation OSRecurrence +- (void)_setTypeSpecificInfoOnRecord +{ + [NSNumber numberWithLong:(_pts.dayOfMonth >= 31 ? -1 : _pts.dayOfMonth)]; +} +@end + diff --git a/test/Rewriter/rewrite-byref-vars.mm b/test/Rewriter/rewrite-byref-vars.mm new file mode 100644 index 0000000..581437b --- /dev/null +++ b/test/Rewriter/rewrite-byref-vars.mm @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o - %s +// radar 7540194 + +extern "C" __declspec(dllexport) void BreakTheRewriter(int i) { + __block int aBlockVariable = 0; + void (^aBlock)(void) = ^ { + aBlockVariable = 42; + }; + aBlockVariable++; + if (i) { + __block int bbBlockVariable = 0; + void (^aBlock)(void) = ^ { + bbBlockVariable = 42; + }; + } +} + +__declspec(dllexport) extern "C" __declspec(dllexport) void XXXXBreakTheRewriter(void) { + + __block int aBlockVariable = 0; + void (^aBlock)(void) = ^ { + aBlockVariable = 42; + }; + aBlockVariable++; + void (^bBlocks)(void) = ^ { + aBlockVariable = 43; + }; + void (^c)(void) = ^ { + aBlockVariable = 44; + }; + +} + +// $CLANG -cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks bug.mm +// g++ -c -D"__declspec(X)=" bug.cpp diff --git a/test/Rewriter/rewrite-eh.m b/test/Rewriter/rewrite-eh.m new file mode 100644 index 0000000..5bc80b5 --- /dev/null +++ b/test/Rewriter/rewrite-eh.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -rewrite-objc -o - %s +// rdar://7522880 + +@interface NSException +@end + +@interface Foo +@end + +@implementation Foo +- (void)bar { + @try { + } @catch (NSException *e) { + } + @catch (Foo *f) { + } + @catch (...) { + } +} +@end diff --git a/test/Rewriter/rewrite-foreach-7.m b/test/Rewriter/rewrite-foreach-7.m new file mode 100644 index 0000000..9fa6a1a --- /dev/null +++ b/test/Rewriter/rewrite-foreach-7.m @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -rewrite-objc %s -o - + +@class NSArray; +int main() { + NSArray *foo; + for (Class c in foo) { } +} diff --git a/test/Rewriter/rewrite-forward-class.m b/test/Rewriter/rewrite-forward-class.m new file mode 100644 index 0000000..5a50f53 --- /dev/null +++ b/test/Rewriter/rewrite-forward-class.m @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -rewrite-objc -o - %s +// rdar://6969189 + +@class XX; +@class YY, ZZ, QQ; +@class ISyncClient, SMSession, ISyncManager, ISyncSession, SMDataclassInfo, SMClientInfo, + DMCConfiguration, DMCStatusEntry; + diff --git a/test/Rewriter/rewrite-function-decl.mm b/test/Rewriter/rewrite-function-decl.mm new file mode 100644 index 0000000..023e55d --- /dev/null +++ b/test/Rewriter/rewrite-function-decl.mm @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o - %s + +extern "C" __declspec(dllexport) void BreakTheRewriter(void) { + __block int aBlockVariable = 0; + void (^aBlock)(void) = ^ { + aBlockVariable = 42; + }; + aBlockVariable++; + void (^bBlocks)(void) = ^ { + aBlockVariable = 43; + }; + void (^c)(void) = ^ { + aBlockVariable = 44; + }; + +} +__declspec(dllexport) extern "C" void AnotherBreakTheRewriter(int *p1, double d) { + + __block int bBlockVariable = 0; + void (^aBlock)(void) = ^ { + bBlockVariable = 42; + }; + bBlockVariable++; + void (^bBlocks)(void) = ^ { + bBlockVariable = 43; + }; + void (^c)(void) = ^ { + bBlockVariable = 44; + }; + +} diff --git a/test/Rewriter/rewrite-ivar-use.m b/test/Rewriter/rewrite-ivar-use.m new file mode 100644 index 0000000..82cff5b --- /dev/null +++ b/test/Rewriter/rewrite-ivar-use.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -rewrite-objc -fms-extensions %s -o - +// radar 7490331 + +@interface Foo { + int a; + id b; +} +- (void)bar; +- (void)baz:(id)q; +@end + +@implementation Foo +// radar 7522803 +static void foo(id bar) { + int i = ((Foo *)bar)->a; +} + +- (void)bar { + a = 42; + [self baz:b]; +} +- (void)baz:(id)q { +} +@end + diff --git a/test/Rewriter/rewrite-trivial-constructor.mm b/test/Rewriter/rewrite-trivial-constructor.mm new file mode 100644 index 0000000..81c7d9b --- /dev/null +++ b/test/Rewriter/rewrite-trivial-constructor.mm @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o - %s +// radar 7537770 + +typedef struct { + int a; + int b; +} s; + +extern void CFBasicHashApply(int (^block)(s)) { + int used, cnt; + for (int idx = 0; 0 < used && idx < cnt; idx++) { + s bkt; + if (0 < bkt.a) { + if (!block(bkt)) { + return; + } + used--; + } + } +} + diff --git a/test/Rewriter/rewrite-weak-attr.m b/test/Rewriter/rewrite-weak-attr.m new file mode 100644 index 0000000..2e559ee --- /dev/null +++ b/test/Rewriter/rewrite-weak-attr.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -fblocks -Dnil=0 -rewrite-objc -o - %s +int main() { + __weak __block id foo = nil; + __block id foo2 = nil; + id foo3 = nil; + + void (^myblock)() = ^{ + foo = nil; + foo2 = nil; + [foo3 bar]; + id foo4 = foo3; + }; +} diff --git a/test/Rewriter/weak_byref_objects.m b/test/Rewriter/weak_byref_objects.m new file mode 100644 index 0000000..a0ebe88 --- /dev/null +++ b/test/Rewriter/weak_byref_objects.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fblocks -triple i386-apple-darwin9 -fobjc-gc -rewrite-objc %s -o - + +#define nil 0 +int main() { + __weak __block id foo = nil; + __block id foo2 = nil; + id foo3 = nil; + + void (^myblock)() = ^{ + foo = nil; + foo2 = nil; + [foo3 bar]; + id foo4 = foo3; + }; +} diff --git a/test/Sema/anonymous-struct-union.c b/test/Sema/anonymous-struct-union.c index 47fb2b6..78995a9 100644 --- a/test/Sema/anonymous-struct-union.c +++ b/test/Sema/anonymous-struct-union.c @@ -96,3 +96,9 @@ struct s2 { int a; } }; // expected-error{{expected member name or ';' after declaration specifiers}} + +// Make sure we don't a.k.a. anonymous structs. +typedef struct { + int x; +} a_struct; +int tmp = (a_struct) { .x = 0 }; // expected-error {{incompatible type initializing 'a_struct', expected 'int'}} diff --git a/test/Sema/attr-noreturn.c b/test/Sema/attr-noreturn.c index 0966989..3f064a0 100644 --- a/test/Sema/attr-noreturn.c +++ b/test/Sema/attr-noreturn.c @@ -2,6 +2,8 @@ static void (*fp0)(void) __attribute__((noreturn)); +void fatal(); + static void __attribute__((noreturn)) f0(void) { fatal(); } // expected-warning {{function declared 'noreturn' should not return}} diff --git a/test/Sema/attr-section.c b/test/Sema/attr-section.c index 20ae2e3..614f294 100644 --- a/test/Sema/attr-section.c +++ b/test/Sema/attr-section.c @@ -8,3 +8,8 @@ int x __attribute__((section( int y __attribute__((section( "sadf"))); // expected-error {{mach-o section specifier requires a segment and section separated by a comma}} +// PR6007 +void test() { + __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute is not valid on local variables}} + __attribute__((section("NEAR,x"))) static int n2; // ok. +}
\ No newline at end of file diff --git a/test/Sema/block-labels.c b/test/Sema/block-labels.c index af364b4..353a570 100644 --- a/test/Sema/block-labels.c +++ b/test/Sema/block-labels.c @@ -1,5 +1,7 @@ // RUN: %clang_cc1 %s -verify -fblocks -fsyntax-only +void xx(); + int a() { A:if (1) xx(); return ^{A:return 1;}(); diff --git a/test/Sema/block-misc.c b/test/Sema/block-misc.c index 9f1bc40..52cebfe 100644 --- a/test/Sema/block-misc.c +++ b/test/Sema/block-misc.c @@ -64,6 +64,7 @@ int test4(int argc) { // rdar://6251437 } +void bar(void*); // rdar://6257721 - reference to static/global is byref by default. static int test5g; void test5() { @@ -157,6 +158,8 @@ void test16(__block int i) { // expected-error {{__block attribute not allowed, __block int (*ap)[size]; // expected-error {{__block attribute not allowed on declaration with a variably modified type}} } +void f(); + void test17() { void (^bp)(int); void (*rp)(int); @@ -197,4 +200,23 @@ L0: return x; } +// radr://7438948 +void test20() { + int n = 7; + int vla[n]; // expected-note {{declared at}} + int (*vm)[n] = 0; // expected-note {{declared at}} + vla[1] = 4341; + ^{ + (void)vla[1]; // expected-error {{cannot refer to declaration with a variably modified type inside block}} + (void)(vm+1); // expected-error {{cannot refer to declaration with a variably modified type inside block}} + }(); +} +// radr://7438948 +void test21() { + int a[7]; // expected-note {{declared at}} + a[1] = 1; + ^{ + (void)a[1]; // expected-error {{cannot refer to declaration with an array type inside block}} + }(); +} diff --git a/test/Sema/block-return.c b/test/Sema/block-return.c index 4240b09..6416545 100644 --- a/test/Sema/block-return.c +++ b/test/Sema/block-return.c @@ -76,6 +76,7 @@ static int funk(char *s) { else return 0; } +void next(); void foo4() { int (^xx)(const char *s) = ^(char *s) { return 1; }; // expected-error {{incompatible block pointer types initializing 'int (^)(char *)', expected 'int (^)(char const *)'}} int (*yy)(const char *s) = funk; // expected-warning {{incompatible pointer types initializing 'int (char *)', expected 'int (*)(char const *)'}} diff --git a/test/Sema/compare.c b/test/Sema/compare.c index 75a3cf1..579c3e5 100644 --- a/test/Sema/compare.c +++ b/test/Sema/compare.c @@ -194,6 +194,9 @@ int ints(long a, unsigned long b) { ((short) a < (unsigned short) 0x80000) + // expected-warning {{comparison of integers of different signs}} ((signed char) a < (unsigned char) 0x80000) + // expected-warning {{comparison of integers of different signs}} + // We should be able to avoid warning about this. + (b != (a < 4 ? 1 : 2)) + + 10 ; } @@ -230,3 +233,44 @@ int test1(int i) { enum en { zero }; return i > zero; } + +// PR5937 +int test2(int i32) { + struct foo { + unsigned int u8 : 8; + unsigned long long u31 : 31; + unsigned long long u32 : 32; + unsigned long long u63 : 63; + unsigned long long u64 : 64; + } *x; + + if (x->u8 == i32) { // comparison in int32, exact + return 0; + } else if (x->u31 == i32) { // comparison in int32, exact + return 1; + } else if (x->u32 == i32) { // expected-warning {{comparison of integers of different signs}} + return 2; + } else if (x->u63 == i32) { // comparison in uint64, exact because == + return 3; + } else if (x->u64 == i32) { // expected-warning {{comparison of integers of different signs}} + return 4; + } else { + return 5; + } +} + +// PR5887 +void test3() { + unsigned short x, y; + unsigned int z; + if ((x > y ? x : y) > z) + (void) 0; +} + +// PR5961 +extern char *ptr4; +void test4() { + long value; + if (value < (unsigned long) &ptr4) // expected-warning {{comparison of integers of different signs}} + return; +} diff --git a/test/Sema/complex-int.c b/test/Sema/complex-int.c index 2bd0374..cb76a34 100644 --- a/test/Sema/complex-int.c +++ b/test/Sema/complex-int.c @@ -49,3 +49,7 @@ void test3(_Complex int *x) { void test4(_Complex float *x) { *x = ~*x; } + +void test5(_Complex int *x) { + (*x)++; +} diff --git a/test/Sema/conditional.c b/test/Sema/conditional.c index e67580a..c3dbe13 100644 --- a/test/Sema/conditional.c +++ b/test/Sema/conditional.c @@ -3,6 +3,7 @@ const char* test1 = 1 ? "i" : 1 == 1 ? "v" : "r"; void _efree(void *ptr); +void free(void *ptr); int _php_stream_free1() { return (1 ? free(0) : _efree(0)); // expected-error {{incompatible type returning 'void', expected 'int'}} diff --git a/test/Sema/conversion.c b/test/Sema/conversion.c index 264e043..298bf75 100644 --- a/test/Sema/conversion.c +++ b/test/Sema/conversion.c @@ -235,3 +235,39 @@ extern void *test16_external; void test16(void) { int a = (unsigned long) &test16_external; // expected-warning {{implicit cast loses integer precision}} } + +// PR 5938 +void test17() { + union { + unsigned long long a : 8; + unsigned long long b : 32; + unsigned long long c; + } U; + + unsigned int x; + x = U.a; + x = U.b; + x = U.c; // expected-warning {{implicit cast loses integer precision}} +} + +// PR 5939 +void test18() { + union { + unsigned long long a : 1; + unsigned long long b; + } U; + + int x; + x = (U.a ? 0 : 1); + x = (U.b ? 0 : 1); +} + +// None of these should warn. +unsigned char test19(unsigned long u64) { + unsigned char x1 = u64 & 0xff; + unsigned char x2 = u64 >> 56; + + unsigned char mask = 0xee; + unsigned char x3 = u64 & mask; + return x1 + x2 + x3; +} diff --git a/test/Sema/declspec.c b/test/Sema/declspec.c index 2cf49aa..5b11960 100644 --- a/test/Sema/declspec.c +++ b/test/Sema/declspec.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only typedef char T[4]; -T foo(int n, int m) { } // expected-error {{cannot return array or function}} +T foo(int n, int m) { } // expected-error {{cannot return array type}} void foof(const char *, ...) __attribute__((__format__(__printf__, 1, 2))), barf (void); diff --git a/test/Sema/enum.c b/test/Sema/enum.c index 262cab5..916de41 100644 --- a/test/Sema/enum.c +++ b/test/Sema/enum.c @@ -84,3 +84,11 @@ enum e1 { YES, NO }; static enum e1 badfunc(struct s1 *q) { return q->bar(); } + + +// Make sure we don't a.k.a. anonymous enums. +typedef enum { + an_enumerator = 20 +} an_enum; +// FIXME: why is this only a warning? +char * s = (an_enum) an_enumerator; // expected-warning {{incompatible integer to pointer conversion initializing 'an_enum', expected 'char *'}} diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c index e6cfa5f..9acc63f 100644 --- a/test/Sema/exprs.c +++ b/test/Sema/exprs.c @@ -87,6 +87,10 @@ int test12(const char *X) { return X == "foo"; // expected-warning {{comparison against a string literal is unspecified}} } +int test12b(const char *X) { + return sizeof(X == "foo"); // no-warning +} + // rdar://6719156 void test13( void (^P)()) { // expected-error {{blocks support disabled - compile with -fblocks}} @@ -114,3 +118,13 @@ test15_t test15(void) { // rdar://7446395 void test16(float x) { x == ((void*) 0); } // expected-error {{invalid operands to binary expression}} +// PR6004 +void test17(int x) { + x = x / 0; // expected-warning {{division by zero is undefined}} + x = x % 0; // expected-warning {{remainder by zero is undefined}} + x /= 0; // expected-warning {{division by zero is undefined}} + x %= 0; // expected-warning {{remainder by zero is undefined}} + + x = sizeof(x/0); // no warning. +} + diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c index 67081b5..20e4dcd 100644 --- a/test/Sema/format-strings.c +++ b/test/Sema/format-strings.c @@ -8,6 +8,7 @@ int printf(const char *restrict, ...); int snprintf(char *restrict, size_t, const char *restrict, ...); int sprintf(char *restrict, const char *restrict, ...); int vasprintf(char **, const char *, va_list); +int asprintf(char **, const char *, ...); int vfprintf(FILE *, const char *restrict, va_list); int vprintf(const char *restrict, va_list); int vsnprintf(char *, size_t, const char *, va_list); diff --git a/test/Sema/i-c-e.c b/test/Sema/i-c-e.c index c561fe0..97d9f43 100644 --- a/test/Sema/i-c-e.c +++ b/test/Sema/i-c-e.c @@ -57,8 +57,9 @@ int comma3[(1,2)]; // expected-warning {{size of static array must be an integer // Pointer + __builtin_constant_p char pbcp[__builtin_constant_p(4) ? (intptr_t)&expr : 0]; // expected-error {{variable length array declaration not allowed at file scope}} -int illegaldiv1[1 || 1/0]; -int illegaldiv2[1/0]; // expected-error {{variable length array declaration not allowed at file scope}} +int illegaldiv1[1 || 1/0]; // expected-warning {{division by zero is undefined}} +int illegaldiv2[1/0]; // expected-error {{variable length array declaration not allowed at file scope}} \ + // expected-warning {{division by zero is undefined}} int illegaldiv3[INT_MIN / -1]; // expected-error {{variable length array declaration not allowed at file scope}} int chooseexpr[__builtin_choose_expr(1, 1, expr)]; diff --git a/test/Sema/implicit-builtin-decl.c b/test/Sema/implicit-builtin-decl.c index 09ecd23..3d92038 100644 --- a/test/Sema/implicit-builtin-decl.c +++ b/test/Sema/implicit-builtin-decl.c @@ -22,7 +22,8 @@ void h() { } void f2() { - fprintf(0, "foo"); // expected-error{{implicit declaration of 'fprintf' requires inclusion of the header <stdio.h>}} + fprintf(0, "foo"); // expected-error{{implicit declaration of 'fprintf' requires inclusion of the header <stdio.h>}} \ + expected-warning {{implicit declaration of function 'fprintf' is invalid in C99}} } // PR2892 diff --git a/test/Sema/implicit-decl.c b/test/Sema/implicit-decl.c index fc48895..830cde9 100644 --- a/test/Sema/implicit-decl.c +++ b/test/Sema/implicit-decl.c @@ -7,7 +7,8 @@ void func() { int32_t *vector[16]; const char compDesc[16 + 1]; int32_t compCount = 0; - if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-note {{previous implicit declaration is here}} + if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-note {{previous implicit declaration is here}} \ + expected-warning {{implicit declaration of function '_CFCalendarDecomposeAbsoluteTimeV' is invalid in C99}} } return ((void *)0); // expected-warning {{void function 'func' should not return a value}} } diff --git a/test/Sema/invalid-decl.c b/test/Sema/invalid-decl.c index 7f471a1..a5e7ad3 100644 --- a/test/Sema/invalid-decl.c +++ b/test/Sema/invalid-decl.c @@ -6,7 +6,7 @@ void test() { // PR2400 -typedef xtype (*x)(void* handle); // expected-error {{function cannot return array or function type}} expected-warning {{type specifier missing, defaults to 'int'}} expected-warning {{type specifier missing, defaults to 'int'}} +typedef xtype (*x)(void* handle); // expected-error {{function cannot return function type}} expected-warning {{type specifier missing, defaults to 'int'}} expected-warning {{type specifier missing, defaults to 'int'}} typedef void ytype(); diff --git a/test/Sema/ms-fuzzy-asm.c b/test/Sema/ms-fuzzy-asm.c index 9ace656..250e322 100644 --- a/test/Sema/ms-fuzzy-asm.c +++ b/test/Sema/ms-fuzzy-asm.c @@ -1,5 +1,4 @@ // RUN: %clang_cc1 %s -verify -fms-extensions -// XFAIL: * #define M __asm int 0x2c #define M2 int diff --git a/test/Sema/overloadable.c b/test/Sema/overloadable.c index 72d3673..ff631ed 100644 --- a/test/Sema/overloadable.c +++ b/test/Sema/overloadable.c @@ -37,9 +37,9 @@ void test_struct(struct X x, struct Y y) { double *f(int) __attribute__((overloadable)); // expected-error{{conflicting types for 'f'}} -double promote(float) __attribute__((__overloadable__)); -double promote(double) __attribute__((__overloadable__)); -long double promote(long double) __attribute__((__overloadable__)); +double promote(float) __attribute__((__overloadable__)); // expected-note {{candidate}} +double promote(double) __attribute__((__overloadable__)); // expected-note {{candidate}} +long double promote(long double) __attribute__((__overloadable__)); // expected-note {{candidate}} void promote() __attribute__((__overloadable__)); // expected-error{{'overloadable' function 'promote' must have a prototype}} void promote(...) __attribute__((__overloadable__, __unavailable__)); // \ diff --git a/test/Sema/parentheses.c b/test/Sema/parentheses.c index f7a7fbd..69c91cb 100644 --- a/test/Sema/parentheses.c +++ b/test/Sema/parentheses.c @@ -4,14 +4,18 @@ // Test the various warnings under -Wparentheses void if_assign(void) { int i; - if (i = 4) {} // expected-warning {{assignment as a condition}} + if (i = 4) {} // expected-warning {{assignment as a condition}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} if ((i = 4)) {} } void bitwise_rel(unsigned i) { - (void)(i & 0x2 == 0); // expected-warning {{& has lower precedence than ==}} - (void)(0 == i & 0x2); // expected-warning {{& has lower precedence than ==}} - (void)(i & 0xff < 30); // expected-warning {{& has lower precedence than <}} + (void)(i & 0x2 == 0); // expected-warning {{& has lower precedence than ==}} \ + // expected-note{{place parentheses around the & expression to evaluate it first}} + (void)(0 == i & 0x2); // expected-warning {{& has lower precedence than ==}} \ + // expected-note{{place parentheses around the & expression to evaluate it first}} + (void)(i & 0xff < 30); // expected-warning {{& has lower precedence than <}} \ + // expected-note{{place parentheses around the & expression to evaluate it first}} (void)((i & 0x2) == 0); (void)(i & (0x2 == 0)); // Eager logical op diff --git a/test/Sema/self-comparison.c b/test/Sema/self-comparison.c index b2b06c2..1baba27 100644 --- a/test/Sema/self-comparison.c +++ b/test/Sema/self-comparison.c @@ -31,3 +31,8 @@ int compare_enum() { enum { A }; return A == A; // no-warning } + +// Don't complain in unevaluated contexts. +int compare_sizeof(int x) { + return sizeof(x == x); // no-warning +} diff --git a/test/Sema/switch.c b/test/Sema/switch.c index f815ba4..08ab0e0 100644 --- a/test/Sema/switch.c +++ b/test/Sema/switch.c @@ -76,7 +76,7 @@ void test6() { } // PR5606 -int f0(int var) { +int f0(int var) { // expected-note{{'var' declared here}} switch (va) { // expected-error{{use of undeclared identifier 'va'}} case 1: break; diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c index f5c64e6..68503bd 100644 --- a/test/Sema/unused-expr.c +++ b/test/Sema/unused-expr.c @@ -1,8 +1,8 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fno-math-errno %s +// RUN: %clang_cc1 -fsyntax-only -verify %s int foo(int X, int Y); -double sqrt(double X); // implicitly const because of -fno-math-errno! +double sqrt(double X); // implicitly const because of no -fmath-errno! void bar(volatile int *VP, int *P, int A, _Complex double C, volatile _Complex double VC) { @@ -24,7 +24,7 @@ void bar(volatile int *VP, int *P, int A, __real__ C; // expected-warning {{expression result unused}} __real__ VC; - // We know this can't change errno because of -fno-math-errno. + // We know this can't change errno because of no -fmath-errno. sqrt(A); // expected-warning {{ignoring return value of function declared with const attribute}} } diff --git a/test/Sema/var-redecl.c b/test/Sema/var-redecl.c index e67499b..71d7ea1 100644 --- a/test/Sema/var-redecl.c +++ b/test/Sema/var-redecl.c @@ -50,7 +50,7 @@ void outer_shadowing_test() { } } -void g18(void) { +void g18(void) { // expected-note{{'g18' declared here}} extern int g19; } int *p=&g19; // expected-error{{use of undeclared identifier 'g19'}} \ diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c new file mode 100644 index 0000000..2c123d0 --- /dev/null +++ b/test/Sema/warn-unreachable.c @@ -0,0 +1,20 @@ +// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code + +void test1() { + goto c; + d: + goto e; // expected-warning {{will never be executed}} + c: ; + int i; + return; + goto b; // expected-warning {{will never be executed}} + goto a; // expected-warning {{will never be executed}} + b: + i = 1; + a: + i = 2; + goto f; + e: + goto d; + f: ; +} diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp index 255b352..ac48215 100644 --- a/test/SemaCXX/aggregate-initialization.cpp +++ b/test/SemaCXX/aggregate-initialization.cpp @@ -26,3 +26,7 @@ NonAggr1 na1 = { 17 }; // expected-error{{non-aggregate type 'struct NonAggr1' c NonAggr2 na2 = { 17 }; // expected-error{{non-aggregate type 'struct NonAggr2' cannot be initialized with an initializer list}} NonAggr3 na3 = { 17 }; // expected-error{{non-aggregate type 'class NonAggr3' cannot be initialized with an initializer list}} NonAggr4 na4 = { 17 }; // expected-error{{non-aggregate type 'struct NonAggr4' cannot be initialized with an initializer list}} + +// PR5817 +typedef int type[][2]; +const type foo = {0}; diff --git a/test/SemaCXX/ambig-user-defined-conversions.cpp b/test/SemaCXX/ambig-user-defined-conversions.cpp index 0820bc9..5e0a2e3 100644 --- a/test/SemaCXX/ambig-user-defined-conversions.cpp +++ b/test/SemaCXX/ambig-user-defined-conversions.cpp @@ -1,52 +1,58 @@ // RUN: %clang_cc1 -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}} +namespace test0 { + 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 test0::B' to 'int const' is ambiguous}} + } + + // This used to crash when comparing the two operands. + void func2(const char cc); // expected-note {{candidate function}} + void func2(const int ci); // expected-note {{candidate function}} + void Test2() { + func2(b1); // expected-error {{call to 'func2' 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. +namespace test1 { + 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/attr-unavailable.cpp b/test/SemaCXX/attr-unavailable.cpp index bebd4cb..8b381df 100644 --- a/test/SemaCXX/attr-unavailable.cpp +++ b/test/SemaCXX/attr-unavailable.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -int &foo(int); -double &foo(double); +int &foo(int); // expected-note {{candidate}} +double &foo(double); // expected-note {{candidate}} void foo(...) __attribute__((__unavailable__)); // expected-note {{candidate function}} \ // expected-note{{function has been explicitly marked unavailable here}} diff --git a/test/SemaCXX/builtin-ptrtomember-overload-1.cpp b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp index 137503b..b1b0b98 100644 --- a/test/SemaCXX/builtin-ptrtomember-overload-1.cpp +++ b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp @@ -40,7 +40,7 @@ void foo1(C1 c1, int A::* pmf) { } 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 *'}} + int i = c1->*pmf; // expected-error {{use of overloaded operator '->*' is ambiguous}} \ + // expected-note {{because of ambiguity in conversion of 'struct C1' to 'struct E *'}} \ + // expected-note 4 {{built-in candidate operator}} } diff --git a/test/SemaCXX/composite-pointer-type.cpp b/test/SemaCXX/composite-pointer-type.cpp index 829e64f..fdf838f 100644 --- a/test/SemaCXX/composite-pointer-type.cpp +++ b/test/SemaCXX/composite-pointer-type.cpp @@ -43,3 +43,10 @@ int f2() { IntPtrPtr j = 0; return i != j; } + +// PR5763 +typedef double Matrix4[4][4]; + +bool f(Matrix4 m1, const Matrix4 m2) { + return m1 != m2; +} diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp index a0b57e1..fe802d0 100644 --- a/test/SemaCXX/condition.cpp +++ b/test/SemaCXX/condition.cpp @@ -16,8 +16,8 @@ void test() { for (;s;) ; // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} switch (s) {} // expected-error {{statement requires expression of integer type ('struct S' invalid)}} - while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate function}} - while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct <anonymous>' is not contextually convertible to 'bool'}} expected-note{{candidate function}} + while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}} + while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct <anonymous>' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}} switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}} if (int x=0) { // expected-note 2 {{previous definition is here}} diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp index 0617cd5..b71133b 100644 --- a/test/SemaCXX/conditional-expr.cpp +++ b/test/SemaCXX/conditional-expr.cpp @@ -7,8 +7,8 @@ struct ToBool { explicit operator bool(); }; struct B; -struct A { A(); A(const B&); }; -struct B { operator A() const; }; +struct A { A(); A(const B&); }; // expected-note 2 {{candidate constructor}} +struct B { operator A() const; }; // expected-note 2 {{candidate function}} struct I { operator int(); }; struct J { operator I(); }; struct K { operator double(); }; @@ -50,8 +50,8 @@ struct MixedFieldsDerived : MixedFields { enum Enum { EVal }; struct Ambig { - operator short(); - operator signed char(); + operator short(); // expected-note 2 {{candidate function}} + operator signed char(); // expected-note 2 {{candidate function}} }; void test() @@ -128,11 +128,10 @@ void test() // "the type [it] woud have if E2 were converted to an rvalue" vfn pfn = i1 ? F() : test; pfn = i1 ? test : F(); - // these are ambiguous - better messages would be nice - (void)(i1 ? A() : B()); // expected-error {{incompatible operand types}} - (void)(i1 ? B() : A()); // expected-error {{incompatible operand types}} - (void)(i1 ? 1 : Ambig()); // expected-error {{incompatible operand types}} - (void)(i1 ? Ambig() : 1); // expected-error {{incompatible operand types}} + (void)(i1 ? A() : B()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}} + (void)(i1 ? B() : A()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}} + (void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'struct Ambig' to 'int' is ambiguous}} + (void)(i1 ? Ambig() : 1); // expected-error {{conversion from 'struct Ambig' to 'int' is ambiguous}} // By the way, this isn't an lvalue: &(i1 ? i1 : i2); // expected-error {{address expression must be an lvalue or a function designator}} diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp index 67d4074..53f057e 100644 --- a/test/SemaCXX/constructor-initializer.cpp +++ b/test/SemaCXX/constructor-initializer.cpp @@ -97,13 +97,10 @@ struct Current : Derived { // 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}} \ +struct M { // expected-note 2 {{candidate constructor (the implicit copy constructor)}} \ // expected-note {{declared here}} \ // expected-note {{declared here}} - M(int i, int j); // expected-note {{candidate function}} \ - // // expected-note {{candidate function}} + M(int i, int j); // expected-note 2 {{candidate constructor}} }; struct N : M { diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp index db322f4..4fef172 100644 --- a/test/SemaCXX/conversion-function.cpp +++ b/test/SemaCXX/conversion-function.cpp @@ -56,9 +56,9 @@ public: // This used to crash Clang. struct Flip; -struct Flop { // expected-note{{candidate function}} +struct Flop { // expected-note{{candidate is the implicit copy constructor}} Flop(); - Flop(const Flip&); // expected-note{{candidate function}} + Flop(const Flip&); // expected-note{{candidate constructor}} }; struct Flip { operator Flop() const; // expected-note{{candidate function}} diff --git a/test/SemaCXX/converting-constructor.cpp b/test/SemaCXX/converting-constructor.cpp index e78798b..1688e51 100644 --- a/test/SemaCXX/converting-constructor.cpp +++ b/test/SemaCXX/converting-constructor.cpp @@ -27,7 +27,7 @@ public: FromShort(short s); }; -class FromShortExplicitly { // expected-note{{candidate function}} +class FromShortExplicitly { // expected-note{{candidate constructor (the implicit copy constructor)}} public: explicit FromShortExplicitly(short s); }; diff --git a/test/SemaCXX/copy-initialization.cpp b/test/SemaCXX/copy-initialization.cpp index ad14923..2cf878a 100644 --- a/test/SemaCXX/copy-initialization.cpp +++ b/test/SemaCXX/copy-initialization.cpp @@ -2,7 +2,7 @@ class X { public: explicit X(const X&); - X(int*); // expected-note 2{{candidate function}} + X(int*); // expected-note 2{{candidate constructor}} explicit X(float*); }; diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp index 87b51e3..07ddb0a 100644 --- a/test/SemaCXX/dcl_init_aggr.cpp +++ b/test/SemaCXX/dcl_init_aggr.cpp @@ -40,9 +40,9 @@ 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 3 {{candidate function}} \ +struct NoDefaultConstructor { // expected-note 3 {{candidate constructor (the implicit copy constructor)}} \ // expected-note{{declared here}} - NoDefaultConstructor(int); // expected-note 3 {{candidate function}} + NoDefaultConstructor(int); // expected-note 3 {{candidate constructor}} }; struct TooFewError { // expected-error{{implicit default constructor for}} int a; @@ -115,7 +115,7 @@ B2 b2_2 = { 4, d2, 0 }; B2 b2_3 = { c2, a2, a2 }; // C++ [dcl.init.aggr]p15: -union u { int a; char* b; }; // expected-note{{candidate function}} +union u { int a; char* b; }; // expected-note{{candidate constructor (the implicit copy constructor)}} u u1 = { 1 }; u u2 = u1; u u3 = 1; // expected-error{{no viable conversion}} diff --git a/test/SemaCXX/decl-init-ref.cpp b/test/SemaCXX/decl-init-ref.cpp index 294543f..656f343 100644 --- a/test/SemaCXX/decl-init-ref.cpp +++ b/test/SemaCXX/decl-init-ref.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s -struct A {}; // expected-note {{candidate function}} +struct A {}; // expected-note {{candidate is the implicit copy constructor}} struct BASE { operator A(); // expected-note {{candidate function}} diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp index 880255e..d2c44bd 100644 --- a/test/SemaCXX/default2.cpp +++ b/test/SemaCXX/default2.cpp @@ -82,7 +82,7 @@ int Y::mem4(int i = a) // expected-error{{invalid use of nonstatic data member ' // constructors. class Z { public: - Z(Z&, int i = 17); // expected-note 3 {{candidate function}} + Z(Z&, int i = 17); // expected-note 3 {{candidate constructor}} void f(Z& z) { Z z2; // expected-error{{no matching constructor for initialization}} @@ -103,7 +103,7 @@ struct ZZ { void f(ZZ z = g()); // expected-error{{no matching constructor for initialization}} - ZZ(ZZ&, int = 17); // expected-note{{candidate function}} + ZZ(ZZ&, int = 17); // expected-note{{candidate constructor}} }; // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#325 diff --git a/test/SemaCXX/direct-initializer.cpp b/test/SemaCXX/direct-initializer.cpp index 03a5da3..6601a3d 100644 --- a/test/SemaCXX/direct-initializer.cpp +++ b/test/SemaCXX/direct-initializer.cpp @@ -13,16 +13,16 @@ class Y { explicit Y(float); }; -class X { // expected-note{{candidate function}} +class X { // expected-note{{candidate constructor (the implicit copy constructor)}} public: - explicit X(int); // expected-note{{candidate function}} - X(float, float, float); // expected-note{{candidate function}} - X(float, Y); // expected-note{{candidate function}} + explicit X(int); // expected-note{{candidate constructor}} + X(float, float, float); // expected-note{{candidate constructor}} + X(float, Y); // expected-note{{candidate constructor}} }; -class Z { // expected-note{{candidate function}} +class Z { // expected-note{{candidate constructor (the implicit copy constructor)}} public: - Z(int); // expected-note{{candidate function}} + Z(int); // expected-note{{candidate constructor}} }; void g() { diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp index 63be770..0bef0cd 100644 --- a/test/SemaCXX/functional-cast.cpp +++ b/test/SemaCXX/functional-cast.cpp @@ -10,10 +10,8 @@ struct InitViaConstructor { InitViaConstructor(int i = 7); }; -// FIXME: error messages for implicitly-declared special member -// function candidates are very poor -struct NoValueInit { // expected-note 2 {{candidate function}} - NoValueInit(int i, int j); // expected-note 2 {{candidate function}} +struct NoValueInit { // expected-note 2 {{candidate constructor (the implicit copy constructor)}} + NoValueInit(int i, int j); // expected-note 2 {{candidate constructor}} }; void test_cxx_functional_value_init() { diff --git a/test/SemaCXX/implicit-virtual-member-functions.cpp b/test/SemaCXX/implicit-virtual-member-functions.cpp index a6b1f8c..4ae9eae 100644 --- a/test/SemaCXX/implicit-virtual-member-functions.cpp +++ b/test/SemaCXX/implicit-virtual-member-functions.cpp @@ -15,15 +15,15 @@ void B::f() { // expected-note {{implicit default destructor for 'struct B' firs struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}} C(); void operator delete(void *, int); // expected-note {{'operator delete' declared here}} -}; +}; // expected-note {{implicit default destructor for 'struct C' first required here}} -C::C() { } // expected-note {{implicit default destructor for 'struct C' first required here}} +C::C() { } struct D : A { // expected-error {{no suitable member 'operator delete' in 'D'}} void operator delete(void *, int); // expected-note {{'operator delete' declared here}} -}; +}; // expected-note {{implicit default destructor for 'struct D' first required here}} void f() { - new D; // expected-note {{implicit default destructor for 'struct D' first required here}} + new D; } diff --git a/test/SemaCXX/literal-operators.cpp b/test/SemaCXX/literal-operators.cpp new file mode 100644 index 0000000..ec585a6 --- /dev/null +++ b/test/SemaCXX/literal-operators.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +#include <stddef.h> + +struct tag { + void operator "" tag_bad (const char *); // expected-error {{literal operator 'operator "" tag_bad' must be in a namespace or global scope}} + friend void operator "" tag_good (const char *); +}; + +namespace ns { void operator "" ns_good (const char *); } + +// Check extern "C++" declarations +extern "C++" void operator "" extern_good (const char *); +extern "C++" { void operator "" extern_good (const char *); } + +void fn () { void operator "" fn_bad (const char *); } // expected-error {{literal operator 'operator "" fn_bad' must be in a namespace or global scope}} + +// One-param declarations (const char * was already checked) +void operator "" good (char); +void operator "" good (wchar_t); +void operator "" good (char16_t); +void operator "" good (char32_t); +void operator "" good (unsigned long long); +void operator "" good (long double); + +// Two-param declarations +void operator "" good (const char *, size_t); +void operator "" good (const wchar_t *, size_t); +void operator "" good (const char16_t *, size_t); +void operator "" good (const char32_t *, size_t); + +// Check typedef and array equivalences +void operator "" good (const char[]); +typedef const char c; +void operator "" good (c*); + +// Check extra cv-qualifiers +void operator "" cv_good (volatile const char *, const size_t); + +// Template delcaration (not implemented yet) +// template <char...> void operator "" good (); + +// FIXME: Test some invalid decls that might crop up. diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp index 65d05eb..3d9d5b5e 100644 --- a/test/SemaCXX/member-pointer.cpp +++ b/test/SemaCXX/member-pointer.cpp @@ -80,7 +80,7 @@ void g() { void (HasMembers::*pmf)() = &HasMembers::f; void (*pnf)() = &Fake::f; - &hm.f; // FIXME: needs diagnostic expected-warning{{result unused}} + &hm.f; // expected-error {{must explicitly qualify}} expected-warning{{result unused}} void (HasMembers::*pmgv)() = &HasMembers::g; void (HasMembers::*pmgi)(int) = &HasMembers::g; @@ -136,3 +136,15 @@ void i() { OverloadsPtrMem m; int foo = m->*"Awesome!"; } + +namespace pr5985 { + struct c { + void h(); + void f() { + void (c::*p)(); + p = &h; // expected-error {{must explicitly qualify}} + p = &this->h; // expected-error {{must explicitly qualify}} + p = &(*this).h; // expected-error {{must explicitly qualify}} + } + }; +} diff --git a/test/SemaCXX/namespace.cpp b/test/SemaCXX/namespace.cpp index ab690b7..2a9d31f 100644 --- a/test/SemaCXX/namespace.cpp +++ b/test/SemaCXX/namespace.cpp @@ -9,7 +9,7 @@ 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}} \ - // FIXME: ugly expected-note{{candidate function}} + // expected-note{{candidate function (the implicit copy assignment operator)}} void C(); // expected-note {{previous definition is here}} namespace C {} // expected-error {{redefinition of 'C' as different kind of symbol}} diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp index 4e65b41..8618f03 100644 --- a/test/SemaCXX/nested-name-spec.cpp +++ b/test/SemaCXX/nested-name-spec.cpp @@ -178,7 +178,7 @@ bool (foo_S::value); namespace somens { - struct a { }; // expected-note{{candidate function}} + struct a { }; // expected-note{{candidate constructor (the implicit copy constructor)}} } template <typename T> diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp index 299c0a7..d20bf23 100644 --- a/test/SemaCXX/overload-call.cpp +++ b/test/SemaCXX/overload-call.cpp @@ -301,3 +301,35 @@ namespace PR5756 { (void)ir; } } + +// Tests the exact text used to note the candidates +namespace test1 { + template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'char const [6]' to 'unsigned int' for 2nd argument}} + void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'char const [6]' to 'char' for 2nd argument}} + void foo(int n); // expected-note {{candidate function not viable: requires 1 argument, but 2 were provided}} + void foo(unsigned n = 10); // expected-note {{candidate function not viable: requires at most 1 argument, but 2 were provided}} + void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}} + void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} + void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} + + void test() { + foo(4, "hello"); //expected-error {{no matching function for call to 'foo'}} + } +} + +// PR 6014 +namespace test2 { + struct QFixed { + QFixed(int i); + QFixed(long i); + }; + + bool operator==(const QFixed &f, int i); + + class qrgb666 { + inline operator unsigned int () const; + + inline bool operator==(const qrgb666 &v) const; + inline bool operator!=(const qrgb666 &v) const { return !(*this == v); } + }; +} diff --git a/test/SemaCXX/overload-member-call.cpp b/test/SemaCXX/overload-member-call.cpp index 4bb3ff3..22416f3 100644 --- a/test/SemaCXX/overload-member-call.cpp +++ b/test/SemaCXX/overload-member-call.cpp @@ -66,3 +66,33 @@ void test_X2(X2 *x2p, const X2 *cx2p) { int &ir = x2p->member(); float &fr = cx2p->member(); } + +// Tests the exact text used to note the candidates +namespace test1 { + class A { + template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'char const [6]' to 'unsigned int' for 2nd argument}} + void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'char const [6]' to 'char' for 2nd argument}} + void foo(int n); // expected-note {{candidate function not viable: requires 1 argument, but 2 were provided}} + void foo(unsigned n = 10); // expected-note {{candidate function not viable: requires at most 1 argument, but 2 were provided}} + void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}} + void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} + void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} + + void bar(double d); //expected-note {{candidate function not viable: 'this' argument has type 'class test1::A const', but method is not marked const}} + void bar(int i); //expected-note {{candidate function not viable: 'this' argument has type 'class test1::A const', but method is not marked const}} + + void baz(A &d); // expected-note {{candidate function not viable: 1st argument ('class test1::A const') would lose const qualifier}} + void baz(int i); // expected-note {{candidate function not viable: no known conversion from 'class test1::A const' to 'int' for 1st argument}} + }; + + void test() { + A a; + a.foo(4, "hello"); //expected-error {{no matching member function for call to 'foo'}} + + const A b; + b.bar(0); //expected-error {{no matching member function for call to 'bar'}} + + a.baz(b); //expected-error {{no matching member function for call to 'baz'}} + } +} + diff --git a/test/SemaCXX/overloaded-builtin-operators.cpp b/test/SemaCXX/overloaded-builtin-operators.cpp index 12903cc..61c2e21 100644 --- a/test/SemaCXX/overloaded-builtin-operators.cpp +++ b/test/SemaCXX/overloaded-builtin-operators.cpp @@ -59,7 +59,7 @@ void f(Short s, Long l, Enum1 e1, Enum2 e2, Xpmf pmf) { // FIXME: should pass (void)static_cast<no&>(islong(e1 % e2)); } -struct ShortRef { // expected-note{{candidate function}} +struct ShortRef { // expected-note{{candidate function (the implicit copy assignment operator)}} operator short&(); }; @@ -67,7 +67,7 @@ struct LongRef { operator volatile long&(); }; -struct XpmfRef { // expected-note{{candidate function}} +struct XpmfRef { // expected-note{{candidate function (the implicit copy assignment operator)}} operator pmf&(); }; diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp index a20c69b..861d679 100644 --- a/test/SemaCXX/overloaded-operator.cpp +++ b/test/SemaCXX/overloaded-operator.cpp @@ -190,16 +190,23 @@ typedef INTREF Func1(FLOAT, double); typedef float& Func2(int, double); struct ConvertToFunc { - operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} - operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}} + operator Func1*(); // expected-note 2{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} + operator Func2&(); // expected-note 2{{conversion candidate of type 'float &(&)(int, double)'}} void operator()(); }; -void test_funcptr_call(ConvertToFunc ctf) { +struct ConvertToFuncDerived : ConvertToFunc { }; + +void test_funcptr_call(ConvertToFunc ctf, ConvertToFuncDerived ctfd) { int &i1 = ctf(1.0f, 2.0); - float &f2 = ctf((short int)1, 1.0f); + float &f1 = ctf((short int)1, 1.0f); ctf((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFunc' is ambiguous; candidates are:}} ctf(); + + int &i2 = ctfd(1.0f, 2.0); + float &f2 = ctfd((short int)1, 1.0f); + ctfd((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFuncDerived' is ambiguous; candidates are:}} + ctfd(); } struct HasMember { @@ -324,3 +331,27 @@ namespace pr5512 { a += x; } } + +// PR5900 +namespace pr5900 { + struct NotAnArray {}; + void test0() { + NotAnArray x; + x[0] = 0; // expected-error {{does not provide a subscript operator}} + } + + struct NonConstArray { + int operator[](unsigned); // expected-note {{candidate}} + }; + int test1() { + const NonConstArray x; + return x[0]; // expected-error {{no viable overloaded operator[] for type}} + } + + // Not really part of this PR, but implemented at the same time. + struct NotAFunction {}; + void test2() { + NotAFunction x; + x(); // expected-error {{does not provide a call operator}} + } +} diff --git a/test/SemaCXX/rval-references.cpp b/test/SemaCXX/rval-references.cpp index 7ff3d58..2a7fb25 100644 --- a/test/SemaCXX/rval-references.cpp +++ b/test/SemaCXX/rval-references.cpp @@ -65,10 +65,10 @@ int&& should_not_warn(int&& i) { // But GCC 4.4 does // Test the return dance. This also tests IsReturnCopyElidable. struct MoveOnly { MoveOnly(); - MoveOnly(const MoveOnly&) = delete; // expected-note {{candidate function}} \ + MoveOnly(const MoveOnly&) = delete; // expected-note {{candidate constructor}} \ // expected-note 3{{explicitly marked deleted here}} - MoveOnly(MoveOnly&&); // expected-note {{candidate function}} - MoveOnly(int&&); // expected-note {{candidate function}} + MoveOnly(MoveOnly&&); // expected-note {{candidate constructor}} + MoveOnly(int&&); // expected-note {{candidate constructor}} }; MoveOnly gmo; diff --git a/test/SemaCXX/unreachable-code.cpp b/test/SemaCXX/unreachable-code.cpp new file mode 100644 index 0000000..528bba7 --- /dev/null +++ b/test/SemaCXX/unreachable-code.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunreachable-code -fblocks -verify %s + +int j; +void bar() { } +int test1() { + for (int i = 0; + i != 10; + ++i) { // expected-warning {{will never be executed}} + if (j == 23) // missing {}'s + bar(); + return 1; + } + return 0; + return 1; // expected-warning {{will never be executed}} +} + +void test2(int i) { + switch (i) { + case 0: + break; + bar(); // expected-warning {{will never be executed}} + case 2: + switch (i) { + default: + a: goto a; + } + bar(); // expected-warning {{will never be executed}} + } + b: goto b; + bar(); // expected-warning {{will never be executed}} +} + +void test3() { + ^{ return; + bar(); // expected-warning {{will never be executed}} + }(); + while (++j) { + continue; + bar(); // expected-warning {{will never be executed}} + } +} diff --git a/test/SemaCXX/virtual-member-functions-key-function.cpp b/test/SemaCXX/virtual-member-functions-key-function.cpp index 3d04859..2e21fb7 100644 --- a/test/SemaCXX/virtual-member-functions-key-function.cpp +++ b/test/SemaCXX/virtual-member-functions-key-function.cpp @@ -4,19 +4,26 @@ struct A { }; struct B : A { // expected-error {{no suitable member 'operator delete' in 'B'}} - B() { } // expected-note {{implicit default destructor for 'struct B' first required here}} + B() { } void operator delete(void *, int); // expected-note {{'operator delete' declared here}} -}; +}; // expected-note {{implicit default destructor for 'struct B' first required here}} struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}} void operator delete(void *, int); // expected-note {{'operator delete' declared here}} -}; +}; // expected-note {{implicit default destructor for 'struct C' first required here}} void f() { - // new B should mark the constructor as used, which then marks - // all the virtual members as used, because B has no key function. (void)new B; - - // Same here, except that C has an implicit constructor. - (void)new C; // expected-note {{implicit default destructor for 'struct C' first required here}} + (void)new C; } + +// Make sure that the key-function computation is consistent when the +// first virtual member function of a nested class has an inline body. +struct Outer { + struct Inner { + virtual void f() { } + void g(); + }; +}; + +void Outer::Inner::g() { } diff --git a/test/SemaCXX/warn-assignment-condition.cpp b/test/SemaCXX/warn-assignment-condition.cpp index 1df906d..ce16a68 100644 --- a/test/SemaCXX/warn-assignment-condition.cpp +++ b/test/SemaCXX/warn-assignment-condition.cpp @@ -11,26 +11,34 @@ void test() { A a, b; // With scalars. - if (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + if (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} if ((x = 7)) {} do { - } while (x = 7); // expected-warning {{using the result of an assignment as a condition without parentheses}} + } while (x = 7); // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} do { } while ((x = 7)); - while (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + while (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} while ((x = 7)) {} - for (; x = 7; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + for (; x = 7; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} for (; (x = 7); ) {} - if (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + if (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} if ((p = p)) {} do { - } while (p = p); // expected-warning {{using the result of an assignment as a condition without parentheses}} + } while (p = p); // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} do { } while ((p = p)); - while (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + while (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} while ((p = p)) {} - for (; p = p; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + for (; p = p; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} for (; (p = p); ) {} // Initializing variables (shouldn't warn). @@ -40,26 +48,34 @@ void test() { 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()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} if ((x = (b+b).foo())) {} do { - } while (x = (b+b).foo()); // expected-warning {{using the result of an assignment as a condition without parentheses}} + } while (x = (b+b).foo()); // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} 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()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} 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(); ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} 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) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} if ((a = b + b)) {} do { - } while (a = b + b); // expected-warning {{using the result of an assignment as a condition without parentheses}} + } while (a = b + b); // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} 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) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} 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; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} for (; (a = b + b); ) {} } diff --git a/test/SemaObjC/bad-receiver-1.m b/test/SemaObjC/bad-receiver-1.m index 094c12f..33e1630 100644 --- a/test/SemaObjC/bad-receiver-1.m +++ b/test/SemaObjC/bad-receiver-1.m @@ -4,6 +4,8 @@ - (id) retain; @end +int objc_lookUpClass(const char*); + void __raiseExc1() { [objc_lookUpClass("NSString") retain]; // expected-warning {{receiver type 'int' is not 'id'}} \ expected-warning {{method '-retain' not found}} diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m index 17c6b46..33e4646 100644 --- a/test/SemaObjC/category-1.m +++ b/test/SemaObjC/category-1.m @@ -29,7 +29,7 @@ @interface MyClass1 (Category) <p2, p3> @end // expected-warning {{cannot find protocol definition for 'p2'}} -@interface MyClass (Category) @end // expected-error {{cannot find interface declaration for 'MyClass'}} +@interface UnknownClass (Category) @end // expected-error {{cannot find interface declaration for 'UnknownClass'}} @class MyClass2; diff --git a/test/SemaObjC/continuation-class-property.m b/test/SemaObjC/continuation-class-property.m new file mode 100644 index 0000000..c48a23d --- /dev/null +++ b/test/SemaObjC/continuation-class-property.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// radar 7509234 + +@protocol Foo +@property (readonly, copy) id foos; +@end + +@interface Bar <Foo> { +} + +@end + +@interface Baz <Foo> { +} +@end + +@interface Bar () +@property (readwrite, copy) id foos; +@end + +@interface Baz () +@property (readwrite, copy) id foos; +@end + diff --git a/test/SemaObjC/ivar-access-package.m b/test/SemaObjC/ivar-access-package.m index 956ae5b..abc3420 100644 --- a/test/SemaObjC/ivar-access-package.m +++ b/test/SemaObjC/ivar-access-package.m @@ -34,6 +34,8 @@ typedef unsigned char BOOL; } @end +void NSLog(id, ...); + int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; A *a = [[A new] autorelease]; diff --git a/test/SemaObjC/ivar-lookup-resolution-builtin.m b/test/SemaObjC/ivar-lookup-resolution-builtin.m new file mode 100644 index 0000000..2e90e8e --- /dev/null +++ b/test/SemaObjC/ivar-lookup-resolution-builtin.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// pr5986 + +@interface Test { + int index; +} +- (int) index; ++ (int) ClassMethod; +@end + +@implementation Test +- (int) index +{ + return index; +} ++ (int) ClassMethod +{ + return index; // expected-error {{instance variable 'index' accessed in class method}} +} +@end + +@interface Test1 { +} +- (int) InstMethod; ++ (int) ClassMethod; +@end + +@implementation Test1 +- (int) InstMethod +{ + return index; // expected-warning {{implicitly declaring C library function 'index'}} \ + // expected-note {{please include the header <strings.h> or explicitly provide a declaration for 'index'}} \ + // expected-warning {{incompatible pointer to integer conversion returning}} +} ++ (int) ClassMethod +{ + return index; // expected-warning {{incompatible pointer to integer conversion returning}} +} +@end + diff --git a/test/SemaObjC/nonnull.m b/test/SemaObjC/nonnull.m index c96a91a..642f50f 100644 --- a/test/SemaObjC/nonnull.m +++ b/test/SemaObjC/nonnull.m @@ -19,6 +19,9 @@ __attribute__((nonnull(1,3))); extern void func4 (void (^block1)(), void (^block2)()) __attribute__((nonnull(1))) __attribute__((nonnull(2))); +void func6(); +void func7(); + void foo (int i1, int i2, int i3, void (^cp1)(), void (^cp2)(), void (^cp3)()) { diff --git a/test/SemaObjC/property-9.m b/test/SemaObjC/property-9.m index 138f099..d527a9c 100644 --- a/test/SemaObjC/property-9.m +++ b/test/SemaObjC/property-9.m @@ -84,3 +84,15 @@ typedef signed char BOOL; view.inEyeDropperMode = 1; } @end + +// radar 7427072 +@interface MyStyleIntf +{ + int _myStyle; +} + +@property(readonly) int myStyle; + +- (float)setMyStyle:(int)style; +@end + diff --git a/test/SemaObjC/protocol-archane.m b/test/SemaObjC/protocol-archane.m index 108a729..138c43d 100644 --- a/test/SemaObjC/protocol-archane.m +++ b/test/SemaObjC/protocol-archane.m @@ -5,6 +5,7 @@ - (void) bar; @end +void bar(); void foo(id x) { bar((short<SomeProtocol>)x); // expected-error {{expected ')'}} expected-note {{to match this '('}} bar((<SomeProtocol>)x); // expected-warning {{protocol qualifiers without 'id' is archaic}} diff --git a/test/SemaObjC/undef-class-messagin-error.m b/test/SemaObjC/undef-class-messagin-error.m index 0a400dd..63e0b9d 100644 --- a/test/SemaObjC/undef-class-messagin-error.m +++ b/test/SemaObjC/undef-class-messagin-error.m @@ -1,13 +1,13 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -@interface _Child +@interface _Child // expected-note{{'_Child' declared here}} + (int) flashCache; @end -@interface Child (Categ) // expected-error {{cannot find interface declaration for 'Child'}} +@interface Child (Categ) // expected-error {{cannot find interface declaration for 'Child'; did you mean '_Child'?}} + (int) flushCache2; @end -@implementation Child (Categ) // expected-error {{cannot find interface declaration for 'Child'}} +@implementation OtherChild (Categ) // expected-error {{cannot find interface declaration for 'OtherChild'}} + (int) flushCache2 { [super flashCache]; } // expected-error {{no @interface declaration found in class messaging of 'flushCache2'}} @end diff --git a/test/SemaObjC/undef-superclass-1.m b/test/SemaObjC/undef-superclass-1.m index 7611cf3..0c2594c 100644 --- a/test/SemaObjC/undef-superclass-1.m +++ b/test/SemaObjC/undef-superclass-1.m @@ -13,7 +13,8 @@ @interface INTF2 : INTF1 @end -@interface INTF3 : Y // expected-error {{cannot find interface declaration for 'Y', superclass of 'INTF3'}} +@interface INTF3 : Y // expected-error {{cannot find interface declaration for 'Y', superclass of 'INTF3'}} \ + // expected-note{{'INTF3' declared here}} @end @interface INTF1 // expected-error {{duplicate interface definition for class 'INTF1'}} @@ -31,3 +32,5 @@ @implementation RecursiveClass @end +@implementation iNTF3 // expected-warning{{cannot find interface declaration for 'iNTF3'; did you mean 'INTF3'?}} +@end diff --git a/test/SemaTemplate/ambiguous-ovl-print.cpp b/test/SemaTemplate/ambiguous-ovl-print.cpp index 17f412f..7e3fa24 100644 --- a/test/SemaTemplate/ambiguous-ovl-print.cpp +++ b/test/SemaTemplate/ambiguous-ovl-print.cpp @@ -2,7 +2,7 @@ void f(void*, int); // expected-note{{candidate function}} template<typename T> - void f(T*, long); // expected-note{{candidate function template}} + void f(T*, long); // expected-note{{candidate function}} void test_f(int *ip, int i) { f(ip, i); // expected-error{{ambiguous}} diff --git a/test/SemaTemplate/constructor-template.cpp b/test/SemaTemplate/constructor-template.cpp index 139de9d..82c2aa4 100644 --- a/test/SemaTemplate/constructor-template.cpp +++ b/test/SemaTemplate/constructor-template.cpp @@ -52,8 +52,8 @@ template <> struct A<int>{A(const A<int>&);}; struct B { A<int> x; B(B& a) : x(a.x) {} }; struct X2 { - X2(); // expected-note{{candidate function}} - X2(X2&); // expected-note {{candidate function}} + X2(); // expected-note{{candidate constructor}} + X2(X2&); // expected-note {{candidate constructor}} template<typename T> X2(T); }; @@ -71,9 +71,9 @@ struct X3 { template<> X3::X3(X3); // expected-error{{must pass its first argument by reference}} struct X4 { - X4(); // expected-note{{candidate function}} + X4(); // expected-note{{candidate constructor}} ~X4(); - X4(X4&); // expected-note {{candidate function}} + X4(X4&); // expected-note {{candidate constructor}} template<typename T> X4(const T&, int = 17); }; diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp index 0edc504..131b80c 100644 --- a/test/SemaTemplate/default-expr-arguments.cpp +++ b/test/SemaTemplate/default-expr-arguments.cpp @@ -5,7 +5,7 @@ class C { C(int a0 = 0); }; template<> C<char>::C(int a0); -struct S { }; // expected-note 3 {{candidate function}} +struct S { }; // expected-note 3 {{candidate constructor (the implicit copy constructor)}} template<typename T> void f1(T a, T b = 10) { } // expected-error{{no viable conversion}} diff --git a/test/SemaTemplate/dependent-base-classes.cpp b/test/SemaTemplate/dependent-base-classes.cpp new file mode 100644 index 0000000..79b28c2 --- /dev/null +++ b/test/SemaTemplate/dependent-base-classes.cpp @@ -0,0 +1,84 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template<typename T, typename U> +struct X0 : T::template apply<U> { + X0(U u) : T::template apply<U>(u) { } +}; + +template<typename T, typename U> +struct X1 : T::apply<U> { }; // expected-error{{missing 'template' keyword prior to dependent template name 'T::apply'}} + +template<typename T> +struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}} + +namespace PR6031 { + template<typename T> + struct A; + + template <class X> + struct C { }; + + template <class TT> + struct II { + typedef typename A<TT>::type type; + }; + + template <class TT> + struct FI : II<TT> + { + C<typename FI::type> a; + }; + + template <class TT> + struct FI2 + { + C<typename FI2::type> a; // expected-error{{no type named 'type' in 'struct PR6031::FI2'}} \ + // expected-error{{C++ requires a type specifier for all declarations}} + }; + + template<typename T> + struct Base { + class Nested { }; + template<typename U> struct MemberTemplate { }; + int a; + }; + + template<typename T> + struct HasDepBase : Base<T> { + int foo() { + class HasDepBase::Nested nested; + typedef typename HasDepBase::template MemberTemplate<T>::type type; + return HasDepBase::a; + } + }; + + template<typename T> + struct NoDepBase { + int foo() { + class NoDepBase::Nested nested; // expected-error{{'Nested' does not name a tag member in the specified scope}} + typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{'MemberTemplate' following the 'template' keyword does not refer to a template}} \ + // FIXME: expected-error{{expected an identifier or template-id after '::'}} \ + // FIXME: expected-error{{unqualified-id}} + return NoDepBase::a; // expected-error{{no member named 'a' in 'struct PR6031::NoDepBase'}} + } + }; +} + +namespace Ambig { + template<typename T> + struct Base1 { + typedef int type; // expected-note{{member found by ambiguous name lookup}} + }; + + struct Base2 { + typedef float type; // expected-note{{member found by ambiguous name lookup}} + }; + + template<typename T> + struct Derived : Base1<T>, Base2 { + typedef typename Derived::type type; // expected-error{{member 'type' found in multiple base classes of different types}} + type *foo(float *fp) { return fp; } + }; + + Derived<int> di; // expected-note{{instantiation of}} +} diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp index fbb5edb..227856f 100644 --- a/test/SemaTemplate/explicit-instantiation.cpp +++ b/test/SemaTemplate/explicit-instantiation.cpp @@ -25,8 +25,8 @@ T X0<T>::value; // expected-error{{no matching constructor}} template int X0<int>::value; -struct NotDefaultConstructible { // expected-note{{candidate function}} - NotDefaultConstructible(int); // expected-note{{candidate function}} +struct NotDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor)}} + NotDefaultConstructible(int); // expected-note{{candidate constructor}} }; template NotDefaultConstructible X0<NotDefaultConstructible>::value; // expected-note{{instantiation}} diff --git a/test/SemaTemplate/fun-template-def.cpp b/test/SemaTemplate/fun-template-def.cpp index 0c2cf9c..1c9b232 100644 --- a/test/SemaTemplate/fun-template-def.cpp +++ b/test/SemaTemplate/fun-template-def.cpp @@ -8,7 +8,7 @@ // Fake typeid, lacking a typeinfo header. namespace std { class type_info {}; } -struct dummy {}; // expected-note 3 {{candidate function}} +struct dummy {}; // expected-note 3 {{candidate constructor (the implicit copy constructor)}} template<typename T> int f0(T x) { diff --git a/test/SemaTemplate/function-template-specialization.cpp b/test/SemaTemplate/function-template-specialization.cpp index 91989b1..9afc99f 100644 --- a/test/SemaTemplate/function-template-specialization.cpp +++ b/test/SemaTemplate/function-template-specialization.cpp @@ -33,3 +33,11 @@ template<> void f2<double>(double (&array)[42]); template<> void f2<42>(double (&array)[42]); void f2<25>(double (&array)[25]); // expected-error{{specialization}} + +// PR5833 +namespace PR5833 { + template <typename T> bool f0(T &t1); + template <> bool f0<float>(float &t1); +} +template <> bool PR5833::f0<float>(float &t1) {} + diff --git a/test/SemaTemplate/injected-class-name.cpp b/test/SemaTemplate/injected-class-name.cpp index 1a65aeb3..482eae1 100644 --- a/test/SemaTemplate/injected-class-name.cpp +++ b/test/SemaTemplate/injected-class-name.cpp @@ -11,11 +11,7 @@ struct X<int***> { typedef X<int***> *ptr; }; -// FIXME: EDG rejects this in their strict-conformance mode, but I -// don't see any wording making this ill-formed. Actually, -// [temp.local]p2 might make it ill-formed. Are we "in the scope of -// the class template specialization?" -X<float>::X<int> xi = x; +X<float>::X<int> xi = x; // expected-error{{qualified reference to 'X' is a constructor name rather than a template name wherever a constructor can be declared}} // [temp.local]p1: diff --git a/test/SemaTemplate/instantiate-expr-4.cpp b/test/SemaTemplate/instantiate-expr-4.cpp index c524e95..428ef1b 100644 --- a/test/SemaTemplate/instantiate-expr-4.cpp +++ b/test/SemaTemplate/instantiate-expr-4.cpp @@ -21,8 +21,8 @@ struct FunctionalCast0 { template struct FunctionalCast0<5>; -struct X { // expected-note 3 {{candidate function}} - X(int, int); // expected-note 3 {{candidate function}} +struct X { // expected-note 3 {{candidate constructor (the implicit copy constructor)}} + X(int, int); // expected-note 3 {{candidate constructor}} }; template<int N, int M> diff --git a/test/SemaTemplate/instantiate-member-class.cpp b/test/SemaTemplate/instantiate-member-class.cpp index 8a19d74..742abcc 100644 --- a/test/SemaTemplate/instantiate-member-class.cpp +++ b/test/SemaTemplate/instantiate-member-class.cpp @@ -14,8 +14,8 @@ public: X<int>::C *c1; X<float>::C *c2; -X<int>::X *xi; -X<float>::X *xf; +X<int>::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}} +X<float>::X *xf; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}} void test_naming() { c1 = c2; // expected-error{{incompatible type assigning 'X<float>::C *', expected 'X<int>::C *'}} diff --git a/test/SemaTemplate/instantiate-member-expr.cpp b/test/SemaTemplate/instantiate-member-expr.cpp index db13624..324363c 100644 --- a/test/SemaTemplate/instantiate-member-expr.cpp +++ b/test/SemaTemplate/instantiate-member-expr.cpp @@ -25,3 +25,27 @@ class RetainReleaseChecker { }; void f(GRExprEngine& Eng) { Eng.registerCheck(new RetainReleaseChecker); // expected-note {{in instantiation of function template specialization 'GRExprEngine::registerCheck<class RetainReleaseChecker>' requested here}} } + +// PR 5838 +namespace test1 { + template<typename T> struct A { + int a; + }; + + template<typename T> struct B : A<float>, A<T> { + void f() { + a = 0; // should not be ambiguous + } + }; + template struct B<int>; + + struct O { + int a; + template<typename T> struct B : A<T> { + void f() { + a = 0; // expected-error {{type 'struct test1::O' is not a direct or virtual base of ''B<int>''}} + } + }; + }; + template struct O::B<int>; // expected-note {{in instantiation}} +} diff --git a/test/SemaTemplate/instantiate-static-var.cpp b/test/SemaTemplate/instantiate-static-var.cpp index 8a2f34d..789fe3d 100644 --- a/test/SemaTemplate/instantiate-static-var.cpp +++ b/test/SemaTemplate/instantiate-static-var.cpp @@ -30,7 +30,7 @@ T Z<T>::value; // expected-error{{no matching constructor}} struct DefCon {}; struct NoDefCon { - NoDefCon(const NoDefCon&); // expected-note{{candidate function}} + NoDefCon(const NoDefCon&); // expected-note{{candidate constructor}} }; void test() { diff --git a/test/SemaTemplate/instantiate-subscript.cpp b/test/SemaTemplate/instantiate-subscript.cpp index a718751..8c119ec 100644 --- a/test/SemaTemplate/instantiate-subscript.cpp +++ b/test/SemaTemplate/instantiate-subscript.cpp @@ -16,7 +16,7 @@ struct ConvertibleToInt { template<typename T, typename U, typename Result> struct Subscript0 { void test(T t, U u) { - Result &result = t[u]; // expected-error{{subscripted value is not}} + Result &result = t[u]; // expected-error{{no viable overloaded operator[] for type}} } }; diff --git a/test/SemaTemplate/temp_class_spec.cpp b/test/SemaTemplate/temp_class_spec.cpp index 48026f9..e86f07a 100644 --- a/test/SemaTemplate/temp_class_spec.cpp +++ b/test/SemaTemplate/temp_class_spec.cpp @@ -330,3 +330,21 @@ 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}} + +namespace PR6025 { + template< int N > struct A; + + namespace N + { + template< typename F > + struct B; + } + + template< typename Protect, typename Second > + struct C; + + template <class T> + struct C< T, A< N::B<T>::value > > + { + }; +} diff --git a/test/SemaTemplate/typo-dependent-name.cpp b/test/SemaTemplate/typo-dependent-name.cpp new file mode 100644 index 0000000..96554e9 --- /dev/null +++ b/test/SemaTemplate/typo-dependent-name.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template<typename T> +struct Base { + T inner; +}; + +template<typename T> +struct X { + template<typename U> + struct Inner { + }; + + bool f(T other) { + return this->inner < other; + } +}; diff --git a/test/SemaTemplate/virtual-member-functions.cpp b/test/SemaTemplate/virtual-member-functions.cpp index 69ae080..db24313 100644 --- a/test/SemaTemplate/virtual-member-functions.cpp +++ b/test/SemaTemplate/virtual-member-functions.cpp @@ -3,14 +3,19 @@ namespace PR5557 { template <class T> struct A { A(); + virtual void anchor(); // expected-note{{instantiation}} virtual int a(T x); }; template<class T> A<T>::A() {} +template<class T> void A<T>::anchor() { } + template<class T> int A<T>::a(T x) { return *x; // expected-error{{requires pointer operand}} } -A<int> x; // expected-note{{instantiation}} +void f(A<int> x) { + x.anchor(); +} template<typename T> struct X { @@ -20,3 +25,31 @@ struct X { template<> void X<int>::f() { } } + +template<typename T> +struct Base { + virtual ~Base() { + int *ptr = 0; + T t = ptr; // expected-error{{cannot initialize}} + } +}; + +template<typename T> +struct Derived : Base<T> { + virtual void foo() { } +}; + +template struct Derived<int>; // expected-note{{instantiation}} + +template<typename T> +struct HasOutOfLineKey { + HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}} + virtual T *f(float *fp); +}; + +template<typename T> +T *HasOutOfLineKey<T>::f(float *fp) { + return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}} +} + +HasOutOfLineKey<int> out_of_line; |