This is an archive of the discontinued LLVM Phabricator instance.

[clang-format] Fix CompactNamespaces corner case when AllowShortLambdasOnASingleLine/BraceWrapping.BeforeLambdaBody are set
ClosedPublic

Authored by curdeius on Mar 20 2021, 9:52 PM.

Details

Summary

In clang-format 12, CompactNamespaces misformatted the code when AllowShortLambdasOnASingleLine is set to false and BraceWrapping.BeforeLambdaBody is true.

Input:

namespace out {
namespace in {
} 
} // namespace out::in

Expected output:

namespace out { namespace in {
}} // namespace out::in

Output from v12:

namespace out {
namespace in {
} 
} // namespace out::in

Config triggering the issue:

---
AllowShortLambdasOnASingleLine: None
BraceWrapping:
  BeforeLambdaBody :    true
BreakBeforeBraces: Custom
CompactNamespaces: true
...

Seems there's a corner case when AllowShortLambdasOnASingleLine is false, and BraceWrapping.BeforeLambdaBody is true, that causes CompactNamespaces to stop working.
The cause was a misannotation of { opening brace after namespace as a lambda opening brace.
The regression was probably introduced with this commit.

Originally contributed by Ahmed Mahdy (@aybassiouny). Thank you!

Diff Detail

Event Timeline

aybassiouny requested review of this revision.Mar 20 2021, 9:52 PM
aybassiouny created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptMar 20 2021, 9:52 PM
Wawha accepted this revision.Mar 21 2021, 9:08 AM

Thank you for the fix!

This revision is now accepted and ready to land.Mar 21 2021, 9:08 AM

Looks good. How about verifyFormat? Would that fail without your patch?

How about verifyFormat? Would that fail without your patch?

@HazardyKnusperkeks sorry, but not sure that I understand your point. Are you suggesting to use verifyFormat in my UT instead of EXPECT_EQ?

How about verifyFormat? Would that fail without your patch?

@HazardyKnusperkeks sorry, but not sure that I understand your point. Are you suggesting to use verifyFormat in my UT instead of EXPECT_EQ?

I'm pretty sure @MyDeveloperDay would ask for that. I would maybe use both. But what it really interesting for me if verifyFormat would fail, i.e. would clang-format misformat something previously correctly formatted.

How about verifyFormat? Would that fail without your patch?

@HazardyKnusperkeks sorry, but not sure that I understand your point. Are you suggesting to use verifyFormat in my UT instead of EXPECT_EQ?

I'm pretty sure @MyDeveloperDay would ask for that. I would maybe use both. But what it really interesting for me if verifyFormat would fail, i.e. would clang-format misformat something previously correctly formatted.

I would, see D98237: [clang-format] Option for empty lines after an access modifier. as to why.

aybassiouny updated this revision to Diff 338403.EditedApr 18 2021, 5:46 PM
aybassiouny edited the summary of this revision. (Show Details)

Sorry for the delay!

After rechecking, turns out AllowShortLambdasOnASingleLine and BeforeLambdaBody both need to be turned on in order for the regression to be expressed, this affects the UT.

Also added verifyFormat check as suggested, it does not fail btw without this patch.

After rechecking, turns out AllowShortLambdasOnASingleLine and BeforeLambdaBody both need to be turned on in order for the regression to be expressed, this affects the UT.

Please update the summary with this information.

clang/unittests/Format/FormatTest.cpp
3852

Nit.

curdeius added inline comments.Apr 19 2021, 12:45 AM
clang/lib/Format/TokenAnnotator.cpp
3498 ↗(On Diff #338403)

Please add at least asserts for Tok.Previous and Tok.Previous->Previous.

aybassiouny edited the summary of this revision. (Show Details)Apr 19 2021, 10:05 AM
aybassiouny edited the summary of this revision. (Show Details)May 24 2021, 2:26 PM

Add an assert

HazardyKnusperkeks requested changes to this revision.May 25 2021, 8:42 AM
HazardyKnusperkeks added inline comments.
clang/lib/Format/TokenAnnotator.cpp
3496–3501 ↗(On Diff #347504)

I find this really hard to read. Maybe you have to split the return.

This revision now requires changes to proceed.May 25 2021, 8:42 AM

@aybassiouny, still interested in working on this?

curdeius commandeered this revision.Jan 14 2022, 1:01 AM
curdeius edited reviewers, added: aybassiouny; removed: curdeius.

This bug is not present in clang-format 13 (nor master), but was there in v12.
I'll commandeer this revision to keep the regression tests.

curdeius updated this revision to Diff 399926.Jan 14 2022, 1:07 AM

Keep tests only. Clean up.
Rebase.

curdeius edited the summary of this revision. (Show Details)Jan 14 2022, 1:10 AM
This revision is now accepted and ready to land.Jan 14 2022, 11:56 AM
curdeius edited the summary of this revision. (Show Details)Jan 14 2022, 12:43 PM
This revision was automatically updated to reflect the committed changes.

Thanks @curdeius for checking this in, apologies for delay on my side. Glad the bug is not there in the new version!

clang/lib/Format/TokenAnnotator.cpp
3498 ↗(On Diff #338403)

I almost see no asserts despite similar usage, but sure