diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2013-06-06 23:43:20 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2013-06-06 23:43:20 +0000 |
| commit | 686d33fd62e832795c48573002c77e9910c8c2eb (patch) | |
| tree | b3379ed400c829574a41e23a6653be035ae8e6ab | |
| parent | 96ff4d6d3b7afad3669eb4bed5b9621ffa82490d (diff) | |
| download | bcm5719-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.td | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 17 | ||||
| -rw-r--r-- | clang/test/CXX/drs/dr0xx.cpp | 9 |
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}} |

