Files
llvm-tms34010/clang/test/Modules/modules-lambda-dependent-crash.cppm
Ivo Popovandipopov b0e490ad4f [Clang][Modules] Skip anonymous declaration numbering for local tags in dependent contexts (#202248)
Local tag declarations (classes, structs, enums, and lambdas) defined
within function template bodies or class templates do not require ODR
merging at the local declaration level across different modules. ODR
consistency is already guaranteed because the instantiator only walks
the canonical template definition body, which instantiates its own copy
of the local class.

Merging them across different modules causes their member definitions
(like methods or call operators) to be canonicalized to one module,
while the instantiator walks the template body from another module.
Since local variables within template bodies are not merged, this
mismatch leads to assertion crashes during template instantiation in
`LocalInstantiationScope::findInstantiationOf`.

Fixes https://github.com/llvm/llvm-project/issues/206203.

Co-authored-by: ipopov <ipopov@google.com>
2026-07-01 02:33:36 +00:00

74 lines
1.5 KiB
C++

// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
// RUN: cd %t
//
// RUN: %clang_cc1 -std=c++20 -I. m_template.cppm -emit-reduced-module-interface \
// RUN: -o m_template.pcm
//
// RUN: %clang_cc1 -std=c++20 -I. m_wrapper.cppm \
// RUN: -emit-reduced-module-interface \
// RUN: -fmodule-file=m_template=m_template.pcm \
// RUN: -o m_wrapper.pcm
//
// RUN: %clang_cc1 -std=c++20 -I. main.cpp \
// RUN: -fmodule-file=m_template=m_template.pcm \
// RUN: -fmodule-file=m_wrapper=m_wrapper.pcm \
// RUN: -fsyntax-only -verify
//--- template_class.h
#pragma once
class TemplateClass {
public:
template <typename U>
auto f1(U u);
};
template <typename U>
auto TemplateClass::f1(U u) {
U z = u;
return [=](auto) {
(void)z;
};
}
template <typename U>
auto trigger_ast_deserialization(U u) {
return []() {};
}
//--- m_template.cppm
module;
#include "template_class.h"
export module m_template;
export using ::TemplateClass;
export using ::trigger_ast_deserialization;
//--- m_wrapper.cppm
module;
#include "template_class.h"
export module m_wrapper;
import m_template;
export inline void TriggerInstantiation() {
TemplateClass tc;
tc.f1(0);
trigger_ast_deserialization(0);
}
//--- main.cpp
// expected-no-diagnostics
import m_template;
import m_wrapper;
#include "template_class.h"
struct Token {};
int main() {
TriggerInstantiation();
trigger_ast_deserialization(Token{});
TemplateClass tc;
tc.f1(Token{});
}