Skip to content

Commit a0153e2

Browse files
Fedrclaude
andcommitted
Parser: skip class members in the buggy-substitute-default-template-args path
The block's own comment already says this path is only needed for free function templates and that "something else already instantiates them for the class member functions". When the path is exercised on a CXXMethodDecl (in particular a CXXConstructorDecl), `Sema::SubstDecl` on the member template's pattern null-derefs inside `TemplateDeclInstantiator::InitMethodInstantiation`. Captured stack from CI (clang 22.1.4) parsing `<boost/multiprecision/cpp_int.hpp>` with `--buggy-substitute-default-template-args`: #0 clang::TemplateDeclInstantiator::InitMethodInstantiation #1 clang::TemplateDeclInstantiator::VisitCXXMethodDecl #2 lambda inside Sema::SubstDecl (runWithSufficientStackSpace) #3 clang::StackExhaustionHandler::runWithSufficientStackSpace #4 clang::Sema::runWithSufficientStackSpace #5 clang::Sema::SubstDecl #6 mrbind::ClangAstVisitor_InstTypesAndCollectNewTypes::VisitFunctionDecl main.cpp:2815 <- this call site #7 clang::RecursiveASTVisitor::TraverseCXXConstructorDecl Adding `!llvm::isa<clang::CXXMethodDecl>(decl)` to the existing `decl->isTemplated()` check matches the comment and avoids the crash. This is consistent with the previous commit, which skipped primary function templates from `InstantiateDefaultArgument` / `InstantiateFunctionDefinition` for the same class of latent libclang bug (public Sema API null-derefs on a primary template's pattern). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent fe3473b commit a0153e2

1 file changed

Lines changed: 6 additions & 1 deletion

File tree

src/parser/main.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2689,7 +2689,12 @@ namespace mrbind
26892689
{
26902690
// If this is a template, try instantiating it.
26912691
// This is currently disabled by default because it's buggy: https://github.com/MeshInspector/mrbind/issues/19
2692-
if (params->buggy_substitute_default_template_args && decl->isTemplated() && !ShouldRejectFunction(*decl, *ctx, *ci, *params, printing_policies, ShouldRejectFlags::allow_uninstantiated_templates))
2692+
//
2693+
// Skip class members entirely (constructors, methods, ...). Per the comment below,
2694+
// they don't need this path, and `Sema::SubstDecl` on a member function template's
2695+
// pattern null-derefs internally on at least clang 22 — for example, a constructor
2696+
// template substitution crashes in `TemplateDeclInstantiator::InitMethodInstantiation`.
2697+
if (params->buggy_substitute_default_template_args && decl->isTemplated() && !llvm::isa<clang::CXXMethodDecl>(decl) && !ShouldRejectFunction(*decl, *ctx, *ci, *params, printing_policies, ShouldRejectFlags::allow_uninstantiated_templates))
26932698
{
26942699
// Among other things, we visit the function declarations to instantiate their default arguments,
26952700
// which apparently doesn't happen otherwise. This is only needed for free function templates.

0 commit comments

Comments
 (0)