summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-05-30 22:13:43 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-05-30 22:13:43 +0000
commite4899c16480dfb06a0265274d0b5b0fe3b370b8a (patch)
tree580366c742dff5d37cd53a967a33b0e9aeaa7562
parente86329777563a372881a3952b2f73dc90becec6e (diff)
downloadbcm5719-llvm-e4899c16480dfb06a0265274d0b5b0fe3b370b8a.tar.gz
bcm5719-llvm-e4899c16480dfb06a0265274d0b5b0fe3b370b8a.zip
PR37631: verify that a member deduction guide has the same access as its template.
llvm-svn: 333599
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td13
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp32
-rw-r--r--clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp16
3 files changed, 54 insertions, 7 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b4d76ba9183..16836b98614 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2115,9 +2115,16 @@ def err_deduction_guide_explicit_mismatch : Error<
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<
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index d5af147279a..8dbf5e7ac14 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -3103,14 +3103,38 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
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())
diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
index 90f168d3fcc..de61e44a6e9 100644
--- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -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
OpenPOWER on IntegriCloud