Skip to content
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

[C++20] [Modules] The constructor of lambda is broken after deserialization #59513

Open
ChuanqiXu9 opened this issue Dec 14, 2022 · 14 comments
Open
Labels
c++20 clang:modules C++20 modules and Clang Header Modules

Comments

@ChuanqiXu9
Copy link
Member

ChuanqiXu9 commented Dec 14, 2022

Reproducer:

//--- lambda.h
auto cmp = [](auto l, auto r) {
  return l < r;
};

//--- A.cppm
module;
#include "lambda.h"
export module A;
export using ::cmp;

//--- use.cpp
import A;
auto x = cmp;

Compile it with:

clang++ -std=c++20 --precompile -o A.pcm A.cppm
clang++ -std=c++20 -fprebuilt-module-path=. use.cpp

It would emit the following errors:

use.cpp:5:6: error: no matching constructor for initialization of '(lambda at /home/chuanqi.xcq/workspace.xuchuanqi/llvm-project-for-work/build/57222/lambda.h:1:12)'
auto x = cmp; // cmp must not be ambiguous,
     ^   ~~~
/home/chuanqi.xcq/workspace.xuchuanqi/llvm-project-for-work/build/57222/lambda.h:1:12: note: candidate template ignored: could not match 'auto (*)(type-parameter-0-0, type-parameter-0-1)' against '(lambda at /home/chuanqi.xcq/workspace.xuchuanqi/llvm-project-for-work/build/57222/lambda.h:1:12)'
auto cmp = [](auto l, auto r) {
           ^
1 error generated.
@ChuanqiXu9 ChuanqiXu9 added c++20 clang:modules C++20 modules and Clang Header Modules labels Dec 14, 2022
@llvmbot
Copy link
Member

llvmbot commented Dec 14, 2022

@llvm/issue-subscribers-c-20

@llvmbot
Copy link
Member

llvmbot commented Dec 14, 2022

@llvm/issue-subscribers-clang-modules

@ChuanqiXu9 ChuanqiXu9 changed the title [C++20] [Modules] The contractor of lambda is broken after deserialization [C++20] [Modules] The constructor of lambda is broken after deserialization Dec 15, 2022
@Bigcheese
Copy link
Contributor

Shouldn't cmp not be visible at all in use.cpp here? It's not exported by A.

@ChuanqiXu9
Copy link
Member Author

Thanks. I just verified it still exists on trunk with the updated reproducer.

@jer-irl
Copy link

jer-irl commented Mar 19, 2024

@ChuanqiXu9 This issue is titled with a reference to serialization/deserialization, do you suspect that the serialization functionality itself is involved in the problem? After dumping the clang AST from the primary module interface unit and from the downstream dependent TU (with -ast-dump-all to force eager parsing), it looks like both have the same constructors and special member functions, all also with the same node attributes. Writing a similar case with plain PCH files also doesn't hit the same sort of visibility problem, but that might be unrelated.

I'm thinking this is deeper in the "Sema" system, but please let me know if you think I might be down the wrong path.

@jer-irl
Copy link

jer-irl commented Mar 19, 2024

@Bigcheese, as you noted, it doesn’t seem like the original reproducer before Chuanqi's edit was actually expected to be acceptable code judging by https://eel.is/c++draft/module.global.frag#4, and I think it shows there’s another related issue that could cause invalid code being accepted, demonstrated (leading to a bad diagnostic) with the following:

// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: split-file %s %t

// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/A.cppm -o %t/A.pcm -verify
// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/useA.cpp -fsyntax-only -verify

//--- global.h
namespace foo {
int x = 42;
}

//--- A.cppm
// expected-no-diagnostics
module;
#include "global.h"
export module A;

//--- useA.cpp
// expected-no-diagnostics
import A;

namespace foo {
double x = 99.9;
}
error: 'expected-error' diagnostics seen but not expected: 
  File /Users/jeremy/Programming/llvm-project/build/tools/clang/test/CXX/module/module.global.frag/Output/p3copy.cpp.tmp/useA.cpp Line 5: redefinition of 'x' with a different type: 'double' vs 'int'
error: 'expected-note' diagnostics seen but not expected: 
  File /Users/jeremy/Programming/llvm-project/build/tools/clang/test/CXX/module/module.global.frag/Output/p3copy.cpp.tmp/global.h Line 2: previous definition is here

Is this worth filing separately?

@ChuanqiXu9
Copy link
Member Author

@ChuanqiXu9 This issue is titled with a reference to serialization/deserialization, do you suspect that the serialization functionality itself is involved in the problem?

No, it was my direct feelings when seeing the problem. I never looked into it. And I feel it might be a Sema issues too.

@ChuanqiXu9
Copy link
Member Author

I think it shows there’s another related issue that could cause invalid code being accepted, demonstrated (leading to a bad diagnostic) with the following:

I guess you're saying valid being rejected?

And this is a known issue that we didn't implement discarding unreachable things in GMFs. I have a draft on this: #76930

@Bigcheese
Copy link
Contributor

Bigcheese commented Mar 20, 2024

The visibility issue is definitely separate, and different from not including things the the PCM, as there are cases where we do need to include entities in the GMF in the PCM, but they still need to not be visible. I think visibility to name lookup should be handled the same way that it's handled for submodules under local submodule visibility (LSV) (but don't actually require LSV).

We can ignore visibility for this issue, and just focus on the updated testcase which definitely should work.

@ChuanqiXu9
Copy link
Member Author

Yeah, the visibility problem is complex (although I don't feel we can't handle this with LSV). Let's ignore that problem in this issue.

@H-G-Hristov
Copy link
Contributor

@ChuanqiXu9 Does this issue also prevent restoring the lambda for synth-three-way

// TODO MODULES restore the lamba to match the Standard.

as per the Standard (the workaround for modules introduced here https://reviews.llvm.org/D146545) as discussed here: #57222 (comment) (in #57222),

@ChuanqiXu9
Copy link
Member Author

@ChuanqiXu9 Does this issue also prevent restoring the lambda for synth-three-way

// TODO MODULES restore the lamba to match the Standard.

as per the Standard (the workaround for modules introduced here https://reviews.llvm.org/D146545) as discussed here: #57222 (comment) (in #57222),

I feel this may not be a blocker for that since the error message are different. I think it maybe worth a try to see if the issue is still exist in libc++.

@ChuanqiXu9
Copy link
Member Author

Simpler reproducer: https://godbolt.org/z/zG5jKc8ao

export module mod;
export auto f = [] {};
import mod;
int main ()
{
    auto const g = f;
}

@ChuanqiXu9
Copy link
Member Author

ChuanqiXu9 commented Jun 27, 2024

I just realized this may be related to the ABI issue: itanium-cxx-abi/cxx-abi#186

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++20 clang:modules C++20 modules and Clang Header Modules
Projects
None yet
Development

No branches or pull requests

5 participants