Author: rsmith Date: Wed May 30 15:13:43 2018 New Revision: 333599 URL: http://llvm.org/viewvc/llvm-project?rev=333599&view=rev Log: PR37631: verify that a member deduction guide has the same access as its template.
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=333599&r1=333598&r2=333599&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed May 30 15:13:43 2018 @@ -2115,9 +2115,16 @@ def err_deduction_guide_explicit_mismatc def err_deduction_guide_specialized : Error<"deduction guide cannot be " "%select{explicitly instantiated|explicitly specialized}0">; def err_deduction_guide_template_not_deducible : Error< - "deduction guide template contains " - "%select{a template parameter|template parameters}0 that cannot be " - "deduced">; + "deduction guide template contains " + "%select{a template parameter|template parameters}0 that cannot be " + "deduced">; +def err_deduction_guide_wrong_access : Error< + "deduction guide has different access from the corresponding " + "member template">; +def note_deduction_guide_template_access : Note< + "member template declared %0 here">; +def note_deduction_guide_access : Note< + "deduction guide declared %0 by intervening access specifier">; // C++1y deduced return types def err_auto_fn_deduction_failure : Error< Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=333599&r1=333598&r2=333599&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed May 30 15:13:43 2018 @@ -3103,14 +3103,38 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, Member->setInvalidDecl(); } + NamedDecl *NonTemplateMember = Member; + if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Member)) + NonTemplateMember = FunTmpl->getTemplatedDecl(); + else if (VarTemplateDecl *VarTmpl = dyn_cast<VarTemplateDecl>(Member)) + NonTemplateMember = VarTmpl->getTemplatedDecl(); + Member->setAccess(AS); // If we have declared a member function template or static data member // template, set the access of the templated declaration as well. - if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Member)) - FunTmpl->getTemplatedDecl()->setAccess(AS); - else if (VarTemplateDecl *VarTmpl = dyn_cast<VarTemplateDecl>(Member)) - VarTmpl->getTemplatedDecl()->setAccess(AS); + if (NonTemplateMember != Member) + NonTemplateMember->setAccess(AS); + + // C++ [temp.deduct.guide]p3: + // A deduction guide [...] for a member class template [shall be + // declared] with the same access [as the template]. + if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(NonTemplateMember)) { + auto *TD = DG->getDeducedTemplate(); + if (AS != TD->getAccess()) { + Diag(DG->getLocStart(), diag::err_deduction_guide_wrong_access); + Diag(TD->getLocStart(), diag::note_deduction_guide_template_access) + << TD->getAccess(); + const AccessSpecDecl *LastAccessSpec = nullptr; + for (const auto *D : cast<CXXRecordDecl>(CurContext)->decls()) { + if (const auto *AccessSpec = dyn_cast<AccessSpecDecl>(D)) + LastAccessSpec = AccessSpec; + } + assert(LastAccessSpec && "differing access with no access specifier"); + Diag(LastAccessSpec->getLocStart(), diag::note_deduction_guide_access) + << AS; + } + } } if (VS.isOverrideSpecified()) Modified: cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp?rev=333599&r1=333598&r2=333599&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp Wed May 30 15:13:43 2018 @@ -330,6 +330,22 @@ namespace member_guides { Bar(int) -> Bar<int>; }; Foo<int>::Bar b = 0; + + struct A { + template<typename T> struct Public; // expected-note {{declared public}} + Public(float) -> Public<float>; + protected: // expected-note {{declared protected by intervening access specifier}} + template<typename T> struct Protected; // expected-note 2{{declared protected}} + Protected(float) -> Protected<float>; + Public(int) -> Public<int>; // expected-error {{different access}} + private: // expected-note {{declared private by intervening access specifier}} + template<typename T> struct Private; // expected-note {{declared private}} + Protected(int) -> Protected<int>; // expected-error {{different access}} + public: // expected-note 2{{declared public by intervening access specifier}} + template<typename T> Public(T) -> Public<T>; + template<typename T> Protected(T) -> Protected<T>; // expected-error {{different access}} + template<typename T> Private(T) -> Private<T>; // expected-error {{different access}} + }; } #else _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits