summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorErik Pilkington <erik.pilkington@gmail.com>2018-10-10 17:17:51 +0000
committerErik Pilkington <erik.pilkington@gmail.com>2018-10-10 17:17:51 +0000
commitd1a184fc6a4a121e8e17415573eaa29e1395cf8f (patch)
tree416e62b21dc4a7e93c6bddcc2b96046edbf121db /clang/lib/Sema/SemaDecl.cpp
parent8a39827eb3fd0b17cd5e820eb2d31d75597182df (diff)
downloadbcm5719-llvm-d1a184fc6a4a121e8e17415573eaa29e1395cf8f.tar.gz
bcm5719-llvm-d1a184fc6a4a121e8e17415573eaa29e1395cf8f.zip
[Sema] Fix a multiple definition bug with friends and templates
The problem was that MergeFunctionDecl sometimes needs the injected template arguments of a FunctionTemplateDecl, but is called before adding the new template to the redecl chain. This leads to multiple common pointers in the same redecl chain, each with their own identical instantiation. Fix this by merging the the common state before inserting the new template into the redecl chain. rdar://44810129 Differential revision: https://reviews.llvm.org/D53046 llvm-svn: 344157
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp10
1 files changed, 8 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 441c54dc358..7ef1ad2bbb0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10022,11 +10022,17 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
if (FunctionTemplateDecl *OldTemplateDecl =
dyn_cast<FunctionTemplateDecl>(OldDecl)) {
auto *OldFD = OldTemplateDecl->getTemplatedDecl();
- NewFD->setPreviousDeclaration(OldFD);
- adjustDeclContextForDeclaratorDecl(NewFD, OldFD);
FunctionTemplateDecl *NewTemplateDecl
= NewFD->getDescribedFunctionTemplate();
assert(NewTemplateDecl && "Template/non-template mismatch");
+
+ // The call to MergeFunctionDecl above may have created some state in
+ // NewTemplateDecl that needs to be merged with OldTemplateDecl before we
+ // can add it as a redeclaration.
+ NewTemplateDecl->mergePrevDecl(OldTemplateDecl);
+
+ NewFD->setPreviousDeclaration(OldFD);
+ adjustDeclContextForDeclaratorDecl(NewFD, OldFD);
if (NewFD->isCXXClassMember()) {
NewFD->setAccess(OldTemplateDecl->getAccess());
NewTemplateDecl->setAccess(OldTemplateDecl->getAccess());
OpenPOWER on IntegriCloud