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

Conversation

owenca
Copy link
Contributor

@owenca owenca commented Nov 16, 2023

Fixed #54815.
Fixed #55269.
Fixed #55493.
Fixed #68431.

@llvmbot
Copy link
Member

llvmbot commented Nov 16, 2023

@llvm/pr-subscribers-clang-format

Author: Owen Pan (owenca)

Changes

Fixed #55493.
Fixed #68431.


Full diff: https://github.com/llvm/llvm-project/pull/72520.diff

3 Files Affected:

  • (modified) clang/lib/Format/WhitespaceManager.cpp (+3-1)
  • (modified) clang/lib/Format/WhitespaceManager.h (+1-1)
  • (modified) clang/unittests/Format/FormatTest.cpp (+18)
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 32d8b97cc8dadb1..3bc6915b8df0a70 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -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;
           auto *Start = (Cells.begin() + RowCount * CellDescs.CellCounts[0]);
           auto *End = Start + Offset;
           ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
@@ -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;
diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h
index df7e9add1cd446f..69398fe411502f1 100644
--- a/clang/lib/Format/WhitespaceManager.h
+++ b/clang/lib/Format/WhitespaceManager.h
@@ -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;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index a12a20359c2fad2..cd4c93e8427723f 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -21140,6 +21140,24 @@ 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 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) {

Comment on lines 1317 to +1320
for (const auto *Next = CellIter->NextColumnElement; Next;
Next = Next->NextColumnElement) {
if (RowCount >= CellDescs.CellCounts.size())
break;
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.)

@owenca
Copy link
Contributor Author

owenca commented Nov 17, 2023

We probably should backport it to 17.0.6. What do you all think? @tru

@tru
Copy link
Collaborator

tru commented Nov 17, 2023

We probably should backport it to 17.0.6. What do you all think? @tru

Yep - seems like a good and small fix to have in 17.x

@tru
Copy link
Collaborator

tru commented Nov 17, 2023

@owenca I picked da1b1fba5cfd41521a840202d8cf4c3796c5e10b on top of the 17.x branch and my test case was not fixed, it still crashes in the same way as described in #72628

@owenca
Copy link
Contributor Author

owenca commented Nov 17, 2023

@owenca I picked da1b1fba5cfd41521a840202d8cf4c3796c5e10b on top of the 17.x branch and my test case was not fixed, it still crashes in the same way as described in #72628

Thanks for trying it on 17.x. We can't backport it then.

@tru
Copy link
Collaborator

tru commented Nov 17, 2023

Thanks for trying it on 17.x. We can't backport it then.

Any idea if there is another workaround or fix that we could do to target 17.x? 18 is still pretty far off and clang-format for 17 will soon be included in a lot of downstream tools. Happy to help out fixing it if you have any pointers.

Copy link
Member

@rymiel rymiel left a comment

Choose a reason for hiding this comment

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

Thanks for doing this! There were probably dozens of duplicates of this same crash across multiple years, so this is great

@owenca
Copy link
Contributor Author

owenca commented Nov 17, 2023

Thanks for trying it on 17.x. We can't backport it then.

Any idea if there is another workaround or fix that we could do to target 17.x? 18 is still pretty far off and clang-format for 17 will soon be included in a lot of downstream tools. Happy to help out fixing it if you have any pointers.

My bad. #72628 was already "fixed" on 18 before this patch. Can you help bisect it?

@owenca owenca merged commit 5679f55 into llvm:main Nov 17, 2023
2 of 3 checks passed
@owenca owenca deleted the 55493 branch November 17, 2023 22:35
sr-tream pushed a commit to sr-tream/llvm-project that referenced this pull request Nov 20, 2023
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
tru pushed a commit that referenced this pull request Nov 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants