summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-05-17 02:19:35 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-05-17 02:19:35 +0000
commit4c163a093f61ec6cbb47816846566930a1705e5c (patch)
tree161f34540a19f66ff462ba1b6d47c214b4c598de /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
parentfbe4d850352c351b0f59d4bcea4bb118d869ceea (diff)
downloadbcm5719-llvm-4c163a093f61ec6cbb47816846566930a1705e5c.tar.gz
bcm5719-llvm-4c163a093f61ec6cbb47816846566930a1705e5c.zip
PR15757: When we instantiate an inheriting constructor template, also
instantiate the inherited constructor template and mark that as the constructor which the instantiated specialization is inheriting. This fixes a crash-on-valid when trying to compute the exception specification of a specialization of the inheriting constructor. llvm-svn: 182072
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index ff59cdcbc42..09ddd9db658 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1558,10 +1558,36 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
Constructor->isExplicit(),
Constructor->isInlineSpecified(),
false, Constructor->isConstexpr());
+
// Claim that the instantiation of a constructor or constructor template
// inherits the same constructor that the template does.
- if (const CXXConstructorDecl *Inh = Constructor->getInheritedConstructor())
+ if (CXXConstructorDecl *Inh = const_cast<CXXConstructorDecl *>(
+ Constructor->getInheritedConstructor())) {
+ // If we're instantiating a specialization of a function template, our
+ // "inherited constructor" will actually itself be a function template.
+ // Instantiate a declaration of it, too.
+ if (FunctionTemplate) {
+ assert(!TemplateParams && Inh->getDescribedFunctionTemplate() &&
+ !Inh->getParent()->isDependentContext() &&
+ "inheriting constructor template in dependent context?");
+ Sema::InstantiatingTemplate Inst(SemaRef, Constructor->getLocation(),
+ Inh);
+ if (Inst)
+ return 0;
+ Sema::ContextRAII SavedContext(SemaRef, Inh->getDeclContext());
+ LocalInstantiationScope LocalScope(SemaRef);
+
+ // Use the same template arguments that we deduced for the inheriting
+ // constructor. There's no way they could be deduced differently.
+ MultiLevelTemplateArgumentList InheritedArgs;
+ InheritedArgs.addOuterTemplateArguments(TemplateArgs.getInnermost());
+ Inh = cast_or_null<CXXConstructorDecl>(
+ SemaRef.SubstDecl(Inh, Inh->getDeclContext(), InheritedArgs));
+ if (!Inh)
+ return 0;
+ }
cast<CXXConstructorDecl>(Method)->setInheritedConstructor(Inh);
+ }
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
StartLoc, NameInfo, T, TInfo,
OpenPOWER on IntegriCloud