diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-05-20 02:24:22 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-05-20 02:24:22 +0000 |
| commit | 527786ea3a6a9baf88efbd188fe1cc258e5bda48 (patch) | |
| tree | 18e77e0548e3ce7f772297b28e0b0fc7f0481f09 | |
| parent | bd7b3ccbf8d5e6c3ff210c0eedf0a913a5ed90f8 (diff) | |
| download | bcm5719-llvm-527786ea3a6a9baf88efbd188fe1cc258e5bda48.tar.gz bcm5719-llvm-527786ea3a6a9baf88efbd188fe1cc258e5bda48.zip | |
Various small fixes for construction/destruction of Objective-C++
instance variables:
- Use isRecordType() rather than isa<RecordType>(), so that we see
through typedefs in ivar types.
- Mark the destructor as referenced
- Perform C++ access control on the destructor
llvm-svn: 104206
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 17 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 10 | ||||
| -rw-r--r-- | clang/test/CodeGenObjCXX/encode.mm | 3 | ||||
| -rw-r--r-- | clang/test/SemaCXX/vararg-adl.cpp | 12 | ||||
| -rw-r--r-- | clang/test/SemaObjCXX/ivar-construct.mm | 29 |
7 files changed, 75 insertions, 6 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 03c9c0e7e46..4d4ad714795 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -503,6 +503,10 @@ def err_access_copy_field : def err_access_copy_base : Error<"base class %0 has %select{private|protected}1 copy constructor">, NoSFINAE; +def err_access_dtor_ivar : + Error<"instance variable of type %0 has %select{private|protected}1 " + "destructor">, + NoSFINAE; def note_previous_access_declaration : Note< "previously declared '%1' here">; def err_access_outside_class : Error< diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 6682c661167..8cbe92af404 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -6190,6 +6190,9 @@ void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit; for (unsigned i = 0; i < ivars.size(); i++) { FieldDecl *Field = ivars[i]; + if (Field->isInvalidDecl()) + continue; + CXXBaseOrMemberInitializer *Member; InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field); InitializationKind InitKind = @@ -6212,6 +6215,20 @@ void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { MemberInit.takeAs<Expr>(), SourceLocation()); AllToInit.push_back(Member); + + // Be sure that the destructor is accessible and is marked as referenced. + if (const RecordType *RecordTy + = Context.getBaseElementType(Field->getType()) + ->getAs<RecordType>()) { + CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); + if (CXXDestructorDecl *Destructor + = const_cast<CXXDestructorDecl*>(RD->getDestructor(Context))) { + MarkDeclarationReferenced(Field->getLocation(), Destructor); + CheckDestructorAccess(Field->getLocation(), Destructor, + PDiag(diag::err_access_dtor_ivar) + << Context.getBaseElementType(Field->getType())); + } + } } ObjCImplementation->setIvarInitializers(Context, AllToInit.data(), AllToInit.size()); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index b166d873404..ef43c051f7b 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1812,7 +1812,7 @@ void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI, E = OI->ivar_end(); I != E; ++I) { ObjCIvarDecl *Iv = (*I); QualType QT = Context.getBaseElementType(Iv->getType()); - if (isa<RecordType>(QT)) + if (QT->isRecordType()) Ivars.push_back(*I); } @@ -1822,7 +1822,7 @@ void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI, E = CDecl->ivar_end(); I != E; ++I) { ObjCIvarDecl *Iv = (*I); QualType QT = Context.getBaseElementType(Iv->getType()); - if (isa<RecordType>(QT)) + if (QT->isRecordType()) Ivars.push_back(*I); } } @@ -1834,7 +1834,7 @@ void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI, E = ImplDecl->ivar_end(); I != E; ++I) { ObjCIvarDecl *Iv = (*I); QualType QT = Context.getBaseElementType(Iv->getType()); - if (isa<RecordType>(QT)) + if (QT->isRecordType()) Ivars.push_back(*I); } } diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 774a82b7c74..d876e6047e7 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1626,15 +1626,21 @@ addAssociatedClassesAndNamespaces(QualType T, // member, if any; and its direct and indirect base // classes. Its associated namespaces are the namespaces in // which its associated classes are defined. - if (const RecordType *ClassType = T->getAs<RecordType>()) + if (const RecordType *ClassType = T->getAs<RecordType>()) { if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(ClassType->getDecl())) { + // The __builtin_va_list type does not participate in ADL. + if (ClassDecl->getIdentifier() && + ClassDecl->getIdentifier()->isStr("__va_list_tag")) + return; + addAssociatedClassesAndNamespaces(ClassDecl, Context, AssociatedNamespaces, AssociatedClasses); return; } - + } + // -- If T is an enumeration type, its associated namespace is // the namespace in which it is defined. If it is class // member, its associated class is the member’s class; else diff --git a/clang/test/CodeGenObjCXX/encode.mm b/clang/test/CodeGenObjCXX/encode.mm index 4f472caa9cd..83fb31e16d5 100644 --- a/clang/test/CodeGenObjCXX/encode.mm +++ b/clang/test/CodeGenObjCXX/encode.mm @@ -5,7 +5,8 @@ // CHECK: v24@0:816 template <typename T1, typename T2, typename T3> struct vector { - vector(T1,T2,T3); + vector(); + vector(T1,T2,T3); }; typedef vector< float, float, float > vector3f; diff --git a/clang/test/SemaCXX/vararg-adl.cpp b/clang/test/SemaCXX/vararg-adl.cpp new file mode 100644 index 00000000000..10b1b62dedc --- /dev/null +++ b/clang/test/SemaCXX/vararg-adl.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin -verify %s + +// PR6762 +#define a_list __builtin_va_list +extern a_list l; +extern int f (a_list arg); +namespace n { +int f(a_list arguments); +void y() { + f(l); +} +} diff --git a/clang/test/SemaObjCXX/ivar-construct.mm b/clang/test/SemaObjCXX/ivar-construct.mm new file mode 100644 index 00000000000..da066e96597 --- /dev/null +++ b/clang/test/SemaObjCXX/ivar-construct.mm @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct Y { + Y(); + +private: + ~Y(); // expected-note 3{{declared private here}} +}; + +template<typename T> +struct X : T { }; // expected-error 2{{private destructor}} + +struct Z; // expected-note{{forward declaration}} + +@interface A { + X<Y> x; // expected-note{{implicit default destructor}} + Y y; // expected-error{{private destructor}} +} +@end + +@implementation A // expected-note{{implicit default constructor}} +@end + +@interface B { + Z z; // expected-error{{incomplete type}} +} +@end + +@implementation B +@end |

