Mordante created this revision. Mordante added reviewers: sepavloff, rsmith. Mordante added a project: clang.
This fixes https://bugs.llvm.org/show_bug.cgi?id=28500 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D65694 Files: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/test/SemaTemplate/default-arguments-cxx0x.cpp
Index: clang/test/SemaTemplate/default-arguments-cxx0x.cpp =================================================================== --- clang/test/SemaTemplate/default-arguments-cxx0x.cpp +++ clang/test/SemaTemplate/default-arguments-cxx0x.cpp @@ -114,3 +114,34 @@ S<int> _a{}; }; } + +// https://bugs.llvm.org/show_bug.cgi?id=28500 +// Failure to resolve the decltype part during instantiation caused an +// assertion failure +namespace PR28500 { +namespace original { +template <class T> +void bar(T t = [](decltype(t) i) { return 0; }(0)) {} +void foo() { + bar<int>(); +} +} // namespace original + +namespace cast { +template <class T> +void bar(T t = decltype(t)(0)) {} +void foo() { + bar<int>(); + bar<double>(); +} +} // namespace cast + +namespace value { +template <class T> +void bar(T t = decltype(t)()) {} +void foo() { + bar<int>(); + bar<double>(); +} +} // namespace value +} // namespace PR28500 Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5287,29 +5287,33 @@ // } // // In this case instantiation of the type of 'g1' requires definition of - // 'x1', which is defined later. Error recovery may produce an enum used - // before definition. In these cases we need to instantiate relevant - // declarations here. + // 'x1', which is defined later. + // + // Error recovery may produce an enum used before definition. + // + // Default arguments with a decltype referencing arguments: + // + // template <class T> void bar(T t = decltype(t)()) {} + // + // Else we must have a label decl that hasn't been found yet. + // + // In these cases we need to instantiate relevant declarations here. bool NeedInstantiate = false; if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) NeedInstantiate = RD->isLocalClass(); else - NeedInstantiate = isa<EnumDecl>(D); + NeedInstantiate = + isa<EnumDecl>(D) || isa<LabelDecl>(D) || isa<ParmVarDecl>(D); if (NeedInstantiate) { Decl *Inst = SubstDecl(D, CurContext, TemplateArgs); + assert(Inst && "Failed to instantiate"); CurrentInstantiationScope->InstantiatedLocal(D, Inst); - return cast<TypeDecl>(Inst); + return cast<NamedDecl>(Inst); } - // If we didn't find the decl, then we must have a label decl that hasn't - // been found yet. Lazily instantiate it and return it now. - assert(isa<LabelDecl>(D)); - - Decl *Inst = SubstDecl(D, CurContext, TemplateArgs); - assert(Inst && "Failed to instantiate label??"); + assert(0 && "Failed to instantiate"); - CurrentInstantiationScope->InstantiatedLocal(D, Inst); - return cast<LabelDecl>(Inst); + return nullptr; } if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) { Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2974,6 +2974,11 @@ if (isa<EnumDecl>(D)) return nullptr; + // Default arguments with a decltype referencing arguments prior to definition + // may require instantiation. + if (isa<ParmVarDecl>(D)) + return nullptr; + // If we didn't find the decl, then we either have a sema bug, or we have a // forward reference to a label declaration. Return null to indicate that // we have an uninstantiated label.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits