summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-05-20 02:24:22 +0000
committerDouglas Gregor <dgregor@apple.com>2010-05-20 02:24:22 +0000
commit527786ea3a6a9baf88efbd188fe1cc258e5bda48 (patch)
tree18e77e0548e3ce7f772297b28e0b0fc7f0481f09
parentbd7b3ccbf8d5e6c3ff210c0eedf0a913a5ed90f8 (diff)
downloadbcm5719-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.td4
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp17
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp6
-rw-r--r--clang/lib/Sema/SemaLookup.cpp10
-rw-r--r--clang/test/CodeGenObjCXX/encode.mm3
-rw-r--r--clang/test/SemaCXX/vararg-adl.cpp12
-rw-r--r--clang/test/SemaObjCXX/ivar-construct.mm29
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
OpenPOWER on IntegriCloud