https://github.com/ojhunt created https://github.com/llvm/llvm-project/pull/213166
This assertion was due to template instantiation not recording the instantiation as incomplete when parameter deduction fails. >From 469b688f32dac03a81d51e3195375db37be28177 Mon Sep 17 00:00:00 2001 From: Oliver Hunt <[email protected]> Date: Thu, 30 Jul 2026 13:39:26 -0700 Subject: [PATCH] [clang] Assertion failure on template parameter deduction failure This assertion was due to template instantiation not recording the instantiation as incomplete when parameter deduction fails. --- clang/lib/Sema/SemaTemplateInstantiate.cpp | 24 +++++++++++++ ...tion-after-parameter-deduction-failure.cpp | 35 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 clang/test/SemaTemplate/instantiation-after-parameter-deduction-failure.cpp diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 2cf2a4f85f830..b3d48218f5efe 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1992,6 +1992,30 @@ Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) { *SemaRef.CurrentInstantiationScope->findInstantiationOf(D)); } + // ***REVIEWER***: Essentially cloned from the above TemplateTemplateParmDecl + // logic. This seems like the actual root cause fix, but prior "correct seeming" + // changes i've made against template code was gratuitously wrong. + // Biggest question: is it correct to use !getInstantiationOfIfExists as the + // test for failure? + // Errrr, ***REVIEWER*** again: I thought this was specific to errors, but I + // managed to come up with a couple of valid code tests that trip this + // assertion. + if (BailOutOnIncomplete && isa<ParmVarDecl>(D) && + SemaRef.CurrentInstantiationScope && + !SemaRef.CurrentInstantiationScope->getInstantiationOfIfExists(D)) { + assert(!SemaRef.CodeSynthesisContexts.empty() && + SemaRef.CodeSynthesisContexts.back().Kind == + Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution && + "***REVIEWER***: it seemed like this is only mean to happen during " + "substitution, but i based that on adding a __builtin_trap() and " + "then looking at a few of the resulting crashing tests and they " + "were all in this mode. Is that expected/correct? the assertion " + "doesn't fire on any of the template tests" + ""); + IsIncomplete = true; + return nullptr; + } + return SemaRef.FindInstantiatedDecl(Loc, cast<NamedDecl>(D), TemplateArgs); } diff --git a/clang/test/SemaTemplate/instantiation-after-parameter-deduction-failure.cpp b/clang/test/SemaTemplate/instantiation-after-parameter-deduction-failure.cpp new file mode 100644 index 0000000000000..c5839f7ff3c6d --- /dev/null +++ b/clang/test/SemaTemplate/instantiation-after-parameter-deduction-failure.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s + +namespace ambiguous_overload { +template <class> struct S { + template <class T> S(T); +}; +struct S1 {}; +struct S2 { + operator S1(); +}; + +template <typename T> auto foo(T, S<decltype(0)>); // #declaration +template <typename T> auto foo(T arg, decltype(arg)) { + foo(arg, S2{}); + // expected-error@-1 {{function 'foo<ambiguous_overload::S1>' with deduced return type cannot be used before it is defined}} + // expected-note@#declaration {{'foo<ambiguous_overload::S1>' declared here}} + // expected-note@#instantiation {{in instantiation of function template specialization 'ambiguous_overload::foo<ambiguous_overload::S1>' requested here}} +} + +void bar(S1 d) { + foo(d, S1{}); // #instantiation +} +} + +namespace explicit_specialization { + template <typename T> void foo(T, int); + template <typename T> void foo(T arg, decltype(arg)); + template <> void foo(int, int) {} +} + +namespace address_of { + template <typename T> void foo(T, int); + template <typename T> void foo(T arg, decltype(arg)); + void (*p)(int, int) = foo; +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
