This is an archive of the discontinued LLVM Phabricator instance.

[C++20] [Modules] Merging of lambda types in deserialization
AbandonedPublic

Authored by ChuanqiXu on Dec 14 2022, 2:18 AM.

Details

Summary

Close https://github.com/llvm/llvm-project/issues/57222

The previous deserialization code wouldn't try to merge lambdas since every lambda has a unique type before C++20. In C++20 and later, lambdas can have the same type under certain condition. See the issue link or the comment for example.

This is a workaround for the problem but the cost is the inefficiency. And if we want to fix the problem properly, it looks like we need to touch something very fundamentally and it may affect a lot of things beyond the C++20 modules or even modules.

See my inline comments for details.

The bug/defect has a strong impact. I feel like fixing bug is more important so I prefer to land this one first and file an issue for this to record it.

Diff Detail

Event Timeline

ChuanqiXu created this revision.Dec 14 2022, 2:18 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 14 2022, 2:18 AM
ChuanqiXu requested review of this revision.Dec 14 2022, 2:18 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 14 2022, 2:18 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
ChuanqiXu added inline comments.Dec 14 2022, 2:19 AM
clang/lib/Serialization/ASTReaderDecl.cpp
2161–2198

The comment tells why this is a workaround and what we need to do to fix the problem properly.

This is my first and pretty shallow review pass. Need to read the standard more thoroughly to be more useful. Others are welcome to chime in (and as I'll be on vacation are encouraged to chime in).

What do you mean by

Due to we don't care about merging unnamed entities before, now it is pretty problematic to fix it in a well formed.

In ASTReaderDecl.cpp we have a bunch of code to deal with anonymous decls, that's why I'm asking. Though I haven't tried to use any of that for your current problem.

Few stylistic nits:

  • most of tests in "clang/test/Modules" start with a lowercase and use kebab-naming-style (sometimes with underscores);
  • can you please use more descriptive names in tests? Currently hunting for 1-character difference isn't fun and doesn't convey the purpose and intention of the test;
  • is it possible to reuse some of the testing code because trying to find differences and what they mean is time-consuming.

Looks like not all branches in the added code are covered by tests but I need more time to play with the code.

clang/lib/Serialization/ASTReaderDecl.cpp
2222

How does this mergeRedeclarable work with other mergeRedeclarable calls in ASTDeclReader::VisitCXXRecordDeclImpl? Are multiple calls OK, do you expect it never to happen or something else?

Test case MergeLambdas3.cppm is unstable. Sometimes it passes but usually it fails.

clang/lib/Serialization/ASTReaderDecl.cpp
2161–2198

Is there are a test covering this workaround? I've removed it and see no new test failures.

ChuanqiXu edited the summary of this revision. (Show Details)Dec 15 2022, 6:28 PM

This is my first and pretty shallow review pass. Need to read the standard more thoroughly to be more useful. Others are welcome to chime in (and as I'll be on vacation are encouraged to chime in).

Thanks for reviewing this!

What do you mean by

Due to we don't care about merging unnamed entities before, now it is pretty problematic to fix it in a well formed.

In ASTReaderDecl.cpp we have a bunch of code to deal with anonymous decls, that's why I'm asking. Though I haven't tried to use any of that for your current problem.

Oh, this is not accurate. I wanted to say lambdas instead of anonymous decls. In ASTDeclReader::findExisting, lambdas will fall in the block: https://github.com/llvm/llvm-project/blob/bcd0bf9284db0d5d4697611ff9bf3243504aab07/clang/lib/Serialization/ASTReaderDecl.cpp#L3269-L3276. Since lambdas has no name and
serialization::needsAnonymousDeclarationNumber(NamedDecl*) will return false for lambdas which are no defined in functions: https://github.com/llvm/llvm-project/blob/bcd0bf9284db0d5d4697611ff9bf3243504aab07/clang/lib/Serialization/ASTCommon.cpp#L470-L485

So we can't find existing decls for lambdas so we can't merge them. This is what I wanted to say. And now I delete it since it may be confusing.

Few stylistic nits:

  • most of tests in "clang/test/Modules" start with a lowercase and use kebab-naming-style (sometimes with underscores);
  • can you please use more descriptive names in tests? Currently hunting for 1-character difference isn't fun and doesn't convey the purpose and intention of the test;
  • is it possible to reuse some of the testing code because trying to find differences and what they mean is time-consuming.

Thanks for this. Let's do it after we get a consensus in the higher level.

Looks like not all branches in the added code are covered by tests but I need more time to play with the code.

Oh, I didn't test the coverage when developing. I'll check it when I look at this again.

Test case MergeLambdas3.cppm is unstable. Sometimes it passes but usually it fails.

Weird. What is the error message if it fails?

clang/lib/Serialization/ASTReaderDecl.cpp
2161–2198

Weird. MergeLambdas3.cppm should cover this. Let me try a double check.

2222

The original mergeRedeclarable in ASTDeclReader::VisitCXXRecordDeclImpl are the mergeRedeclarable with two parameters and it will call the mergeRedeclarable with 3 parameters if it found an existing declaration. So the relationship of the mergeLambda here and the mergeRedeclarable in ASTDeclReader::VisitCXXRecordDeclImpl is that they find different things and they will call the same method.

The original mergeRedeclarable in ASTDeclReader::VisitCXXRecordDeclImpl can't find existing lambdas for the reason I explained in the main thread.

And mergeLambda is called after we read the definition about lambdas and the original mergeRedeclarable in ASTDeclReader::VisitCXXRecordDeclImpl is called before we read the definitions since it mainly cares about the declaration instead of the definition.

Test case MergeLambdas3.cppm is unstable. Sometimes it passes but usually it fails.

Weird. What is the error message if it fails?

error: 'error' diagnostics seen but not expected: 
  File /path/to/llvm/build/clang/relwithdebinfo/tools/clang/test/Modules/Output/MergeLambdas3.cppm.tmp/Use2.cpp Line 4: static assertion failed due to requirement '__is_same((lambda at /path/to/llvm/build/clang/relwithdebinfo/tools/clang/test/Modules/Output/MergeLambdas3.cppm.tmp/lambda.h:4:13), (lambda at /path/to/llvm/build/clang/relwithdebinfo/tools/clang/test/Modules/Output/MergeLambdas3.cppm.tmp/lambda.h:1:12))'

Also looks like this test fails in pre-commit checks too.

ChuanqiXu planned changes to this revision.Dec 15 2022, 7:24 PM

Test case MergeLambdas3.cppm is unstable. Sometimes it passes but usually it fails.

Weird. What is the error message if it fails?

error: 'error' diagnostics seen but not expected: 
  File /path/to/llvm/build/clang/relwithdebinfo/tools/clang/test/Modules/Output/MergeLambdas3.cppm.tmp/Use2.cpp Line 4: static assertion failed due to requirement '__is_same((lambda at /path/to/llvm/build/clang/relwithdebinfo/tools/clang/test/Modules/Output/MergeLambdas3.cppm.tmp/lambda.h:4:13), (lambda at /path/to/llvm/build/clang/relwithdebinfo/tools/clang/test/Modules/Output/MergeLambdas3.cppm.tmp/lambda.h:1:12))'

Also looks like this test fails in pre-commit checks too.

I reproduced it after I rebase onto main. Let me check what happened..

ChuanqiXu abandoned this revision.Jun 27 2023, 10:51 PM