summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2013-06-06 23:43:20 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2013-06-06 23:43:20 +0000
commit686d33fd62e832795c48573002c77e9910c8c2eb (patch)
treeb3379ed400c829574a41e23a6653be035ae8e6ab
parent96ff4d6d3b7afad3669eb4bed5b9621ffa82490d (diff)
downloadbcm5719-llvm-686d33fd62e832795c48573002c77e9910c8c2eb.tar.gz
bcm5719-llvm-686d33fd62e832795c48573002c77e9910c8c2eb.zip
Implement DR7
Disallowing deriving from classes that have private virtual base classes except in instances where the deriving class would be able to cast itself to the private virtual base via a different derivation. llvm-svn: 183462
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp17
-rw-r--r--clang/test/CXX/drs/dr0xx.cpp9
3 files changed, 20 insertions, 10 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c328e71057e..40ef1ac75ae 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1011,8 +1011,8 @@ def err_access_dtor_base :
Error<"base class %0 has %select{private|protected}1 destructor">,
AccessControl;
def err_access_dtor_vbase :
- Error<"inherited virtual base class %0 has "
- "%select{private|protected}1 destructor">,
+ Error<"inherited virtual base class %1 has "
+ "%select{private|protected}2 destructor">,
AccessControl;
def err_access_dtor_temp :
Error<"temporary of type %0 has %select{private|protected}1 destructor">,
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 573738cedb9..059c3720d67 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -1311,7 +1311,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
assert(BaseDecl && "Record type has no declaration");
BaseDecl = BaseDecl->getDefinition();
assert(BaseDecl && "Base type is not incomplete, but has no definition");
- CXXRecordDecl * CXXBaseDecl = cast<CXXRecordDecl>(BaseDecl);
+ CXXRecordDecl *CXXBaseDecl = cast<CXXRecordDecl>(BaseDecl);
assert(CXXBaseDecl && "Base type is not a C++ type");
// C++ [class]p3:
@@ -3806,10 +3806,17 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl);
assert(Dtor && "No dtor found for BaseClassDecl!");
- CheckDestructorAccess(ClassDecl->getLocation(), Dtor,
- PDiag(diag::err_access_dtor_vbase)
- << VBase->getType(),
- Context.getTypeDeclType(ClassDecl));
+ if (CheckDestructorAccess(
+ ClassDecl->getLocation(), Dtor,
+ PDiag(diag::err_access_dtor_vbase)
+ << Context.getTypeDeclType(ClassDecl) << VBase->getType(),
+ Context.getTypeDeclType(ClassDecl)) ==
+ AR_accessible) {
+ CheckDerivedToBaseConversion(
+ Context.getTypeDeclType(ClassDecl), VBase->getType(),
+ diag::err_access_dtor_vbase, 0, ClassDecl->getLocation(),
+ SourceRange(), DeclarationName(), 0);
+ }
MarkFunctionReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
DiagnoseUseOfDecl(Dtor, Location);
diff --git a/clang/test/CXX/drs/dr0xx.cpp b/clang/test/CXX/drs/dr0xx.cpp
index 4298960426d..7ff199d0b1f 100644
--- a/clang/test/CXX/drs/dr0xx.cpp
+++ b/clang/test/CXX/drs/dr0xx.cpp
@@ -59,10 +59,13 @@ namespace dr5 { // dr5: yes
const C c = e;
}
-namespace dr7 { // dr7: no
+namespace dr7 { // dr7: yes
class A { public: ~A(); };
- class B : virtual private A {};
- class C : public B {} c; // FIXME: should be rejected, ~A is inaccessible
+ class B : virtual private A {}; // expected-note 2 {{declared private here}}
+ class C : public B {} c; // expected-error 2 {{inherited virtual base class 'dr7::A' has private destructor}} \
+ // expected-note {{implicit default constructor for 'dr7::C' first required here}} \
+ // expected-note {{implicit default destructor for 'dr7::C' first required here}}
+ class VeryDerivedC : public B, virtual public A {} vdc;
class X { ~X(); }; // expected-note {{here}}
class Y : X { ~Y() {} }; // expected-error {{private destructor}}
OpenPOWER on IntegriCloud