Author: paulhoad Date: Wed Sep 18 11:57:09 2019 New Revision: 372246 URL: http://llvm.org/viewvc/llvm-project?rev=372246&view=rev Log: [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 Modified: cfe/trunk/lib/Format/Encoding.h cfe/trunk/lib/Format/FormatTokenLexer.cpp cfe/trunk/lib/Format/WhitespaceManager.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/lib/Format/Encoding.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Encoding.h?rev=372246&r1=372245&r2=372246&view=diff ============================================================================== --- cfe/trunk/lib/Format/Encoding.h (original) +++ cfe/trunk/lib/Format/Encoding.h Wed Sep 18 11:57:09 2019 @@ -67,7 +67,8 @@ inline unsigned columnWidthWithTabs(Stri 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); } } Modified: cfe/trunk/lib/Format/FormatTokenLexer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatTokenLexer.cpp?rev=372246&r1=372245&r2=372246&view=diff ============================================================================== --- cfe/trunk/lib/Format/FormatTokenLexer.cpp (original) +++ cfe/trunk/lib/Format/FormatTokenLexer.cpp Wed Sep 18 11:57:09 2019 @@ -657,7 +657,8 @@ FormatToken *FormatTokenLexer::getNextTo ++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')) Modified: cfe/trunk/lib/Format/WhitespaceManager.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/WhitespaceManager.cpp?rev=372246&r1=372245&r2=372246&view=diff ============================================================================== --- cfe/trunk/lib/Format/WhitespaceManager.cpp (original) +++ cfe/trunk/lib/Format/WhitespaceManager.cpp Wed Sep 18 11:57:09 2019 @@ -815,19 +815,24 @@ void WhitespaceManager::appendIndentText 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) { + if (Style.TabWidth) { + 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"); + + Text.append(Spaces / Style.TabWidth, '\t'); + Text.append(Spaces % Style.TabWidth, ' '); + } else if (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, ' '); break; } case FormatStyle::UT_ForIndentation: @@ -837,14 +842,16 @@ void WhitespaceManager::appendIndentText // 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; Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=372246&r1=372245&r2=372246&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Wed Sep 18 11:57:09 2019 @@ -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" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits