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

[clang-format] Fix crashes in AlignArrayOfStructures #72520

Merged
merged 4 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion clang/lib/Format/WhitespaceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1316,6 +1316,8 @@ void WhitespaceManager::alignArrayInitializersRightJustified(
auto Offset = std::distance(Cells.begin(), CellIter);
for (const auto *Next = CellIter->NextColumnElement; Next;
Next = Next->NextColumnElement) {
if (RowCount >= CellDescs.CellCounts.size())
break;
Comment on lines 1317 to +1320
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (const auto *Next = CellIter->NextColumnElement; Next;
Next = Next->NextColumnElement) {
if (RowCount >= CellDescs.CellCounts.size())
break;
for (const auto *Next = CellIter->NextColumnElement; Next && RowCount < CellDescs.CellCounts.size();
Next = Next->NextColumnElement, ++RowCount) {

Maybe?

Then the ++RowCount below must be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intentionally made it the same as lines 1384-1385 below so that lines 1315-1323 would remain copy-pasted from lines 1380-1388. This will make future refactoring easier.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change the other lines too. I think it's better to see the condition in the for, but it's your call.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same/similar code appeared twice in this file and once in the header file. If I were to refactor it, I might not use the same for-loop, so I'll leave it as is for now. (There are also much more cleanup that can be done with this option, but I don't know if it's worthwhile as it's so buggy even after @mydeveloperday limited it to matrices.)

auto *Start = (Cells.begin() + RowCount * CellDescs.CellCounts[0]);
auto *End = Start + Offset;
ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
Expand Down Expand Up @@ -1379,7 +1381,7 @@ void WhitespaceManager::alignArrayInitializersLeftJustified(
auto Offset = std::distance(Cells.begin(), CellIter);
for (const auto *Next = CellIter->NextColumnElement; Next;
Next = Next->NextColumnElement) {
if (RowCount > CellDescs.CellCounts.size())
if (RowCount >= CellDescs.CellCounts.size())
break;
auto *Start = (Cells.begin() + RowCount * CellDescs.CellCounts[0]);
auto *End = Start + Offset;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Format/WhitespaceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ class WhitespaceManager {
auto Offset = std::distance(CellStart, CellStop);
for (const auto *Next = CellStop->NextColumnElement; Next;
Next = Next->NextColumnElement) {
if (RowCount > MaxRowCount)
if (RowCount >= MaxRowCount)
break;
auto Start = (CellStart + RowCount * CellCount);
auto End = Start + Offset;
Expand Down
39 changes: 39 additions & 0 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20709,6 +20709,18 @@ TEST_F(FormatTest, CatchExceptionReferenceBinding) {
TEST_F(FormatTest, CatchAlignArrayOfStructuresRightAlignment) {
auto Style = getLLVMStyle();
Style.AlignArrayOfStructures = FormatStyle::AIAS_Right;

verifyNoCrash("f({\n"
"table({}, table({{\"\", false}}, {}))\n"
"});",
Style);
verifyNoCrash("Bar a[1] = {\n"
" #define buf(a, b) \\\n"
" { #a, #b },\n"
" { Test, bar }\n"
"};",
Style);
owenca marked this conversation as resolved.
Show resolved Hide resolved

Style.AlignConsecutiveAssignments.Enabled = true;
Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("struct test demo[] = {\n"
Expand Down Expand Up @@ -21140,6 +21152,33 @@ TEST_F(FormatTest, CatchAlignArrayOfStructuresLeftAlignment) {
"that really, in any just world, ought to be split over multiple "
"lines\"},{-1, 93463, \"world\"},{7, 5, \"!!\"},};",
Style);

Style.ColumnLimit = 25;
verifyNoCrash("Type foo{\n"
" {\n"
" 1, // A\n"
" 2, // B\n"
" 3, // C\n"
" },\n"
" \"hello\",\n"
"};",
Style);
verifyNoCrash("Type object[X][Y] = {\n"
" {{val}, {val}, {val}},\n"
" {{val}, {val}, // some comment\n"
" {val}}\n"
"};",
Style);

Style.ColumnLimit = 120;
verifyNoCrash(
"T v[] {\n"
" { AAAAAAAAAAAAAAAAAAAAAAAAA::aaaaaaaaaaaaaaaaaaa, "
"AAAAAAAAAAAAAAAAAAAAAAAAA::aaaaaaaaaaaaaaaaaaaaaaaa, 1, 0.000000000f, "
"\"00000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000000000\" },\n"
"};",
Style);
}

TEST_F(FormatTest, UnderstandsPragmas) {
Expand Down