From 07b2cfcdb817cc0790420f159a313d61e7241cb9 Mon Sep 17 00:00:00 2001 From: rdivacky Date: Fri, 2 Apr 2010 08:55:10 +0000 Subject: Update clang to r100181. --- test/Analysis/PR3991.m | 20 ++- test/Analysis/inline.c | 2 +- test/Analysis/misc-ps-region-store.m | 45 +++++++ test/Analysis/no-outofbounds.c | 3 +- test/Analysis/null-deref-ps.c | 4 +- test/Analysis/outofbound.c | 23 ++++ test/Analysis/plist-output.m | 40 +++--- test/Analysis/pr4209.m | 8 +- test/Analysis/retain-release-region-store.m | 16 +++ test/Analysis/retain-release.m | 9 +- test/Analysis/uninit-vals-ps-region.m | 7 ++ .../basic/basic.lookup/basic.lookup.argdep/p4.cpp | 12 ++ .../basic.stc.dynamic/p2-noexceptions.cpp | 13 ++ test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp | 9 +- test/CXX/class.access/class.access.base/p5.cpp | 75 +++++++++++ test/CXX/class.access/class.friend/p1.cpp | 43 +++++++ test/CXX/class.access/p4.cpp | 69 ++++++++++- test/CXX/class.derived/class.abstract/p4.cpp | 80 ++++++++++++ test/CXX/class.derived/class.abstract/p5.cpp | 23 ++++ test/CXX/class.derived/class.virtual/p2.cpp | 37 ++++++ .../dcl.dcl/basic.namespace/namespace.udecl/p1.cpp | 43 ++++++- .../dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp | 14 +-- test/CXX/stmt.stmt/stmt.select/p3.cpp | 11 ++ test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp | 4 +- test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp | 80 +++++++++++- test/CXX/temp/temp.decls/temp.friend/p1.cpp | 131 ++++++++++++++++++++ test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp | 26 ++++ .../temp.deduct/temp.deduct.type/p17.cpp | 31 +++++ test/CXX/temp/temp.res/temp.local/p1.cpp | 3 +- test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp | 2 +- test/CodeGen/atomic.c | 6 +- test/CodeGen/mangle.c | 4 + test/CodeGen/palignr.c | 2 +- test/CodeGen/regparm.c | 11 +- test/CodeGen/restrict.c | 26 ++++ test/CodeGenCXX/constructor-init.cpp | 21 ++++ test/CodeGenCXX/copy-constructor-synthesis.cpp | 54 ++++++-- test/CodeGenCXX/member-expressions.cpp | 40 ++++++ test/CodeGenCXX/multi-dim-operator-new.cpp | 49 ++++++++ test/CodeGenCXX/references.cpp | 8 ++ test/CodeGenCXX/rtti-fundamental.cpp | 71 +++++++++++ test/CodeGenCXX/rtti-linkage.cpp | 1 + test/CodeGenCXX/template-instantiation.cpp | 76 ++++++++++++ test/CodeGenCXX/temporaries.cpp | 13 ++ test/CodeGenCXX/thunks.cpp | 137 +++++++++++++++++++++ test/CodeGenCXX/virt.cpp | 52 -------- test/CodeGenCXX/virtual-bases.cpp | 23 ++++ test/CodeGenCXX/vtable-layout-abi-examples.cpp | 1 - test/CodeGenCXX/vtable-layout.cpp | 49 +++++--- test/CodeGenCXX/vtable-linkage.cpp | 20 +-- test/CodeGenObjC/complex-property.m | 32 +++++ test/CodeGenObjC/objc2-nonfragile-abi-impl.m | 15 +++ test/Driver/nostdincxx.cpp | 4 + test/FixIt/fixit.cpp | 3 + test/Headers/c89.c | 10 ++ test/Headers/x86-intrinsics-headers.c | 32 +++++ test/Index/Inputs/remap-complete-to.c | 7 +- test/Index/cindex-on-invalid.m | 7 +- test/Index/print-usrs.c | 17 +++ test/Index/recover-bad-code-rdar_7487294.c | 1 - test/Index/remap-complete.c | 7 +- test/PCH/changed-files.c | 36 +++--- test/Parser/cxx-default-args.cpp | 9 ++ test/Parser/objc-messaging-neg-1.m | 6 + test/Parser/statements.c | 5 + test/Preprocessor/dependencies-and-pp.c | 26 ++++ test/Preprocessor/macro_disable.c | 34 ++++- test/Preprocessor/macro_disable2.c | 8 -- test/Preprocessor/macro_disable3.c | 10 -- test/Preprocessor/macro_disable4.c | 6 - test/Preprocessor/output_paste_avoid.c | 4 + test/Sema/attr-format.c | 80 ++++++++++++ test/Sema/attr-sentinel.c | 48 ++++++++ test/Sema/attr-unused.c | 17 ++- test/Sema/format-attr-pr4470.c | 12 -- test/Sema/format-attribute-printf0.c | 26 ---- test/Sema/format-attribute.c | 34 ----- test/Sema/format-strings.c | 13 ++ test/Sema/function-pointer-sentinel-attribute.c | 20 --- test/Sema/function-sentinel-attr.c | 30 ----- test/Sema/init.c | 3 +- test/Sema/nested-redef.c | 3 +- test/Sema/return.c | 17 +++ test/Sema/struct-packed-align.c | 8 ++ test/Sema/warn-gnu-designators.c | 2 + test/Sema/warn-shadow.c | 5 + test/Sema/x86-intrinsics-headers.c | 32 ----- test/SemaCXX/PR6618.cpp | 13 ++ test/SemaCXX/class-base-member-init.cpp | 44 ++++++- test/SemaCXX/class-layout.cpp | 7 ++ test/SemaCXX/conditional-expr.cpp | 18 ++- test/SemaCXX/destructor.cpp | 5 + test/SemaCXX/exception-spec.cpp | 6 +- test/SemaCXX/invalid-member-expr.cpp | 18 +++ test/SemaCXX/namespace-alias.cpp | 10 +- test/SemaCXX/namespace.cpp | 22 ++++ test/SemaCXX/nested-name-spec.cpp | 2 +- test/SemaCXX/new-delete-predefined-decl-2.cpp | 13 ++ test/SemaCXX/qual-id-test.cpp | 9 ++ test/SemaCXX/static-cast.cpp | 4 +- test/SemaCXX/warn-reorder-ctor-initialization.cpp | 12 ++ test/SemaObjC/block-type-safety.m | 8 +- test/SemaObjC/category-1.m | 6 +- test/SemaObjC/compare-qualified-id.m | 7 +- test/SemaObjC/comptypes-7.m | 5 + test/SemaObjC/conditional-expr.m | 4 +- test/SemaObjC/gcc-cast-ext.m | 6 +- test/SemaObjC/ivar-in-class-extension-error.m | 15 +++ test/SemaObjC/ivar-in-implementations.m | 23 +++- test/SemaObjC/ivar-sem-check-1.m | 3 +- test/SemaObjC/method-arg-decay.m | 10 +- test/SemaObjC/method-undef-category-warn-1.m | 22 ++-- test/SemaObjC/method-undef-extension-warn-1.m | 10 +- test/SemaObjC/method-undefined-warn-1.m | 16 +-- test/SemaObjC/method-warn-unused-attribute.m | 12 +- test/SemaObjC/no-protocol-option-tests.m | 32 +++++ test/SemaObjC/nsobject-attribute.m | 6 + test/SemaObjC/property-expression-error.m | 5 + test/SemaObjC/property-in-class-extension.m | 15 +++ test/SemaObjC/property-ivar-mismatch.m | 4 +- test/SemaObjC/property.m | 4 +- test/SemaObjC/undef-protocol-methods-1.m | 34 +++-- test/SemaTemplate/dependent-base-classes.cpp | 2 +- test/SemaTemplate/friend-template.cpp | 8 +- test/SemaTemplate/instantiate-declref.cpp | 2 +- .../instantiate-elab-type-specifier.cpp | 13 ++ test/SemaTemplate/instantiate-expr-4.cpp | 13 ++ test/SemaTemplate/instantiate-function-params.cpp | 57 +++++++++ test/SemaTemplate/instantiate-init.cpp | 18 +++ test/SemaTemplate/instantiate-member-class.cpp | 30 +++++ .../instantiate-member-initializers.cpp | 6 +- test/SemaTemplate/instantiation-default-2.cpp | 2 +- test/SemaTemplate/temp_arg_nontype.cpp | 33 ++--- 133 files changed, 2306 insertions(+), 484 deletions(-) create mode 100644 test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp create mode 100644 test/CXX/class.access/class.access.base/p5.cpp create mode 100644 test/CXX/class.derived/class.abstract/p4.cpp create mode 100644 test/CXX/class.derived/class.abstract/p5.cpp create mode 100644 test/CXX/class.derived/class.virtual/p2.cpp create mode 100644 test/CXX/stmt.stmt/stmt.select/p3.cpp create mode 100644 test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp create mode 100644 test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp create mode 100644 test/CodeGen/restrict.c create mode 100644 test/CodeGenCXX/multi-dim-operator-new.cpp create mode 100644 test/CodeGenCXX/rtti-fundamental.cpp create mode 100644 test/CodeGenCXX/template-instantiation.cpp create mode 100644 test/CodeGenCXX/thunks.cpp create mode 100644 test/CodeGenObjC/complex-property.m create mode 100644 test/CodeGenObjC/objc2-nonfragile-abi-impl.m create mode 100644 test/Driver/nostdincxx.cpp create mode 100644 test/Headers/c89.c create mode 100644 test/Headers/x86-intrinsics-headers.c create mode 100644 test/Index/print-usrs.c create mode 100644 test/Parser/cxx-default-args.cpp delete mode 100644 test/Preprocessor/macro_disable2.c delete mode 100644 test/Preprocessor/macro_disable3.c delete mode 100644 test/Preprocessor/macro_disable4.c create mode 100644 test/Sema/attr-format.c create mode 100644 test/Sema/attr-sentinel.c delete mode 100644 test/Sema/format-attr-pr4470.c delete mode 100644 test/Sema/format-attribute-printf0.c delete mode 100644 test/Sema/format-attribute.c delete mode 100644 test/Sema/function-pointer-sentinel-attribute.c delete mode 100644 test/Sema/function-sentinel-attr.c create mode 100644 test/Sema/warn-gnu-designators.c delete mode 100644 test/Sema/x86-intrinsics-headers.c create mode 100644 test/SemaCXX/PR6618.cpp create mode 100644 test/SemaCXX/new-delete-predefined-decl-2.cpp create mode 100644 test/SemaObjC/ivar-in-class-extension-error.m create mode 100644 test/SemaObjC/no-protocol-option-tests.m create mode 100644 test/SemaObjC/property-in-class-extension.m create mode 100644 test/SemaTemplate/instantiate-elab-type-specifier.cpp create mode 100644 test/SemaTemplate/instantiate-function-params.cpp (limited to 'test') diff --git a/test/Analysis/PR3991.m b/test/Analysis/PR3991.m index 3fed57e..c1f238c 100644 --- a/test/Analysis/PR3991.m +++ b/test/Analysis/PR3991.m @@ -35,22 +35,16 @@ typedef struct _NSZone NSZone; @protocol IHGoogleDocsAdapterDelegate - (void)googleDocsAdapter:(IHGoogleDocsAdapter*)inGoogleDocsAdapter accountVerifyIsValid:(BOOL)inIsValid error:(NSError *)inError; @end @interface IHGoogleDocsAdapter : NSObject { } -- (NSArray *)entries; +- (NSArray *)entries; // expected-note {{method definition for 'entries' not found}} @end extern Class const kGDataUseRegisteredClass ; -@interface IHGoogleDocsAdapter () - (GDataFeedDocList *)feedDocList; -- (NSArray *)directoryPathComponents; -- (unsigned int)currentPathComponentIndex; -- (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex; -- (NSURL *)folderFeedURL; +@interface IHGoogleDocsAdapter () - (GDataFeedDocList *)feedDocList; // expected-note {{method definition for 'feedDocList' not found}} +- (NSArray *)directoryPathComponents; // expected-note {{method definition for 'directoryPathComponents' not found}} +- (unsigned int)currentPathComponentIndex; // expected-note {{method definition for 'currentPathComponentIndex' not found}} +- (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex; // expected-note {{method definition for 'setCurrentPathComponentIndex:' not found}} +- (NSURL *)folderFeedURL; // expected-note {{method definition for 'folderFeedURL' not found}} @end -@implementation IHGoogleDocsAdapter - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject *)owner { // expected-warning {{incomplete implementation}} \ -// expected-warning {{method definition for 'entries' not found}} \ -// expected-warning {{method definition for 'feedDocList' not found}} \ -// expected-warning {{method definition for 'directoryPathComponents' not found}} \ -// expected-warning {{method definition for 'currentPathComponentIndex' not found}} \ -// expected-warning {{method definition for 'setCurrentPathComponentIndex:' not found}} \ -// expected-warning {{method definition for 'folderFeedURL' not found}} +@implementation IHGoogleDocsAdapter - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject *)owner { // expected-warning {{incomplete implementation}} return 0; } diff --git a/test/Analysis/inline.c b/test/Analysis/inline.c index 13d4f7f..952de73 100644 --- a/test/Analysis/inline.c +++ b/test/Analysis/inline.c @@ -15,6 +15,6 @@ void f2() { } if (x == 2) { int *p = 0; - *p = 3; // expected-warning{{Dereference of null pointer loaded from variable}} + *p = 3; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}} } } diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index 898a33e..d10b9fa 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -910,3 +910,48 @@ int rdar_7770737_pos(void) struct rdar_7770737_s f = { .p = (intptr_t)&x }; return x; // expected-warning{{Undefined or garbage value returned to caller}} } + +//===----------------------------------------------------------------------===// +// Test handling of the implicit 'isa' field. For now we don't do anything +// interesting. +//===----------------------------------------------------------------------===// + +void pr6302(id x, Class y) { + // This previously crashed the analyzer (reported in PR 6302) + x->isa = y; +} + +//===----------------------------------------------------------------------===// +// Specially handle global variables that are declared constant. In the +// example below, this forces the loop to take exactly 2 iterations. +//===----------------------------------------------------------------------===// + +const int pr6288_L_N = 2; +void pr6288_(void) { + int x[2]; + int *px[2]; + int i; + for (i = 0; i < pr6288_L_N; i++) + px[i] = &x[i]; + *(px[0]) = 0; // no-warning +} + +void pr6288_pos(int z) { + int x[2]; + int *px[2]; + int i; + for (i = 0; i < z; i++) + px[i] = &x[i]; // expected-warning{{Access out-of-bound array element (buffer overflow)}} + *(px[0]) = 0; // expected-warning{{Dereference of undefined pointer value}} +} + +void pr6288_b(void) { + const int L_N = 2; + int x[2]; + int *px[2]; + int i; + for (i = 0; i < L_N; i++) + px[i] = &x[i]; + *(px[0]) = 0; // no-warning +} + diff --git a/test/Analysis/no-outofbounds.c b/test/Analysis/no-outofbounds.c index f9ac589..771323b 100644 --- a/test/Analysis/no-outofbounds.c +++ b/test/Analysis/no-outofbounds.c @@ -1,6 +1,5 @@ // RUN: %clang_cc1 -analyzer-check-objc-mem -analyze -analyzer-experimental-internal-checks -analyzer-store=basic -verify %s // RUN: %clang_cc1 -analyzer-check-objc-mem -analyze -analyzer-experimental-internal-checks -analyzer-store=region -verify %s -// XFAIL: * //===----------------------------------------------------------------------===// // This file tests cases where we should not flag out-of-bounds warnings. @@ -10,4 +9,6 @@ void f() { long x = 0; char *y = (char*) &x; char c = y[0] + y[1] + y[2]; // no-warning + short *z = (short*) &x; + short s = z[0] + z[1]; // no-warning } diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c index 704ad33..5376ca0 100644 --- a/test/Analysis/null-deref-ps.c +++ b/test/Analysis/null-deref-ps.c @@ -26,7 +26,7 @@ int f2(struct foo_struct* p) { if (p) p->x = 1; - return p->x++; // expected-warning{{Dereference of null pointer}} + return p->x++; // expected-warning{{Field access results in a dereference of a null pointer (loaded from variable 'p')}} } int f3(char* x) { @@ -57,7 +57,7 @@ int f4(int *p) { return 1; int *q = (int*) x; - return *q; // expected-warning{{Dereference of null pointer loaded from variable 'q'}} + return *q; // expected-warning{{Dereference of null pointer (loaded from variable 'q')}} } int f4_b() { diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c index 45325e9..e1ff66c 100644 --- a/test/Analysis/outofbound.c +++ b/test/Analysis/outofbound.c @@ -13,3 +13,26 @@ void f2() { int *p = malloc(12); p[3] = 4; // expected-warning{{Access out-of-bound array element (buffer overflow)}} } + +struct three_words { + int c[3]; +}; + +struct seven_words { + int c[7]; +}; + +void f3() { + struct three_words a, *p; + p = &a; + p[0] = a; // no-warning + p[1] = a; // expected-warning{{Access out-of-bound array element (buffer overflow)}} +} + +void f4() { + struct seven_words c; + struct three_words a, *p = (struct three_words *)&c; + p[0] = a; // no-warning + p[1] = a; // no-warning + p[2] = a; // expected-warning{{Access out-of-bound array element (buffer overflow)}} +} diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m index f49fef5..aa866de 100644 --- a/test/Analysis/plist-output.m +++ b/test/Analysis/plist-output.m @@ -124,7 +124,7 @@ void test_null_field(void) { // CHECK: // CHECK: // CHECK: line5 -// CHECK: col3 +// CHECK: col4 // CHECK: file0 // CHECK: // CHECK: @@ -135,12 +135,12 @@ void test_null_field(void) { // CHECK: // CHECK: // CHECK: extended_message -// CHECK: Dereference of null pointer loaded from variable 'p' +// CHECK: Dereference of null pointer (loaded from variable 'p') // CHECK: message -// CHECK: Dereference of null pointer loaded from variable 'p' +// CHECK: Dereference of null pointer (loaded from variable 'p') // CHECK: // CHECK: -// CHECK: descriptionDereference of null pointer loaded from variable 'p' +// CHECK: descriptionDereference of null pointer (loaded from variable 'p') // CHECK: categoryLogic error // CHECK: typeDereference of null pointer // CHECK: location @@ -262,7 +262,7 @@ void test_null_field(void) { // CHECK: // CHECK: // CHECK: line11 -// CHECK: col3 +// CHECK: col4 // CHECK: file0 // CHECK: // CHECK: @@ -273,12 +273,12 @@ void test_null_field(void) { // CHECK: // CHECK: // CHECK: extended_message -// CHECK: Dereference of null pointer loaded from variable 'p' +// CHECK: Dereference of null pointer (loaded from variable 'p') // CHECK: message -// CHECK: Dereference of null pointer loaded from variable 'p' +// CHECK: Dereference of null pointer (loaded from variable 'p') // CHECK: // CHECK: -// CHECK: descriptionDereference of null pointer loaded from variable 'p' +// CHECK: descriptionDereference of null pointer (loaded from variable 'p') // CHECK: categoryLogic error // CHECK: typeDereference of null pointer // CHECK: location @@ -400,7 +400,7 @@ void test_null_field(void) { // CHECK: // CHECK: // CHECK: line18 -// CHECK: col3 +// CHECK: col4 // CHECK: file0 // CHECK: // CHECK: @@ -411,12 +411,12 @@ void test_null_field(void) { // CHECK: // CHECK: // CHECK: extended_message -// CHECK: Dereference of null pointer loaded from variable 'q' +// CHECK: Dereference of null pointer (loaded from variable 'q') // CHECK: message -// CHECK: Dereference of null pointer loaded from variable 'q' +// CHECK: Dereference of null pointer (loaded from variable 'q') // CHECK: // CHECK: -// CHECK: descriptionDereference of null pointer loaded from variable 'q' +// CHECK: descriptionDereference of null pointer (loaded from variable 'q') // CHECK: categoryLogic error // CHECK: typeDereference of null pointer // CHECK: location @@ -538,7 +538,7 @@ void test_null_field(void) { // CHECK: // CHECK: // CHECK: line23 -// CHECK: col5 +// CHECK: col6 // CHECK: file0 // CHECK: // CHECK: @@ -549,12 +549,12 @@ void test_null_field(void) { // CHECK: // CHECK: // CHECK: extended_message -// CHECK: Dereference of null pointer loaded from variable 'p' +// CHECK: Dereference of null pointer (loaded from variable 'p') // CHECK: message -// CHECK: Dereference of null pointer loaded from variable 'p' +// CHECK: Dereference of null pointer (loaded from variable 'p') // CHECK: // CHECK: -// CHECK: descriptionDereference of null pointer loaded from variable 'p' +// CHECK: descriptionDereference of null pointer (loaded from variable 'p') // CHECK: categoryLogic error // CHECK: typeDereference of null pointer // CHECK: location @@ -710,7 +710,7 @@ void test_null_field(void) { // CHECK: // CHECK: // CHECK: line30 -// CHECK: col5 +// CHECK: col6 // CHECK: file0 // CHECK: // CHECK: @@ -721,12 +721,12 @@ void test_null_field(void) { // CHECK: // CHECK: // CHECK: extended_message -// CHECK: Dereference of null pointer loaded from variable 'p' +// CHECK: Dereference of null pointer (loaded from variable 'p') // CHECK: message -// CHECK: Dereference of null pointer loaded from variable 'p' +// CHECK: Dereference of null pointer (loaded from variable 'p') // CHECK: // CHECK: -// CHECK: descriptionDereference of null pointer loaded from variable 'p' +// CHECK: descriptionDereference of null pointer (loaded from variable 'p') // CHECK: categoryLogic error // CHECK: typeDereference of null pointer // CHECK: location diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m index eb01015..dc1ef7b 100644 --- a/test/Analysis/pr4209.m +++ b/test/Analysis/pr4209.m @@ -48,16 +48,14 @@ CMProfileLocation; @interface GBCategoryChooserPanelController : NSWindowController { GSEbayCategory *rootCategory; } -- (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories; --(NSString*) categoryID; +- (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories; // expected-note {{method definition for 'categoryDictionaryForCategoryID:inRootTreeCategories:' not found}} +-(NSString*) categoryID; // expected-note {{method definition for 'categoryID' not found}} @end @interface GSEbayCategory : NSObject { } - (int) categoryID; - (GSEbayCategory *) parent; - (GSEbayCategory*) subcategoryWithID:(int) inID; -@end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent { // expected-warning {{incomplete implementation}} \ -// expected-warning {{method definition for 'categoryDictionaryForCategoryID:inRootTreeCategories:' not found}} \ -// expected-warning {{method definition for 'categoryID' not found}} +@end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent { // expected-warning {{incomplete implementation}} return 0; } - (void) addCategory:(EBayCategoryType*)inCategory toRootTreeCategory:(NSMutableArray*)inRootTreeCategories { diff --git a/test/Analysis/retain-release-region-store.m b/test/Analysis/retain-release-region-store.m index 111d4b9..db49b91 100644 --- a/test/Analysis/retain-release-region-store.m +++ b/test/Analysis/retain-release-region-store.m @@ -207,3 +207,19 @@ void rdar7283470_2_positive(void) { [numbers[i] release]; } +void pr6699(int x) { + CFDateRef values[2]; + values[0] = values[1] = 0; + + if (x) { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + values[1] = CFDateCreate(0, t); + } + + if (values[1]) { + // A bug in RegionStore::RemoveDeadBindings caused 'values[1]' to get prematurely + // pruned from the store. + CFRelease(values[1]); // no-warning + } +} + diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 675e9a6..3f79c0c 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -1268,6 +1268,7 @@ CFDateRef returnsRetainedCFDate() { //===----------------------------------------------------------------------===// void panic() __attribute__((noreturn)); +void panic_not_in_hardcoded_list() __attribute__((noreturn)); void test_panic_negative() { signed z = 1; @@ -1291,9 +1292,13 @@ void test_panic_pos_2(int x) { signed z = 1; CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning if (x) - panic(); - if (!x) panic(); + if (!x) { + // This showed up in , where we silently missed checking + // the function type for noreturn. "panic()" is a hard-coded known panic function + // that isn't always noreturn. + panic_not_in_hardcoded_list(); + } } //===----------------------------------------------------------------------===// diff --git a/test/Analysis/uninit-vals-ps-region.m b/test/Analysis/uninit-vals-ps-region.m index 7e2fff9..69c1ecd 100644 --- a/test/Analysis/uninit-vals-ps-region.m +++ b/test/Analysis/uninit-vals-ps-region.m @@ -59,4 +59,11 @@ void testFoo(Foo *o) { [o passVal:x]; // expected-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}} } +// Test case from . That shows an uninitialized value +// being used in the LHS of a compound assignment. +void rdar_7780304() { + typedef struct s_r7780304 { int x; } s_r7780304; + s_r7780304 b; + b.x |= 1; // expected-warning{{The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage}} +} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp index b59e6ca..df3429e 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp @@ -40,3 +40,15 @@ namespace Test { D::D() + D::D(); // expected-error {{ invalid operands to binary expression ('D::D' and 'D::D') }} } } + +// PR6716 +namespace test1 { + template class A { + template friend void foo(A &, U); // expected-note {{not viable: 1st argument ('A const') would lose const qualifier}} + }; + + void test() { + const A a; + foo(a, 10); // expected-error {{no matching function for call to 'foo'}} + } +} diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp new file mode 100644 index 0000000..4567c46 --- /dev/null +++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +namespace std { + class bad_alloc { }; + + typedef __SIZE_TYPE__ size_t; +} + +class foo { virtual ~foo(); }; + +void* operator new(std::size_t); +void* operator new[](std::size_t); +void operator delete(void*); +void operator delete[](void*); diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp index f4860bb..37a4f97 100644 --- a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp +++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -fexceptions -verify %s int *use_new(int N) { if (N == 1) return new int; @@ -19,7 +19,10 @@ namespace std { typedef __SIZE_TYPE__ size_t; } -void* operator new(std::size_t) throw(std::bad_alloc); +void* operator new(std::size_t) throw(std::bad_alloc); // expected-note{{previous declaration}} void* operator new[](std::size_t) throw(std::bad_alloc); -void operator delete(void*) throw(); +void operator delete(void*) throw(); // expected-note{{previous declaration}} void operator delete[](void*) throw(); + +void* operator new(std::size_t); // expected-warning{{'operator new' is missing exception specification 'throw(std::bad_alloc)'}} +void operator delete(void*); // expected-warning{{'operator delete' is missing exception specification 'throw()'}} diff --git a/test/CXX/class.access/class.access.base/p5.cpp b/test/CXX/class.access/class.access.base/p5.cpp new file mode 100644 index 0000000..96037e7 --- /dev/null +++ b/test/CXX/class.access/class.access.base/p5.cpp @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -faccess-control -verify %s + +namespace test0 { + struct A { + static int x; + }; + struct B : A {}; + struct C : B {}; + + int test() { + return A::x + + B::x + + C::x; + } +} + +namespace test1 { + struct A { + private: static int x; // expected-note 5 {{declared private here}} + static int test() { return x; } + }; + struct B : public A { + static int test() { return x; } // expected-error {{private member}} + }; + struct C : private A { + static int test() { return x; } // expected-error {{private member}} + }; + + struct D { + public: static int x; + static int test() { return x; } + }; + struct E : private D { // expected-note{{constrained by private inheritance}} + static int test() { return x; } + }; + + int test() { + return A::x // expected-error {{private member}} + + B::x // expected-error {{private member}} + + C::x // expected-error {{private member}} + + D::x + + E::x; // expected-error {{private member}} + } +} + +namespace test2 { + class A { + protected: static int x; + }; + + class B : private A {}; // expected-note {{private inheritance}} + class C : private A { + int test(B *b) { + return b->x; // expected-error {{private member}} + } + }; +} + +namespace test3 { + class A { + protected: static int x; + }; + + class B : public A {}; + class C : private A { + int test(B *b) { + // x is accessible at C when named in A. + // A is an accessible base of B at C. + // Therefore this succeeds. + return b->x; + } + }; +} + +// TODO: flesh out these cases diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp index 851cd3d..22266cd 100644 --- a/test/CXX/class.access/class.friend/p1.cpp +++ b/test/CXX/class.access/class.friend/p1.cpp @@ -149,3 +149,46 @@ namespace test2 { // expected-error {{'getNext' is a private member of 'test2::ilist_node'}} }; } + +namespace test3 { + class A { protected: int x; }; // expected-note {{declared protected here}} + + class B : public A { + friend int foo(B*); + }; + + int foo(B *p) { + return p->x; + } + + int foo(const B *p) { + return p->x; // expected-error {{'x' is a protected member of 'test3::A'}} + } +} + +namespace test3a { + class A { protected: int x; }; + + class B : public A { + friend int foo(B*); + }; + + int foo(B * const p) { + return p->x; + } +} + +namespace test4 { + template class Holder { + T object; + friend bool operator==(Holder &a, Holder &b) { + return a.object == b.object; // expected-error {{invalid operands to binary expression}} + } + }; + + struct Inequal {}; + bool test() { + Holder a, b; + return a == b; // expected-note {{requested here}} + } +} diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp index bc69bee..3bbdbab8 100644 --- a/test/CXX/class.access/p4.cpp +++ b/test/CXX/class.access/p4.cpp @@ -101,14 +101,14 @@ namespace test2 { namespace test3 { class A { private: - ~A(); // expected-note 3 {{declared private here}} + ~A(); // expected-note 2 {{declared private here}} static A foo; }; A a; // expected-error {{variable of type 'test3::A' has private destructor}} A A::foo; - void foo(A param) { // expected-error {{variable of type 'test3::A' has private destructor}} + void foo(A param) { // okay A local; // expected-error {{variable of type 'test3::A' has private destructor}} } @@ -262,3 +262,68 @@ namespace test9 { static int getX() { return x; } // expected-error {{'x' is a private member of 'test9::A'}} }; } + +namespace test10 { + class A { + enum { + value = 10 // expected-note {{declared private here}} + }; + friend class C; + }; + + class B { + enum { + value = A::value // expected-error {{'value' is a private member of 'test10::A'}} + }; + }; + + class C { + enum { + value = A::value + }; + }; +} + +namespace test11 { + class A { + protected: virtual ~A(); + }; + + class B : public A { + ~B(); + }; + + B::~B() {}; +} + +namespace test12 { + class A { + int x; + + void foo() { + class Local { + int foo(A *a) { + return a->x; + } + }; + } + }; +} + +namespace test13 { + struct A { + int x; + unsigned foo() const; + }; + + struct B : protected A { + using A::foo; + using A::x; + }; + + void test() { + A *d; + d->foo(); + (void) d->x; + } +} diff --git a/test/CXX/class.derived/class.abstract/p4.cpp b/test/CXX/class.derived/class.abstract/p4.cpp new file mode 100644 index 0000000..ca99bf7 --- /dev/null +++ b/test/CXX/class.derived/class.abstract/p4.cpp @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace PR6631 { + struct A { + virtual void f() = 0; + }; + + struct B : virtual A { }; + + struct C : virtual A { + virtual void f(); + }; + + struct D : public B, public C { + virtual void f(); + }; + + void f() { + (void)new D; // okay + } +} + +// Check cases where we have a virtual function that is pure in one +// subobject but not pure in another subobject. +namespace PartlyPure { + struct A { + virtual void f() = 0; // expected-note{{pure virtual function}} + }; + + struct B : A { + virtual void f(); + }; + + struct C : virtual A { }; + + struct D : B, C { }; + + void f() { + (void) new D; // expected-error{{abstract type}} + } +} + +namespace NonPureAlongOnePath { + struct A { + virtual void f() = 0; + }; + + struct B : virtual A { + virtual void f(); + }; + + struct C : virtual A { }; + + struct D : B, C { }; + + void f() { + (void) new D; // okay + } +} + +namespace NonPureAlongOnePath2 { + struct Aprime { + virtual void f() = 0; + }; + + struct A : Aprime { + }; + + struct B : virtual A { + virtual void f(); + }; + + struct C : virtual A { }; + + struct D : B, C { }; + + void f() { + (void) new D; // okay + } +} diff --git a/test/CXX/class.derived/class.abstract/p5.cpp b/test/CXX/class.derived/class.abstract/p5.cpp new file mode 100644 index 0000000..207519d --- /dev/null +++ b/test/CXX/class.derived/class.abstract/p5.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A { + virtual void f() = 0; // expected-note{{pure virtual function}} +}; + +struct B : A { + virtual void f(); +}; + +struct C : B { + virtual void f() = 0; // expected-note 2{{pure virtual function}} +}; + +struct D : C { +}; + +void test() { + (void)new A; // expected-error{{object of abstract type}} + (void)new B; + (void)new C; // expected-error{{object of abstract type}} + (void)new D; // expected-error{{object of abstract type}} +} diff --git a/test/CXX/class.derived/class.virtual/p2.cpp b/test/CXX/class.derived/class.virtual/p2.cpp new file mode 100644 index 0000000..64d93c8 --- /dev/null +++ b/test/CXX/class.derived/class.virtual/p2.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct A { + virtual void f() = 0; // expected-note 2{{overridden virtual function}} +}; + +struct Aprime : virtual A { + virtual void f(); +}; + +struct B : Aprime { + virtual void f(); // expected-note 3{{final overrider of 'A::f'}} +}; + +struct C : virtual A { + virtual void f(); // expected-note{{final overrider of 'A::f'}} +}; + +struct D : B, C { }; // expected-error{{virtual function 'A::f' has more than one final overrider in 'D'}} + +struct B2 : B { }; + +struct E : B, B2 { }; //expected-error{{virtual function 'A::f' has more than one final overrider in 'E'}} + +struct F : B, B2 { + virtual void f(); // okay +}; + +struct G : F { }; // okay + +struct H : G, A { }; // okay + +namespace MultipleSubobjects { + struct A { virtual void f(); }; + struct B : A { virtual void f(); }; + struct C : A { virtual void f(); }; + struct D : B, C { }; // okay +} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp index 935f576..89e9c89 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s // We have to avoid ADL for this test. @@ -65,3 +65,44 @@ namespace Test1 { b _2 = B::b(); } } + +namespace test2 { + class A { + protected: + operator int(); + operator bool(); + }; + + class B : private A { + protected: + using A::operator int; // expected-note {{'declared protected here'}} + public: + using A::operator bool; + }; + + int test() { + bool b = B(); + return B(); // expected-error {{'operator int' is a protected member of 'test2::B'}} + } +} + +namespace test3 { + class A { + ~A(); + }; + + class B { + friend class C; + private: + operator A*(); + }; + + class C : public B { + public: + using B::operator A*; + }; + + void test() { + delete C(); + } +} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp index 392888e..c530311 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp @@ -25,8 +25,7 @@ template <> class B { }; template <> struct B { - // FIXME: the error here should be associated with the use at "void foo..." - union Member { // expected-note 4 {{previous use is here}} expected-error {{tag type that does not match previous declaration}} + union Member { // expected-note 4 {{previous use is here}} void* a; }; }; @@ -41,10 +40,10 @@ void c2(class B::Member); void c3(union B::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} void c4(enum B::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} -void d1(struct B::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} -void d2(class B::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} -void d3(union B::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} -void d4(enum B::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} +void d1(struct B::Member); // expected-error {{no struct named 'Member' in 'B'}} +void d2(class B::Member); // expected-error {{no class named 'Member' in 'B'}} +void d3(union B::Member); // expected-error {{no union named 'Member' in 'B'}} +void d4(enum B::Member); // expected-error {{no enum named 'Member' in 'B'}} void e1(struct B::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} void e2(class B::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} @@ -52,7 +51,8 @@ void e3(union B::Member); void e4(enum B::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} template struct C { - void foo(class B::Member); // expected-error{{no type named 'Member' in 'B'}} + void foo(class B::Member); // expected-error{{no class named 'Member' in 'B'}} \ + // expected-error{{use of 'Member' with tag type that does not match previous declaration}} }; C f1; diff --git a/test/CXX/stmt.stmt/stmt.select/p3.cpp b/test/CXX/stmt.stmt/stmt.select/p3.cpp new file mode 100644 index 0000000..e674f97 --- /dev/null +++ b/test/CXX/stmt.stmt/stmt.select/p3.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int f(); + +void g() { + if (int x = f()) { // expected-note 2{{previous definition}} + int x; // expected-error{{redefinition of 'x'}} + } else { + int x; // expected-error{{redefinition of 'x'}} + } +} diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp index 83365a2..14dace8 100644 --- a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp +++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp @@ -49,9 +49,9 @@ namespace addr_of_obj_or_func { // -- a pointer to member expressed as described in 5.3.1. namespace bad_args { - template struct X0 { }; + template struct X0 { }; // expected-note 2{{template parameter is declared here}} int i = 42; X0<&i + 2> x0a; // expected-error{{non-type template argument does not refer to any declaration}} int* iptr = &i; - X0 x0b; // FIXME: This should not be accepted. + X0 x0b; // expected-error{{non-type template argument for template parameter of pointer type 'int *' must have its address taken}} } diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp index 458aff2..b0f1c46 100644 --- a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp +++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp @@ -7,6 +7,14 @@ // program is ill-formed. // -- for a non-type template-parameter of integral or enumeration type, // integral promotions (4.5) and integral conversions (4.7) are applied. +namespace integral_parameters { + template struct X0 { }; + X0<17> x0i; + X0<'a'> x0c; + template struct X1 { }; + X1<100l> x1l; +} + // -- for a non-type template-parameter of type pointer to object, // qualification conversions (4.4) and the array-to-pointer conversion // (4.2) are applied; if the template-argument is of type @@ -37,12 +45,12 @@ namespace pointer_to_object_parameters { operator int() const; }; - template struct A2; + template struct A2; // expected-note{{template parameter is declared here}} X *X_ptr; X an_X; X array_of_Xs[10]; - A2 *a12; + A2 *a12; // expected-error{{must have its address taken}} A2 *a13; A2<&an_X> *a13_2; A2<(&an_X)> *a13_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}} @@ -52,6 +60,16 @@ namespace pointer_to_object_parameters { template struct X2 { }; template struct X3 : X2 { }; struct X4 : X3<&X1v> { }; + + // PR6563 + int *bar; + template struct zed {}; // expected-note 2{{template parameter is declared here}} + void g(zed*); // expected-error{{must have its address taken}} + + int baz; + void g2(zed*); // expected-error{{must have its address taken}} + + void g3(zed<&baz>*); // okay } // -- For a non-type template-parameter of type reference to object, no @@ -105,6 +123,12 @@ namespace reference_parameters { bind(); // expected-note{{instantiation of}} } } + + namespace PR6749 { + template struct foo {}; // expected-note{{template parameter is declared here}} + int x, &y = x; + foo f; // expected-error{{is not an object}} + } } // -- For a non-type template-parameter of type pointer to function, the @@ -113,17 +137,69 @@ namespace reference_parameters { // conversion (4.10) is applied. If the template-argument represents // a set of overloaded functions (or a pointer to such), the matching // function is selected from the set (13.4). +namespace pointer_to_function { + template struct X0 { }; // expected-note 3{{template parameter is declared here}} + int f(int); + int f(float); + int g(float); + int (*funcptr)(int); + void x0a(X0); + void x0b(X0<&f>); + void x0c(X0); // expected-error{{non-type template argument of type 'int (float)' cannot be converted to a value of type 'int (*)(int)'}} + void x0d(X0<&g>); // expected-error{{non-type template argument of type 'int (*)(float)' cannot be converted to a value of type 'int (*)(int)'}} + void x0e(X0); // expected-error{{must have its address taken}} +} + // -- For a non-type template-parameter of type reference to function, no // conversions apply. If the template-argument represents a set of // overloaded functions, the matching function is selected from the set // (13.4). +namespace reference_to_function { + template struct X0 { }; // expected-note 4{{template parameter is declared here}} + int f(int); + int f(float); + int g(float); + int (*funcptr)(int); + void x0a(X0); + void x0b(X0<&f>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}} + void x0c(X0); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (float)'}} + void x0d(X0<&g>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}} + void x0e(X0); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (*)(int)'}} +} // -- For a non-type template-parameter of type pointer to member function, // if the template-argument is of type std::nullptr_t, the null member // pointer conversion (4.11) is applied; otherwise, no conversions // apply. If the template-argument represents a set of overloaded member // functions, the matching member function is selected from the set // (13.4). +namespace pointer_to_member_function { + struct X { }; + struct Y : X { + int f(int); + int g(int); + int g(float); + float h(float); + }; + + template struct X0 {}; // expected-note{{template parameter is declared here}} + X0<&Y::f> x0a; + X0<&Y::g> x0b; + X0<&Y::h> x0c; // expected-error{{non-type template argument of type 'float (pointer_to_member_function::Y::*)(float)' cannot be converted to a value of type 'int (pointer_to_member_function::Y::*)(int)'}} +} + // -- For a non-type template-parameter of type pointer to data member, // qualification conversions (4.4) are applied; if the template-argument // is of type std::nullptr_t, the null member pointer conversion (4.11) // is applied. +namespace pointer_to_member_data { + struct X { int x; }; + struct Y : X { int y; }; + + template struct X0 {}; // expected-note{{template parameter is declared here}} + X0<&Y::y> x0a; + X0<&Y::x> x0b; // expected-error{{non-type template argument of type 'int pointer_to_member_data::X::*' cannot be converted to a value of type 'int pointer_to_member_data::Y::*'}} + + // Test qualification conversions + template struct X1 {}; + X1<&Y::y> x1a; +} diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp index f1b3c81..c9dc546 100644 --- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp +++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -faccess-control -verify -emit-llvm-only %s +namespace test0 { template struct Num { T value_; @@ -54,6 +55,7 @@ int calc2() { Num result = x * n; return result.get(); } +} // Reduced from GNU namespace test1 { @@ -85,3 +87,132 @@ namespace test2 { } }; } + +namespace test3 { + class Bool; + template class User; + template T transform(class Bool, T); + + class Bool { + friend class User; + friend bool transform<>(Bool, bool); + + bool value; // expected-note 2 {{declared private here}} + }; + + template class User { + static T compute(Bool b) { + return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}} + } + }; + + template T transform(Bool b, T value) { + if (b.value) // expected-error {{'value' is a private member of 'test3::Bool'}} + return value; + return value + 1; + } + + template bool transform(Bool, bool); + template int transform(Bool, int); // expected-note {{requested here}} + + template class User; + template class User; // expected-note {{requested here}} +} + +namespace test4 { + template class A { + template friend class B; + bool foo(const A *) const; + }; + + template class B { + bool bar(const A *a, const A *b) { + return a->foo(b); + } + }; + + template class B; +} + +namespace test5 { + template class A {}; + template class B { + template friend class A; + }; + template class B; + template class A; +} + +namespace Dependent { + template class X; + template + X operator+(const X&, const T*); + + template class X { + typedef typename Traits::value_type value_type; + friend X operator+<>(const X&, const value_type*); + }; +} + +namespace test7 { + template class A { // expected-note {{previous definition is here}} + friend class B; + int x; // expected-note {{declared private here}} + }; + + class B { + int foo(A &a) { + return a.x; + } + }; + + class C { + int foo(A &a) { + return a.x; // expected-error {{'x' is a private member of 'test7::A'}} + } + }; + + // This shouldn't crash. + template class D { + friend class A; // expected-error {{redefinition of 'A' as different kind of symbol}} + }; + template class D; +} + +namespace test8 { + template class A { + static int x; + template friend void foo(); + }; + template class A; + + template void foo() { + A::x = 0; + } + template void foo(); +} + +namespace test9 { + template class A { + class B; class C; + + int foo(B *b) { + return b->x; + } + + int foo(C *c) { + return c->x; // expected-error {{'x' is a private member}} + } + + class B { + int x; + friend int A::foo(B*); + }; + + class C { + int x; // expected-note {{declared private here}} + }; + }; + + template class A; // expected-note {{in instantiation}} +} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp new file mode 100644 index 0000000..c27261c --- /dev/null +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template int f(int); // expected-note 2{{candidate}} +template int f(int); // expected-note 2{{candidate}} +int i1 = f<1>(0); // expected-error{{ambiguous}} +int i2 = f<1000>(0); // expected-error{{ambiguous}} + +namespace PR6707 { + template + struct X { }; + + template + void f(X); + + void g(X x) { + f(x); + } + + static const unsigned char ten = 10; + template + void f2(X, X); + + void g2() { + f2(X(), X()); + } +} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp new file mode 100644 index 0000000..2a7f16d --- /dev/null +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template class A { }; +template void f(A); // expected-note{{failed template argument deduction}} + +void k1() { + A<1> a; + f(a); // expected-error{{no matching function for call}} + f<1>(a); +} +template class B { }; +template void g(B); +void k2() { + B<1> b; + g(b); // OK: cv-qualifiers are ignored on template parameter types +} + +template void h(int (&)[s]); // expected-note{{failed template argument deduction}} +void k3() { + int array[5]; + h(array); + h<5>(array); +} + +template void h(int (&)[s], A); // expected-note{{failed template argument deduction}} +void k4() { + A<5> a; + int array[5]; + h(array, a); // expected-error{{no matching function for call}} + h<5>(array, a); +} diff --git a/test/CXX/temp/temp.res/temp.local/p1.cpp b/test/CXX/temp/temp.res/temp.local/p1.cpp index ed534a4..1ad4464 100644 --- a/test/CXX/temp/temp.res/temp.local/p1.cpp +++ b/test/CXX/temp/temp.res/temp.local/p1.cpp @@ -26,8 +26,7 @@ template struct X1 { // FIXME: Test this clause. int i = 42; -int* iptr = &i; void test() { X0 x0; (void)x0; - X1<42, i, iptr> x1; (void)x1; + X1<42, i, &i> x1; (void)x1; } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp index f987c12..86cdcf8 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp @@ -6,7 +6,7 @@ template struct A { }; struct X { - template<> friend void f(int); // expected-error{{in class scope}} + template<> friend void f(int); // expected-error{{in a friend}} template<> friend class A; // expected-error{{cannot be a friend}} friend void f(float); // okay diff --git a/test/CodeGen/atomic.c b/test/CodeGen/atomic.c index c201a1a..aa5aa15 100644 --- a/test/CodeGen/atomic.c +++ b/test/CodeGen/atomic.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 > %t1 -// RUN: grep @llvm.memory.barrier %t1 | count 42 +// RUN: grep @llvm.memory.barrier %t1 | count 38 // RUN: grep @llvm.atomic.load.add.i32 %t1 | count 3 // RUN: grep @llvm.atomic.load.sub.i8 %t1 | count 2 // RUN: grep @llvm.atomic.load.min.i32 %t1 @@ -8,7 +8,7 @@ // RUN: grep @llvm.atomic.load.umax.i32 %t1 // RUN: grep @llvm.atomic.swap.i32 %t1 // RUN: grep @llvm.atomic.cmp.swap.i32 %t1 | count 4 -// RUN: grep @llvm.atomic.load.and.i32 %t1 | count 2 +// RUN: grep @llvm.atomic.load.and.i32 %t1 // RUN: grep @llvm.atomic.load.or.i8 %t1 // RUN: grep @llvm.atomic.load.xor.i8 %t1 @@ -34,14 +34,12 @@ int atomic(void) old = __sync_fetch_and_and(&val, 0x9); old = __sync_fetch_and_or(&val, 0xa); old = __sync_fetch_and_xor(&val, 0xb); - old = __sync_fetch_and_nand(&val, 0xb); old = __sync_add_and_fetch(&val, 1); old = __sync_sub_and_fetch(&val, 2); old = __sync_and_and_fetch(&valc, 3); old = __sync_or_and_fetch(&valc, 4); old = __sync_xor_and_fetch(&valc, 5); - old = __sync_nand_and_fetch(&valc, 5); __sync_val_compare_and_swap((void **)0, (void *)0, (void *)0); diff --git a/test/CodeGen/mangle.c b/test/CodeGen/mangle.c index a087b42..93d424a 100644 --- a/test/CodeGen/mangle.c +++ b/test/CodeGen/mangle.c @@ -59,3 +59,7 @@ extern int func (void) __asm__ ("FUNC"); int func(void) { return 42; } + +// CHECK: @_Z4foo9Dv4_f +typedef __attribute__(( vector_size(16) )) float float4; +void __attribute__((__overloadable__)) foo9(float4 f) {} diff --git a/test/CodeGen/palignr.c b/test/CodeGen/palignr.c index 68efb41..627e309 100644 --- a/test/CodeGen/palignr.c +++ b/test/CodeGen/palignr.c @@ -15,5 +15,5 @@ int4 align1(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 15); } int4 align2(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 16); } // CHECK: psrldq int4 align3(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 17); } -// CHECK: xorps +// CHECK: xor int4 align4(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 32); } diff --git a/test/CodeGen/regparm.c b/test/CodeGen/regparm.c index ac37975..b60f8c7 100644 --- a/test/CodeGen/regparm.c +++ b/test/CodeGen/regparm.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | grep inreg | count 2 +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s #define FASTCALL __attribute__((regparm(2))) @@ -8,11 +8,16 @@ typedef struct { int ccc[200]; } foo; +typedef void (*FType)(int, int) __attribute ((regparm (3), stdcall)); +FType bar; + static void FASTCALL -reduced(char b, double c, foo* d, double e, int f) { -} +reduced(char b, double c, foo* d, double e, int f); int main(void) { + // CHECK: call void @reduced(i8 signext inreg 0, {{.*}} %struct.anon* inreg null reduced(0, 0.0, 0, 0.0, 0); + // CHECK: call x86_stdcallcc void {{.*}}(i32 inreg 1, i32 inreg 2) + bar(1,2); } diff --git a/test/CodeGen/restrict.c b/test/CodeGen/restrict.c new file mode 100644 index 0000000..8bbff24 --- /dev/null +++ b/test/CodeGen/restrict.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple x86_64-darwin-apple -emit-llvm %s -o - | FileCheck %s + +// PR6695 + +// CHECK: define void @test0(i32* %{{.*}}, i32 %{{.*}}) +void test0(int *x, int y) { +} + +// CHECK: define void @test1(i32* noalias %{{.*}}, i32 %{{.*}}) +void test1(int * restrict x, int y) { +} + +// CHECK: define void @test2(i32* %{{.*}}, i32* noalias %{{.*}}) +void test2(int *x, int * restrict y) { +} + +typedef int * restrict rp; + +// CHECK: define void @test3(i32* noalias %{{.*}}, i32 %{{.*}}) +void test3(rp x, int y) { +} + +// CHECK: define void @test4(i32* %{{.*}}, i32* noalias %{{.*}}) +void test4(int *x, rp y) { +} + diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp index a0a35fa..284b8b5 100644 --- a/test/CodeGenCXX/constructor-init.cpp +++ b/test/CodeGenCXX/constructor-init.cpp @@ -80,3 +80,24 @@ void f() { // CHECK-NOT: call void @_ZN1AIsED1Ev // CHECK: ret void } + +template +struct X { + X(const X &); + + T *start; + T *end; +}; + +template struct X; + +// Make sure that the instantiated constructor initializes start and +// end properly. +// CHECK: define linkonce_odr void @_ZN1XIiEC2ERKS0_ +// CHECK: {{store.*null}} +// CHECK: {{store.*null}} +// CHECK: ret +template +X::X(const X &other) : start(0), end(0) { } + +X get_X(X x) { return x; } diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp index ae8eefa..9cafd0a 100644 --- a/test/CodeGenCXX/copy-constructor-synthesis.cpp +++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp @@ -1,7 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s -// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s -// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s extern "C" int printf(...); @@ -24,6 +21,7 @@ struct P { }; +// CHECK: define linkonce_odr void @_ZN1XC1ERKS_ struct X : M, N, P { // ... X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd), au_i1(1234), au1_4("MASKED") {} @@ -113,10 +111,46 @@ void f(const B &b1) { B b2(b1); } -// CHECK-LP64: .globl __ZN1XC1ERKS_ -// CHECK-LP64: .weak_definition __ZN1XC1ERKS_ -// CHECK-LP64: __ZN1XC1ERKS_: +// PR6628 +namespace PR6628 { + +struct T { + T(); + ~T(); + + double d; +}; + +struct A { + A(const A &other, const T &t = T(), const T& t2 = T()); +}; + +struct B : A { + A a1; + A a2; + A a[10]; +}; + +// Force the copy constructor to be synthesized. +void f(B b1) { + B b2 = b1; +} + +// CHECK: define linkonce_odr void @_ZN6PR66281BC2ERKS0_ +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281AC2ERKS0_RKNS_1TES5_ +// CHECK: call void @_ZN6PR66281TD1Ev +// CHECK: call void @_ZN6PR66281TD1Ev +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_ +// CHECK: call void @_ZN6PR66281TD1Ev +// CHECK: call void @_ZN6PR66281TD1Ev +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_ +// CHECK: call void @_ZN6PR66281TD1Ev +// CHECK: call void @_ZN6PR66281TD1Ev +} -// CHECK-LP32: .globl __ZN1XC1ERKS_ -// CHECK-LP32: .weak_definition __ZN1XC1ERKS_ -// CHECK-LP32: __ZN1XC1ERKS_: diff --git a/test/CodeGenCXX/member-expressions.cpp b/test/CodeGenCXX/member-expressions.cpp index 720a9a7..d9fb394 100644 --- a/test/CodeGenCXX/member-expressions.cpp +++ b/test/CodeGenCXX/member-expressions.cpp @@ -44,3 +44,43 @@ int f() { return A().foo(); } } + +namespace test4 { + struct A { + int x; + }; + struct B { + int x; + void foo(); + }; + struct C : A, B { + }; + + extern C *c_ptr; + + // CHECK: define i32 @_ZN5test44testEv() + int test() { + // CHECK: load {{.*}} @_ZN5test45c_ptrE + // CHECK-NEXT: bitcast + // CHECK-NEXT: getelementptr + // CHECK-NEXT: bitcast + // CHECK-NEXT: call void @_ZN5test41B3fooEv + c_ptr->B::foo(); + + // CHECK: load {{.*}} @_ZN5test45c_ptrE + // CHECK-NEXT: bitcast + // CHECK-NEXT: getelementptr + // CHECK-NEXT: bitcast + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store i32 5 + c_ptr->B::x = 5; + + // CHECK: load {{.*}} @_ZN5test45c_ptrE + // CHECK-NEXT: bitcast + // CHECK-NEXT: getelementptr + // CHECK-NEXT: bitcast + // CHECK-NEXT: getelementptr + // CHECK-NEXT: load i32* + return c_ptr->B::x; + } +} diff --git a/test/CodeGenCXX/multi-dim-operator-new.cpp b/test/CodeGenCXX/multi-dim-operator-new.cpp new file mode 100644 index 0000000..7a235e8 --- /dev/null +++ b/test/CodeGenCXX/multi-dim-operator-new.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 %s -triple x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s +// PR6641 + +extern "C" int printf(const char *, ...); + +struct Foo { + Foo() : iFoo (2) { + printf("%p\n", this); + } + int iFoo; +}; + + +typedef Foo (*T)[3][4]; + +T bar() { + return new Foo[2][3][4]; +} + +T bug(int i) { + return new Foo[i][3][4]; +} + +void pr(T a) { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 4; j++) + printf("%p\n", a[i][j]); +} + +Foo *test() { + return new Foo[5]; +} + +int main() { + T f = bar(); + pr(f); + f = bug(3); + pr(f); + + Foo * g = test(); + for (int i = 0; i < 5; i++) + printf("%d\n", g[i].iFoo); + return 0; +} + +// CHECK: call noalias i8* @_Znam +// CHECK: call noalias i8* @_Znam +// CHECK: call noalias i8* @_Znam + diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp index 39b5909..5a5947d 100644 --- a/test/CodeGenCXX/references.cpp +++ b/test/CodeGenCXX/references.cpp @@ -147,3 +147,11 @@ void f(int &a) { struct s0; struct s1 { struct s0 &s0; }; void f0(s1 a) { s1 b = a; } + +// PR6024 +// CHECK: @_Z2f2v() +// CHECK: alloca +// CHECK: store +// CHECK: load +// CHECK: ret +const int &f2() { return 0; } diff --git a/test/CodeGenCXX/rtti-fundamental.cpp b/test/CodeGenCXX/rtti-fundamental.cpp new file mode 100644 index 0000000..473f48d --- /dev/null +++ b/test/CodeGenCXX/rtti-fundamental.cpp @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +#include + +std::type_info foo() { + return typeid(void); +} + +namespace __cxxabiv1 { + struct __fundamental_type_info { + virtual ~__fundamental_type_info() {} + }; +} + +// CHECK: @_ZTIv = weak_odr constant +// CHECK: @_ZTIPv = weak_odr constant +// CHECK: @_ZTIPKv = weak_odr constant +// CHECK: @_ZTIDi = weak_odr constant +// CHECK: @_ZTIPDi = weak_odr constant +// CHECK: @_ZTIPKDi = weak_odr constant +// CHECK: @_ZTIDs = weak_odr constant +// CHECK: @_ZTIPDs = weak_odr constant +// CHECK: @_ZTIPKDs = weak_odr constant +// CHECK: @_ZTIy = weak_odr constant +// CHECK: @_ZTIPy = weak_odr constant +// CHECK: @_ZTIPKy = weak_odr constant +// CHECK: @_ZTIx = weak_odr constant +// CHECK: @_ZTIPx = weak_odr constant +// CHECK: @_ZTIPKx = weak_odr constant +// CHECK: @_ZTIw = weak_odr constant +// CHECK: @_ZTIPw = weak_odr constant +// CHECK: @_ZTIPKw = weak_odr constant +// CHECK: @_ZTIt = weak_odr constant +// CHECK: @_ZTIPt = weak_odr constant +// CHECK: @_ZTIPKt = weak_odr constant +// CHECK: @_ZTIs = weak_odr constant +// CHECK: @_ZTIPs = weak_odr constant +// CHECK: @_ZTIPKs = weak_odr constant +// CHECK: @_ZTIm = weak_odr constant +// CHECK: @_ZTIPm = weak_odr constant +// CHECK: @_ZTIPKm = weak_odr constant +// CHECK: @_ZTIl = weak_odr constant +// CHECK: @_ZTIPl = weak_odr constant +// CHECK: @_ZTIPKl = weak_odr constant +// CHECK: @_ZTIj = weak_odr constant +// CHECK: @_ZTIPj = weak_odr constant +// CHECK: @_ZTIPKj = weak_odr constant +// CHECK: @_ZTIi = weak_odr constant +// CHECK: @_ZTIPi = weak_odr constant +// CHECK: @_ZTIPKi = weak_odr constant +// CHECK: @_ZTIh = weak_odr constant +// CHECK: @_ZTIPh = weak_odr constant +// CHECK: @_ZTIPKh = weak_odr constant +// CHECK: @_ZTIf = weak_odr constant +// CHECK: @_ZTIPf = weak_odr constant +// CHECK: @_ZTIPKf = weak_odr constant +// CHECK: @_ZTIe = weak_odr constant +// CHECK: @_ZTIPe = weak_odr constant +// CHECK: @_ZTIPKe = weak_odr constant +// CHECK: @_ZTId = weak_odr constant +// CHECK: @_ZTIPd = weak_odr constant +// CHECK: @_ZTIPKd = weak_odr constant +// CHECK: @_ZTIc = weak_odr constant +// CHECK: @_ZTIPc = weak_odr constant +// CHECK: @_ZTIPKc = weak_odr constant +// CHECK: @_ZTIb = weak_odr constant +// CHECK: @_ZTIPb = weak_odr constant +// CHECK: @_ZTIPKb = weak_odr constant +// CHECK: @_ZTIa = weak_odr constant +// CHECK: @_ZTIPa = weak_odr constant +// CHECK: @_ZTIPKa = weak_odr constant diff --git a/test/CodeGenCXX/rtti-linkage.cpp b/test/CodeGenCXX/rtti-linkage.cpp index 799c1d4..b9eb5b4 100644 --- a/test/CodeGenCXX/rtti-linkage.cpp +++ b/test/CodeGenCXX/rtti-linkage.cpp @@ -92,6 +92,7 @@ const std::type_info &t2() { (void)typeid(D *); (void)typeid(D (*)()); (void)typeid(void (*)(D)); + (void)typeid(void (*)(D&)); // The exception specification is not part of the RTTI descriptor, so it should not have // internal linkage. (void)typeid(void (*)() throw (D)); diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp new file mode 100644 index 0000000..416c0a1 --- /dev/null +++ b/test/CodeGenCXX/template-instantiation.cpp @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +// CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant +// CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE +// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = constant + +// CHECK: define linkonce_odr void @_ZN5test21CIiEC1Ev( +// CHECK: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_( +// CHECK: define available_externally void @_ZN5test21CIiE6zedbarEd( + +namespace test0 { + struct basic_streambuf { + virtual ~basic_streambuf(); + }; + template + struct stdio_sync_filebuf : public basic_streambuf { + virtual void xsgetn(); + }; + + // This specialization should cause the vtable to be emitted, even with + // the following extern template declaration. + template<> void stdio_sync_filebuf::xsgetn() { + } + extern template class stdio_sync_filebuf; +} + +namespace test1 { + struct basic_streambuf { + virtual ~basic_streambuf(); + }; + template + struct stdio_sync_filebuf : public basic_streambuf { + virtual void xsgetn(); + }; + + // Just a declaration should not force the vtable to be emitted. + template<> void stdio_sync_filebuf::xsgetn(); +} + +namespace test2 { + template + class C { + virtual ~C(); + void zedbar(double) { + } + template + void foobar(T2 foo) { + } + }; + extern template class C; + void g() { + // The extern template declaration should not prevent us from producing + // the implicit constructor (test at the top). + C a; + + // or foobar(test at the top). + a.foobar(0.0); + + // But it should prevent zebbar + // (test at the top). + a.zedbar(0.0); + } +} + +namespace test3 { + template + class basic_fstreamXX { + virtual void foo(){} + virtual void is_open() const { } + }; + + extern template class basic_fstreamXX; + // This template instantiation should not cause us to produce a vtable. + // (test at the top). + template void basic_fstreamXX::is_open() const; +} diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp index cd0cf77..4aad3c0 100644 --- a/test/CodeGenCXX/temporaries.cpp +++ b/test/CodeGenCXX/temporaries.cpp @@ -288,3 +288,16 @@ void g() { } } + +namespace PR6648 { + struct B { + ~B(); + }; + B foo; + struct D; + D& zed(B); + void foobar() { + // CHECK: call %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE + zed(foo); + } +} diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp new file mode 100644 index 0000000..b91ba32 --- /dev/null +++ b/test/CodeGenCXX/thunks.cpp @@ -0,0 +1,137 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +namespace Test1 { + +// Check that we emit a non-virtual thunk for C::f. + +struct A { + virtual void f(); +}; + +struct B { + virtual void f(); +}; + +struct C : A, B { + virtual void c(); + + virtual void f(); +}; + +// CHECK: define void @_ZThn8_N5Test11C1fEv( +void C::f() { } + +} + +namespace Test2 { + +// Check that we emit a thunk for B::f since it's overriding a virtual base. + +struct A { + virtual void f(); +}; + +struct B : virtual A { + virtual void b(); + virtual void f(); +}; + +// CHECK: define void @_ZTv0_n24_N5Test21B1fEv( +void B::f() { } + +} + +namespace Test3 { + +// Check that we emit a covariant thunk for B::f. + +struct V1 { }; +struct V2 : virtual V1 { }; + +struct A { + virtual V1 *f(); +}; + +struct B : A { + virtual void b(); + + virtual V2 *f(); +}; + +// CHECK: define %{{.*}}* @_ZTch0_v0_n24_N5Test31B1fEv( +V2 *B::f() { return 0; } + +} + +namespace Test4 { + +// Check that the thunk for 'C::f' has the same visibility as the function itself. + +struct A { + virtual void f(); +}; + +struct B { + virtual void f(); +}; + +struct __attribute__((visibility("protected"))) C : A, B { + virtual void c(); + + virtual void f(); +}; + +// CHECK: define protected void @_ZThn8_N5Test41C1fEv( +void C::f() { } + +} + +// This is from Test5: +// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv + +// Check that the thunk gets internal linkage. +namespace { + +struct A { + virtual void f(); +}; + +struct B { + virtual void f(); +}; + +struct C : A, B { + virtual void c(); + + virtual void f(); +}; + +// CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv( +void C::f() { } + +} + +// Force C::f to be used. +void f() { + C c; + + c.f(); +} + +namespace Test5 { + +// Check that the thunk for 'B::f' gets the same linkage as the function itself. +struct A { + virtual void f(); +}; + +struct B : virtual A { + virtual void f() { } +}; + +void f(B b) { + b.f(); +} +} + + diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp index 9d671c4..c404129 100644 --- a/test/CodeGenCXX/virt.cpp +++ b/test/CodeGenCXX/virt.cpp @@ -693,55 +693,3 @@ void test12_foo() { // CHECK-LPLL64: call void % // CHECK-LPLL64: call void @_ZN8test12_A3fooEv(%class.test14* %{{.*}}) - -// FIXME: This is the wrong thunk, but until these issues are fixed, better -// than nothing. -// CHECK-LPLL64define weak %class.test8_D* @_ZTcvn16_n72_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|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: %{{retval|1}} = alloca %class.test8_D* -// CHECK-LPLL64: %{{.addr|2}} = alloca %class.test8_D* -// CHECK-LPLL64: store %class.test8_D* %0, %class.test8_D** %{{.addr|2}} -// CHECK-LPLL64: %{{this|3}} = load %class.test8_D** %{{.addr|2}} -// 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:;