this allow much better support of codebases like the linux kernel that mix tabs and spaces.
-ftabstop=Width allow specifying how large tabs are considered to be.
Differential D71037
[Diagnostic] Add ftabstop to -Wmisleading-indentation Tyker on Dec 4 2019, 3:07 PM. Authored by
Details this allow much better support of codebases like the linux kernel that mix tabs and spaces. -ftabstop=Width allow specifying how large tabs are considered to be.
Diff Detail Event Timeline
Comment Actions i ran a build of the linux kernel using the stage1 compiler, about 30% of files crashed the compiler in the optimizer. everything was building fine 2 weeks ago with the same configuration but a previous compiler.
Comment Actions Adding @rsmith to weigh in on the default behavior.
Comment Actions If we want correct visual columns, we have more work to do: we need to do UTF-8 decoding and use llvm::sys::locale::columnWidth to compute widths of individual characters (byteToColumn in TextDiagnostic.cpp already does this when printing caret diagnostics). Maybe instead of changing the source manager, we should expose the byte <-> column map from the diagnostic printer and use it from the misleading indentation warning? Or perhaps we can provide an optimized form of it on the basis that we only care about the column number of the first non-whitespace character in the line (so we only need to deal with tabs and spaces) -- but then it's very clear that this is specific to misleading indentation and not a general computation that belongs in the source manager.
Comment Actions my intent was not necessarily to create a generic solution but to get a solution that is sufficient to not have false positives on the Wmisleading-indentation warning for code base that have mixes of tabs and spaces. after taking a look at SourceColumnMap and byteToColumn this seems like way overkill for what i am trying to solve.
i did not found such a mapping. after fixing the bug rsmith spotted. there is no test failures in clang + clang-tool + clangd with UseTabStopOption = true (i found this quite surprising but i double checked). the previous test result were incorrect due to this bug sorry. however I am still not sure that UseTabStopOption = true is the right default for every uses of getSpellingColumnNumber. one visible example of the impact is the indentation in diagnostics on code indented with tabs. test.cpp:5:3: warning: misleading indentation; statement is not part of the previous 'if' return 0; ^ test.cpp:3:2: note: previous statement is here if (0) ^ 1 warning generated. with ftabstop = 2 test.cpp:5:3: warning: misleading indentation; statement is not part of the previous 'if' return 0; ^ test.cpp:3:2: note: previous statement is here if (0) ^ 1 warning generated. i don't know if this is a good thing, i never coded with tabs so i don't know the habits.
Comment Actions I think that would be a bad idea. The column numbers are often typically used as offsets (e.g. in diagnostics/etc, that's the expectation) and shouldn't generally be changed to visual offsets.
That was already the case -- that's basically the only part of Clang which used TabStop already. I'm not sure this code really needs to be in SourceManager -- it seems maybe simple enough to just special case within MisleadingIndentationChecker, e.g. something like this function: // Figure out the visually-apparent column number for a SourceLocation, using // the TabStop value, from the "-ftabstop" option, to expand tabs. unsigned GetVisualColumnNum(SourceLocation Loc) { SourceManager &SM = P.getPreprocessor().getSourceManager(); unsigned TabStop = P.getActions().getDiagnostics().getDiagnosticOptions().TabStop; unsigned ColNo = SM.getSpellingColumnNumber(Loc); if (ColNo == 0 || TabStop == 1) return ColNo; auto FIDAndOffset = SM.getDecomposedLoc(Loc); bool Invalid; StringRef BufData = SM.getBufferData(FIDAndOffset.first, &Invalid); if (Invalid) return 0; const char *EndPos = BufData.data() + FIDAndOffset.second; assert(FIDAndOffset.second > ColNo && "Column number smaller than file offset?"); unsigned VisualColumn = 0; // stored as 0-based column, here. // Loop from beginning of line up to Loc's file position, counting columns, expanding tabs for (const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos; ++CurPos) { if (*CurPos == '\t') // Advance visual column to next tabstop VisualColumn += (TabStop - VisualColumn % TabStop); else VisualColumn++; } return VisualColumn + 1; }
This comment was removed by Tyker. Comment Actions This broke my builds. A configure test that tries to compile int main (void) { for( int i = 0; i < 9; i++ ); return 0; } (a single line source file), with -Wall enabled, now triggers failed asserts: clang-10: ../tools/clang/lib/Parse/ParseStmt.cpp:1236: static unsigned int {anonymous}::MisleadingIndentationChecker::getVisualIndentation(clang::SourceManager&, clang::SourceLocation): Assertion `FIDAndOffset.second > ColNo && "Column number smaller than file offset?"' failed. <cut> 1. oneline.c:1:49: current parser token 'return' 2. oneline.c:1:17: parsing function body 'main' 3. oneline.c:1:17: in compound statement ('{}') Comment Actions This update should fixes the issue. however the issue can only occur for on the first line. so we can't have a run line. before it to add a test case. Comment Actions as i said. the bug can only occur for one line files. so we can't have a run line and a the crashing line. so i wasn't able to make a test for it. Comment Actions Is it possible to have the RUN bit at the end of the line in a comment, after the test code itself? Comment Actions I just ran into this warning, and I think there's a bit of a discoverability problem related to the width of tabs and -ftabstop. If you have mixed tabs and spaces, and you've correctly specified the tab stop width with -ftabstop, everything works fine. If you haven't specified -ftabstop, you get a warning, and the issue isn't obvious. Depending on your editor settings, the code might look fine at first glance, and the warning text doesn't mention -ftabstop at all. Maybe there's something that could be improved here, if we're printing a warning for two lines with mismatched indentation styles? Comment Actions i agree that this is not obvious. i added a patch to improve this https://reviews.llvm.org/D75009. |
Typo