forked from OSchip/llvm-project
[clang-format][PR41964] Fix crash with SIGFPE when TabWidth is set to 0 and line starts with tab
Summary: clang-format 8.0 crashes with SIGFPE (floating point exception) when formatting following file: app.cpp: void a() { //line starts with '\t' } $ clang-format -style='{TabWidth: 0}' app.cpp Reviewers: owenpan, klimek, russellmcc, timwoj Reviewed By: klimek Subscribers: cfe-commits Tags: #clang-tools-extra, #clang Differential Revision: https://reviews.llvm.org/D67670 llvm-svn: 372246
This commit is contained in:
parent
ba4cad9039
commit
79983be5a0
|
@ -67,7 +67,8 @@ inline unsigned columnWidthWithTabs(StringRef Text, unsigned StartColumn,
|
|||
if (TabPos == StringRef::npos)
|
||||
return TotalWidth + columnWidth(Tail, Encoding);
|
||||
TotalWidth += columnWidth(Tail.substr(0, TabPos), Encoding);
|
||||
TotalWidth += TabWidth - (TotalWidth + StartColumn) % TabWidth;
|
||||
if (TabWidth)
|
||||
TotalWidth += TabWidth - (TotalWidth + StartColumn) % TabWidth;
|
||||
Tail = Tail.substr(TabPos + 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -657,7 +657,8 @@ FormatToken *FormatTokenLexer::getNextToken() {
|
|||
++Column;
|
||||
break;
|
||||
case '\t':
|
||||
Column += Style.TabWidth - Column % Style.TabWidth;
|
||||
Column +=
|
||||
Style.TabWidth - (Style.TabWidth ? Column % Style.TabWidth : 0);
|
||||
break;
|
||||
case '\\':
|
||||
if (i + 1 == e || (Text[i + 1] != '\r' && Text[i + 1] != '\n'))
|
||||
|
|
|
@ -815,19 +815,24 @@ void WhitespaceManager::appendIndentText(std::string &Text,
|
|||
Text.append(Spaces, ' ');
|
||||
break;
|
||||
case FormatStyle::UT_Always: {
|
||||
unsigned FirstTabWidth =
|
||||
Style.TabWidth - WhitespaceStartColumn % Style.TabWidth;
|
||||
// Insert only spaces when we want to end up before the next tab.
|
||||
if (Spaces < FirstTabWidth || Spaces == 1) {
|
||||
Text.append(Spaces, ' ');
|
||||
break;
|
||||
}
|
||||
// Align to the next tab.
|
||||
Spaces -= FirstTabWidth;
|
||||
Text.append("\t");
|
||||
if (Style.TabWidth) {
|
||||
unsigned FirstTabWidth =
|
||||
Style.TabWidth - WhitespaceStartColumn % Style.TabWidth;
|
||||
|
||||
Text.append(Spaces / Style.TabWidth, '\t');
|
||||
Text.append(Spaces % Style.TabWidth, ' ');
|
||||
// Insert only spaces when we want to end up before the next tab.
|
||||
if (Spaces < FirstTabWidth || Spaces == 1) {
|
||||
Text.append(Spaces, ' ');
|
||||
break;
|
||||
}
|
||||
// Align to the next tab.
|
||||
Spaces -= FirstTabWidth;
|
||||
Text.append("\t");
|
||||
|
||||
Text.append(Spaces / Style.TabWidth, '\t');
|
||||
Text.append(Spaces % Style.TabWidth, ' ');
|
||||
} else if (Spaces == 1) {
|
||||
Text.append(Spaces, ' ');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FormatStyle::UT_ForIndentation:
|
||||
|
@ -837,14 +842,16 @@ void WhitespaceManager::appendIndentText(std::string &Text,
|
|||
// the first one.
|
||||
if (Indentation > Spaces)
|
||||
Indentation = Spaces;
|
||||
unsigned Tabs = Indentation / Style.TabWidth;
|
||||
Text.append(Tabs, '\t');
|
||||
Spaces -= Tabs * Style.TabWidth;
|
||||
if (Style.TabWidth) {
|
||||
unsigned Tabs = Indentation / Style.TabWidth;
|
||||
Text.append(Tabs, '\t');
|
||||
Spaces -= Tabs * Style.TabWidth;
|
||||
}
|
||||
}
|
||||
Text.append(Spaces, ' ');
|
||||
break;
|
||||
case FormatStyle::UT_ForContinuationAndIndentation:
|
||||
if (WhitespaceStartColumn == 0) {
|
||||
if (WhitespaceStartColumn == 0 && Style.TabWidth) {
|
||||
unsigned Tabs = Spaces / Style.TabWidth;
|
||||
Text.append(Tabs, '\t');
|
||||
Spaces -= Tabs * Style.TabWidth;
|
||||
|
|
|
@ -9877,6 +9877,79 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {
|
|||
Tab);
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, ZeroTabWidth) {
|
||||
FormatStyle Tab = getLLVMStyleWithColumns(42);
|
||||
Tab.IndentWidth = 8;
|
||||
Tab.UseTab = FormatStyle::UT_Never;
|
||||
Tab.TabWidth = 0;
|
||||
EXPECT_EQ("void a(){\n"
|
||||
" // line starts with '\t'\n"
|
||||
"};",
|
||||
format("void a(){\n"
|
||||
"\t// line starts with '\t'\n"
|
||||
"};",
|
||||
Tab));
|
||||
|
||||
EXPECT_EQ("void a(){\n"
|
||||
" // line starts with '\t'\n"
|
||||
"};",
|
||||
format("void a(){\n"
|
||||
"\t\t// line starts with '\t'\n"
|
||||
"};",
|
||||
Tab));
|
||||
|
||||
Tab.UseTab = FormatStyle::UT_ForIndentation;
|
||||
EXPECT_EQ("void a(){\n"
|
||||
" // line starts with '\t'\n"
|
||||
"};",
|
||||
format("void a(){\n"
|
||||
"\t// line starts with '\t'\n"
|
||||
"};",
|
||||
Tab));
|
||||
|
||||
EXPECT_EQ("void a(){\n"
|
||||
" // line starts with '\t'\n"
|
||||
"};",
|
||||
format("void a(){\n"
|
||||
"\t\t// line starts with '\t'\n"
|
||||
"};",
|
||||
Tab));
|
||||
|
||||
Tab.UseTab = FormatStyle::UT_ForContinuationAndIndentation;
|
||||
EXPECT_EQ("void a(){\n"
|
||||
" // line starts with '\t'\n"
|
||||
"};",
|
||||
format("void a(){\n"
|
||||
"\t// line starts with '\t'\n"
|
||||
"};",
|
||||
Tab));
|
||||
|
||||
EXPECT_EQ("void a(){\n"
|
||||
" // line starts with '\t'\n"
|
||||
"};",
|
||||
format("void a(){\n"
|
||||
"\t\t// line starts with '\t'\n"
|
||||
"};",
|
||||
Tab));
|
||||
|
||||
Tab.UseTab = FormatStyle::UT_Always;
|
||||
EXPECT_EQ("void a(){\n"
|
||||
"// line starts with '\t'\n"
|
||||
"};",
|
||||
format("void a(){\n"
|
||||
"\t// line starts with '\t'\n"
|
||||
"};",
|
||||
Tab));
|
||||
|
||||
EXPECT_EQ("void a(){\n"
|
||||
"// line starts with '\t'\n"
|
||||
"};",
|
||||
format("void a(){\n"
|
||||
"\t\t// line starts with '\t'\n"
|
||||
"};",
|
||||
Tab));
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, CalculatesOriginalColumn) {
|
||||
EXPECT_EQ("\"qqqqqqqqqqqqqqqqqqqqqqqqqq\\\n"
|
||||
"q\"; /* some\n"
|
||||
|
|
Loading…
Reference in New Issue