diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_DECLTEMPLATE_H #include "clang/AST/ASTConcept.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" @@ -373,11 +374,19 @@ /// Set that the default argument was inherited from another parameter. void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) { - assert(!isInherited() && "default argument already inherited"); InheritedFrom = getParmOwningDefaultArg(InheritedFrom); if (!isSet()) ValueOrInherited = InheritedFrom; - else + else if (auto *D = ValueOrInherited.template dyn_cast()) { + assert(C.isSameDefaultTemplateArgument(D, InheritedFrom)); + ValueOrInherited = + new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()}; + } else if (auto *Inherited = + ValueOrInherited.template dyn_cast()) { + assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg, + InheritedFrom)); + Inherited->PrevDeclWithDefaultArg = InheritedFrom; + } else ValueOrInherited = new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, ValueOrInherited.template get()}; } diff --git a/clang/test/Modules/InheritDefaultArguments.cppm b/clang/test/Modules/InheritDefaultArguments.cppm --- a/clang/test/Modules/InheritDefaultArguments.cppm +++ b/clang/test/Modules/InheritDefaultArguments.cppm @@ -10,7 +10,10 @@ class Templ; template -class Templ {}; +class Templ { +public: + Templ(T t) {} +}; template Templ(T t) -> Templ; @@ -26,3 +29,6 @@ #include "foo.h" export module X; import A; +void foo() { + Templ t(0); +} diff --git a/clang/test/Modules/Inputs/PR31469/textual.h b/clang/test/Modules/Inputs/PR31469/textual.h --- a/clang/test/Modules/Inputs/PR31469/textual.h +++ b/clang/test/Modules/Inputs/PR31469/textual.h @@ -4,7 +4,7 @@ template class allocator; template > class list; template class __list_iterator { - //template friend class list; // causes another crash in ASTDeclReader::attachPreviousDecl + template friend class list; template friend class list; }; template class __list_imp {};