r183462 - Implement DR7

Richard Smith richard at metafoo.co.uk
Wed Jun 19 14:08:51 PDT 2013


On Thu, Jun 6, 2013 at 4:43 PM, David Majnemer <david.majnemer at gmail.com> wrote:
> Author: majnemer
> Date: Thu Jun  6 18:43:20 2013
> New Revision: 183462
>
> URL: http://llvm.org/viewvc/llvm-project?rev=183462&view=rev
> Log:
> 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.
>
> Modified:
>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>     cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>     cfe/trunk/test/CXX/drs/dr0xx.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=183462&r1=183461&r2=183462&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jun  6 18:43:20 2013
> @@ -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">,
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=183462&r1=183461&r2=183462&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jun  6 18:43:20 2013
> @@ -1311,7 +1311,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *
>    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::MarkBaseAndMemberDestructorsRefere
>
>      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(),

The 0 here is the cause of the regression. Diagnostic 0 just happens
to be diag::err_attribute_not_type_attr, and
CheckDerivedToBaseConversion doesn't check whether it's 0 before
emitting it.

We should probably reserve diagnostic ID 0 and assert if anyone tries
to emit it, because we use it to mean "no diagnostic" in several
places already...

> +          SourceRange(), DeclarationName(), 0);
> +    }
>
>      MarkFunctionReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
>      DiagnoseUseOfDecl(Dtor, Location);
>
> Modified: cfe/trunk/test/CXX/drs/dr0xx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?rev=183462&r1=183461&r2=183462&view=diff
> ==============================================================================
> --- cfe/trunk/test/CXX/drs/dr0xx.cpp (original)
> +++ cfe/trunk/test/CXX/drs/dr0xx.cpp Thu Jun  6 18:43:20 2013
> @@ -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}}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list