forked from OSchip/llvm-project
PR47682: Merge the DeclContext of a merged FunctionDecl before we inherit
default arguments. When a function is declared with a qualified name, its eventual semantic DeclContext may differ from the scope specified by the qualifier if it redeclares a function in an inline namespace. In this case, we need to update the DeclContext to be that of the previous declaration, and we need to do so before we decide whether to inherit default arguments from that previous declaration, because we only inherit default arguments from declarations in the same scope.
This commit is contained in:
parent
d18c3c7b18
commit
e92be7cd9f
|
@ -3238,6 +3238,10 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
|
|||
}
|
||||
}
|
||||
|
||||
// If the old declaration was found in an inline namespace and the new
|
||||
// declaration was qualified, update the DeclContext to match.
|
||||
adjustDeclContextForDeclaratorDecl(New, Old);
|
||||
|
||||
// If the old declaration is invalid, just give up here.
|
||||
if (Old->isInvalidDecl())
|
||||
return true;
|
||||
|
@ -4052,6 +4056,10 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
|
|||
return New->setInvalidDecl();
|
||||
}
|
||||
|
||||
// If the old declaration was found in an inline namespace and the new
|
||||
// declaration was qualified, update the DeclContext to match.
|
||||
adjustDeclContextForDeclaratorDecl(New, Old);
|
||||
|
||||
// Ensure the template parameters are compatible.
|
||||
if (NewTemplate &&
|
||||
!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
|
||||
|
@ -4236,7 +4244,6 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
|
|||
New->setPreviousDecl(Old);
|
||||
if (NewTemplate)
|
||||
NewTemplate->setPreviousDecl(OldTemplate);
|
||||
adjustDeclContextForDeclaratorDecl(New, Old);
|
||||
|
||||
// Inherit access appropriately.
|
||||
New->setAccess(Old->getAccess());
|
||||
|
@ -10788,7 +10795,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
|
|||
NewTemplateDecl->mergePrevDecl(OldTemplateDecl);
|
||||
|
||||
NewFD->setPreviousDeclaration(OldFD);
|
||||
adjustDeclContextForDeclaratorDecl(NewFD, OldFD);
|
||||
if (NewFD->isCXXClassMember()) {
|
||||
NewFD->setAccess(OldTemplateDecl->getAccess());
|
||||
NewTemplateDecl->setAccess(OldTemplateDecl->getAccess());
|
||||
|
@ -10815,7 +10821,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
|
|||
auto *OldFD = cast<FunctionDecl>(OldDecl);
|
||||
// This needs to happen first so that 'inline' propagates.
|
||||
NewFD->setPreviousDeclaration(OldFD);
|
||||
adjustDeclContextForDeclaratorDecl(NewFD, OldFD);
|
||||
if (NewFD->isCXXClassMember())
|
||||
NewFD->setAccess(OldFD->getAccess());
|
||||
}
|
||||
|
|
|
@ -95,4 +95,12 @@ void g2(int c = f2<int>()) {}
|
|||
template<typename T> int f3() { return T::error; } // expected-error {{no members}}
|
||||
void g3(int c = f3<int>()) {} // expected-note {{in instantiation of}}
|
||||
void use_g3() { g3(); }
|
||||
|
||||
namespace PR47682 {
|
||||
inline namespace A {
|
||||
void f(int = 0);
|
||||
}
|
||||
}
|
||||
void PR47682::f(int) {}
|
||||
void PR47682_test() { PR47682::f(); }
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue