Skip to content

Commit cb990cd

Browse files
committed
[Format] Invert nestingAndIndentLevel pair in WhitespaceManager used for
alignments Indent should be compared before nesting level to determine if a token is on the same scope as the one we align with. Because it was inverted, clang-format sometimes tried to align tokens with tokens from outer scopes, causing the assert(Shift >= 0) to fire. This fixes bug #33507. Patch by Beren Minor, thank you! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@311792 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 8846be3 commit cb990cd

File tree

3 files changed

+21
-12
lines changed

3 files changed

+21
-12
lines changed

lib/Format/WhitespaceManager.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,12 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches,
246246

247247
for (unsigned i = Start; i != End; ++i) {
248248
if (ScopeStack.size() != 0 &&
249-
Changes[i].nestingAndIndentLevel() <
250-
Changes[ScopeStack.back()].nestingAndIndentLevel())
249+
Changes[i].indentAndNestingLevel() <
250+
Changes[ScopeStack.back()].indentAndNestingLevel())
251251
ScopeStack.pop_back();
252252

253-
if (i != Start && Changes[i].nestingAndIndentLevel() >
254-
Changes[i - 1].nestingAndIndentLevel())
253+
if (i != Start && Changes[i].indentAndNestingLevel() >
254+
Changes[i - 1].indentAndNestingLevel())
255255
ScopeStack.push_back(i);
256256

257257
bool InsideNestedScope = ScopeStack.size() != 0;
@@ -327,8 +327,8 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
327327

328328
// Measure the scope level (i.e. depth of (), [], {}) of the first token, and
329329
// abort when we hit any token in a higher scope than the starting one.
330-
auto NestingAndIndentLevel = StartAt < Changes.size()
331-
? Changes[StartAt].nestingAndIndentLevel()
330+
auto IndentAndNestingLevel = StartAt < Changes.size()
331+
? Changes[StartAt].indentAndNestingLevel()
332332
: std::pair<unsigned, unsigned>(0, 0);
333333

334334
// Keep track of the number of commas before the matching tokens, we will only
@@ -359,7 +359,7 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
359359

360360
unsigned i = StartAt;
361361
for (unsigned e = Changes.size(); i != e; ++i) {
362-
if (Changes[i].nestingAndIndentLevel() < NestingAndIndentLevel)
362+
if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
363363
break;
364364

365365
if (Changes[i].NewlinesBefore != 0) {
@@ -375,7 +375,7 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
375375

376376
if (Changes[i].Tok->is(tok::comma)) {
377377
++CommasBeforeMatch;
378-
} else if (Changes[i].nestingAndIndentLevel() > NestingAndIndentLevel) {
378+
} else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
379379
// Call AlignTokens recursively, skipping over this scope block.
380380
unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
381381
i = StoppedAt - 1;

lib/Format/WhitespaceManager.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,11 @@ class WhitespaceManager {
154154
const Change *StartOfBlockComment;
155155
int IndentationOffset;
156156

157-
// A combination of nesting level and indent level, which are used in
157+
// A combination of indent level and nesting level, which are used in
158158
// tandem to compute lexical scope, for the purposes of deciding
159159
// when to stop consecutive alignment runs.
160-
std::pair<unsigned, unsigned>
161-
nestingAndIndentLevel() const {
162-
return std::make_pair(Tok->NestingLevel, Tok->IndentLevel);
160+
std::pair<unsigned, unsigned> indentAndNestingLevel() const {
161+
return std::make_pair(Tok->IndentLevel, Tok->NestingLevel);
163162
}
164163
};
165164

unittests/Format/FormatTest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8958,6 +8958,16 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
89588958
Alignment);
89598959
Alignment.BinPackParameters = true;
89608960
Alignment.ColumnLimit = 80;
8961+
8962+
// Bug 33507
8963+
Alignment.PointerAlignment = FormatStyle::PAS_Middle;
8964+
verifyFormat(
8965+
"auto found = range::find_if(vsProducts, [&](auto * aProduct) {\n"
8966+
" static const Version verVs2017;\n"
8967+
" return true;\n"
8968+
"});\n",
8969+
Alignment);
8970+
Alignment.PointerAlignment = FormatStyle::PAS_Right;
89618971
}
89628972

89638973
TEST_F(FormatTest, LinuxBraceBreaking) {

0 commit comments

Comments
 (0)