-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[Clang] [Modules] Clang instantiates the wrong lambda call operator #110401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@llvm/issue-subscribers-clang-frontend Author: None (Sirraide)
Given `a.ccm`:
```c++
module;
#include <variant>
#include <string>
export module A;
export using Foo = std::variant<int, std::string, std::monostate>;
Attempting to compile this asserts on trunk (https://godbolt.org/z/sqWax9eKq). I have not been able to reproduce this w/o modules (yet, but I’ll keep trying). #102353 seems to be the same assertion, but I’m not sure they’re related.
Invocation:
It’s clearly crashing in Stack trace:
|
@llvm/issue-subscribers-clang-modules Author: None (Sirraide)
Given `a.ccm`:
```c++
module;
#include <variant>
#include <string>
export module A;
export using Foo = std::variant<int, std::string, std::monostate>;
Attempting to compile this asserts on trunk (https://godbolt.org/z/sqWax9eKq). I have not been able to reproduce this w/o modules (yet, but I’ll keep trying). #102353 seems to be the same assertion, but I’m not sure they’re related.
Invocation:
It’s clearly crashing in Stack trace:
|
declaration not instantiated in this scope
in code involving variants and modules
This comment was marked as spam.
This comment was marked as spam.
How to use this? |
I just tested this w/ libc++ instead of libstdc++, and it works just fine, so there’s something about libstdc++’s implementation of |
That account seems to be stolen. |
The declaration it’s crashing on is this:
|
Ok, after fighting w/ The bug only triggers if the declaration of clang -cc1 -emit-module-interface -x c++ -std=c++26 b.ccm -o b.pcm
clang -cc1 -emit-module-interface -x c++ -std=c++26 -fmodule-file=A=a.pcm b.ccm -o b.pcm
module;
template <typename _Visitor>
void __do_visit(_Visitor &&__visitor) {
using _V0 = int;
[](_V0 __v) -> _V0 { return __v; }(1);
}
export module A;
void g() {
struct Visitor { };
__do_visit(Visitor());
}
module;
template <typename _Visitor>
void __do_visit(_Visitor &&__visitor) {
using _V0 = int;
[](_V0 __v) -> _V0 { return __v; }(1);
}
export module B;
import A;
void f() {
__do_visit(1);
} |
It seems that, while instantiating the lambda in module |
Ok, found the issue: we’re trying to find the |
@ChuanqiXu9 I’d appreciate it if you (or someone else familiar w/ our modules implementation) could maybe take a look at this, because I feel like I’ve done pretty much all I can here: I don’t know enough about modules to know where to fix this—alternatively, if you have an idea of how to fix this, then I could also take care of that, but at the moment, I’m fairly lost as to what to do here... |
Decided to look into this a bit more since this is kind of blocking me from doing anything else (because
but calling
Clearly, these are two different |
I think I might have figured something out; I’ll recompile and write a test, and if that works, I’ll open a pr for it shortly. |
declaration not instantiated in this scope
in code involving variants and modulesThis is a fix for the following issue: when a lambda’s class type is merged across modules (e.g. because it is defined in a template in the GMF of some module `A`, and some other module `B` both imports `A` and has the same template in its GMF), then `getLambdaCallOperator()` might return the wrong operator (e.g. while compiling `B`, the lambda’s class type would be the one attached to `B`’s GMF, but the call operator ends up being the one attached to `A`’s GMF). This causes issues in situations where the call operator is in a template and accesses declarations in the surrounding context: when those declarations are instantated, a mapping is introduced from the original node in the template to that of the instantiation. If such an instantiation happens in `B`, and we then try to instantiate `A`’s call operator, any nodes in that call operator refer to declarations in the template in `A`, but the `LocalInstantiationScope` only contains mappings for declarations in `B`! This causes the following assertion (for godbolt links and more, see the issue below): ``` Assertion `isa<LabelDecl>(D) && "declaration not instantiated in this scope"' failed. ``` We now walk the redecl chain of the call operator to find the one that is in the same module as the record decl. This fixes #110401.
Uh oh!
There was an error while loading. Please reload this page.
Update: See #110401 (comment) for a reduced version + cc1 invocations.
Given
a.ccm
:and
b.ccm
:Attempting to compile this asserts on trunk (https://godbolt.org/z/sqWax9eKq). I have not been able to reproduce this w/o modules (yet, but I’ll keep trying). #102353 seems to be the same assertion, but I’m not sure they’re related.
Invocation:
It’s clearly crashing in
b.ccm
, but that might be due to a faulty module being emitted fora.ccm
. I’m unfortunately not that familiar w/ our modules implementation, so I don’t know which one is more likely.Stack trace:
The text was updated successfully, but these errors were encountered: