On Thu, Sep 19, 2024 at 4:35 PM Jakub Jelinek <ja...@redhat.com> wrote: > > On Thu, Sep 19, 2024 at 08:17:24AM +0200, Richard Biener wrote: > > On Wed, Sep 18, 2024 at 7:33 PM Jakub Jelinek <ja...@redhat.com> wrote: > > > > > > On Wed, Sep 18, 2024 at 06:17:58PM +0100, Richard Sandiford wrote: > > > > +1 I'd much rather learn about this kind of error before the code > > > > reaches > > > > a review tool :) > > > > > > > > >From a quick check, it doesn't look like Clang has this, so there is no > > > > existing name to follow. > > > > > > I was considering also -Wtrailing-whitespace, but > > > 1) git diff really warns just about trailing spaces/tabs, not form feeds > > > or > > > vertical tabs > > > 2) gcc source contains tons of spots with form feed in it (though, > > > I think pretty much always as the sole character on a line). > > > And not really sure how people use vertical tabs in the source if at all. > > > Perhaps form feed could be not warned if at end of line if it isn't the > > > sole > > > character on a line... > > > > Generally I like diagnosing this early. For the above I'd say > > -Wtrailing-whitespace= > > with a set of things to diagnose (and a sane default - just spaces and > > tabs - for > > -Wtrailiing-whitespace) would be nice. As for naming possibly follow the > > is{space,blank,cntrl} character classifications? If those are a good > > fit, that is. > > Here is a patch which currently allows blank (' ' '\t') and space (' ' '\t' > '\f' '\v'), cntrl not yet added, not anything non-ASCII, but in theory could > be added later (though, non-ASCII would be just for inside of comments, > say non-breaking space etc. in the source is otherwise an error). > > Bootstrapped/regtested on x86_64-linux and i686-linux. >
I think this is getting too complex now; I preferred the simpler version... > 2024-09-19 Jakub Jelinek <ja...@redhat.com> > > libcpp/ > * include/cpplib.h (struct cpp_options): Add > cpp_warn_trailing_whitespace member. > (enum cpp_warning_reason): Add CPP_W_TRAILING_WHITESPACE. > * internal.h (struct _cpp_line_note): Document 'W' line note. > * lex.cc (_cpp_clean_line): Add 'W' line note for trailing whitespace > except for trailing whitespace after backslash. Formatting fix. > (_cpp_process_line_notes): Emit -Wtrailing-whitespace diagnostics. > Formatting fixes. > (lex_raw_string): Clear type on 'W' notes. > gcc/ > * doc/invoke.texi (Wtrailing-whitespace): Document. > gcc/c-family/ > * c.opt (Wtrailing-whitespace=): New option. > (Wtrailing-whitespace): New alias. > gcc/testsuite/ > * c-c++-common/cpp/Wtrailing-whitespace-1.c: New test. > * c-c++-common/cpp/Wtrailing-whitespace-2.c: New test. > * c-c++-common/cpp/Wtrailing-whitespace-3.c: New test. > * c-c++-common/cpp/Wtrailing-whitespace-4.c: New test. > * c-c++-common/cpp/Wtrailing-whitespace-5.c: New test. > > --- libcpp/include/cpplib.h.jj 2024-09-13 16:09:32.690455174 +0200 > +++ libcpp/include/cpplib.h 2024-09-19 16:59:09.674903649 +0200 > @@ -594,6 +594,9 @@ struct cpp_options > /* True if -finput-charset= option has been used explicitly. */ > bool cpp_input_charset_explicit; > > + /* -Wtrailing-whitespace= value. */ > + unsigned char cpp_warn_trailing_whitespace; > + > /* Dependency generation. */ > struct > { > @@ -709,7 +712,8 @@ enum cpp_warning_reason { > CPP_W_EXPANSION_TO_DEFINED, > CPP_W_BIDIRECTIONAL, > CPP_W_INVALID_UTF8, > - CPP_W_UNICODE > + CPP_W_UNICODE, > + CPP_W_TRAILING_WHITESPACE > }; > > /* Callback for header lookup for HEADER, which is the name of a > --- libcpp/internal.h.jj 2024-09-18 09:45:36.832570227 +0200 > +++ libcpp/internal.h 2024-09-19 16:54:56.610321817 +0200 > @@ -318,8 +318,8 @@ struct _cpp_line_note > > /* Type of note. The 9 'from' trigraph characters represent those > trigraphs, '\\' an escaped newline, ' ' an escaped newline with > - intervening space, 0 represents a note that has already been handled, > - and anything else is invalid. */ > + intervening space, 'W' trailing whitespace, 0 represents a note that > + has already been handled, and anything else is invalid. */ > unsigned int type; > }; > > --- libcpp/lex.cc.jj 2024-09-13 16:09:32.720454758 +0200 > +++ libcpp/lex.cc 2024-09-19 16:58:37.434339128 +0200 > @@ -928,7 +928,7 @@ _cpp_clean_line (cpp_reader *pfile) > if (p == buffer->next_line || p[-1] != '\\') > break; > > - add_line_note (buffer, p - 1, p != d ? ' ': '\\'); > + add_line_note (buffer, p - 1, p != d ? ' ' : '\\'); > d = p - 2; > buffer->next_line = p - 1; > } > @@ -943,6 +943,20 @@ _cpp_clean_line (cpp_reader *pfile) > } > } > } > + done: > + if (d > buffer->next_line > + && CPP_OPTION (pfile, cpp_warn_trailing_whitespace)) > + switch (CPP_OPTION (pfile, cpp_warn_trailing_whitespace)) > + { > + case 1: > + if (ISBLANK (d[-1])) > + add_line_note (buffer, d - 1, 'W'); > + break; > + case 2: > + if (IS_NVSPACE (d[-1]) && d[-1]) > + add_line_note (buffer, d - 1, 'W'); > + break; > + } > } > else > { > @@ -955,7 +969,6 @@ _cpp_clean_line (cpp_reader *pfile) > s++; > } > > - done: > *d = '\n'; > /* A sentinel note that should never be processed. */ > add_line_note (buffer, d + 1, '\n'); > @@ -1013,13 +1026,23 @@ _cpp_process_line_notes (cpp_reader *pfi > > if (note->type == '\\' || note->type == ' ') > { > - if (note->type == ' ' && !in_comment) > - cpp_error_with_line (pfile, CPP_DL_WARNING, > pfile->line_table->highest_line, col, > - "backslash and newline separated by space"); > + if (note->type == ' ') > + { > + if (!in_comment) > + cpp_error_with_line (pfile, CPP_DL_WARNING, > + pfile->line_table->highest_line, col, > + "backslash and newline separated by " > + "space"); > + else if (CPP_OPTION (pfile, cpp_warn_trailing_whitespace)) > + cpp_warning_with_line (pfile, CPP_W_TRAILING_WHITESPACE, > + pfile->line_table->highest_line, col, > + "trailing whitespace"); > + } > > if (buffer->next_line > buffer->rlimit) > { > - cpp_error_with_line (pfile, CPP_DL_PEDWARN, > pfile->line_table->highest_line, col, > + cpp_error_with_line (pfile, CPP_DL_PEDWARN, > + pfile->line_table->highest_line, col, > "backslash-newline at end of file"); > /* Prevent "no newline at end of file" warning. */ > buffer->next_line = buffer->rlimit; > @@ -1040,15 +1063,16 @@ _cpp_process_line_notes (cpp_reader *pfi > note->type, > (int) _cpp_trigraph_map[note->type]); > else > - { > - cpp_warning_with_line > - (pfile, CPP_W_TRIGRAPHS, > - pfile->line_table->highest_line, col, > - "trigraph ??%c ignored, use -trigraphs to enable", > - note->type); > - } > + cpp_warning_with_line (pfile, CPP_W_TRIGRAPHS, > + pfile->line_table->highest_line, col, > + "trigraph ??%c ignored, use -trigraphs > " > + "to enable", note->type); > } > } > + else if (note->type == 'W') > + cpp_warning_with_line (pfile, CPP_W_TRAILING_WHITESPACE, > + pfile->line_table->highest_line, col, > + "trailing whitespace"); > else if (note->type == 0) > /* Already processed in lex_raw_string. */; > else > @@ -2539,6 +2563,12 @@ lex_raw_string (cpp_reader *pfile, cpp_t > note->type = 0; > note++; > break; > + > + case 'W': > + /* Don't warn about trailing whitespace in raw string literals. > */ > + note->type = 0; > + note++; > + break; > > default: > gcc_checking_assert (_cpp_trigraph_map[note->type]); > --- gcc/doc/invoke.texi.jj 2024-09-12 18:15:20.458626277 +0200 > +++ gcc/doc/invoke.texi 2024-09-19 17:18:14.730458180 +0200 > @@ -413,7 +413,8 @@ Objective-C and Objective-C++ Dialects}. > > -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} > -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum > -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand > --Wsystem-headers -Wtautological-compare -Wtrampolines -Wtrigraphs > +-Wsystem-headers -Wtautological-compare -Wtrailing-whitespace > +-Wtrailing-whitespace=@var{kind} -Wtrampolines -Wtrigraphs > -Wtrivial-auto-var-init -Wno-tsan -Wtype-limits -Wundef > -Wuninitialized -Wunknown-pragmas > -Wunsuffixed-float-constants > @@ -8996,6 +8997,21 @@ will always be false. > > This warning is enabled by @option{-Wall}. > > +@opindex Wtrailing-whitespace > +@opindex Wno-trailing-whitespace > +@opindex Wtrailing-whitespace= > +@item -Wtrailing-whitespace > +@itemx -Wtrailing-whitespace=@var{kind} > +Warn about trailing whitespace at the end of lines, including inside of > +comments, but excluding trailing whitespace in raw string literals. > +@code{-Wtrailing-whitespace} is equivalent to > +@code{-Wtrailing-whitespace=blank} and warns just about trailing space and > +horizontal tab characters. @code{-Wtrailing-whitespace=space} warns about > +those or trailing form feed or vertical tab characters. > +@code{-Wno-trailing-whitespace} or @code{-Wtrailing-whitespace=none} > +disables the warning, which is the default. > +This is a coding style warning. > + > @opindex Wtrampolines > @opindex Wno-trampolines > @item -Wtrampolines > --- gcc/c-family/c.opt.jj 2024-09-12 18:15:20.415626861 +0200 > +++ gcc/c-family/c.opt 2024-09-19 17:10:50.463448288 +0200 > @@ -1450,6 +1450,26 @@ Wtraditional-conversion > C ObjC Var(warn_traditional_conversion) Warning > Warn of prototypes causing type conversions different from what would happen > in the absence of prototype. > > +Enum > +Name(warn_trailing_whitespace_kind) Type(int) UnknownError(argument %qs to > %<-Wtrailing-whitespace=%> not recognized) > + > +EnumValue > +Enum(warn_trailing_whitespace_kind) String(none) Value(0) > + > +EnumValue > +Enum(warn_trailing_whitespace_kind) String(blank) Value(1) > + > +EnumValue > +Enum(warn_trailing_whitespace_kind) String(space) Value(2) > + > +Wtrailing-whitespace= > +C ObjC C++ ObjC++ CPP(cpp_warn_trailing_whitespace) > CppReason(CPP_W_TRAILING_WHITESPACE) Enum(warn_trailing_whitespace_kind) > Joined RejectNegative Var(warn_trailing_whitespace) Init(0) Warning > +Warn about trailing whitespace on lines except when in raw string literals. > + > +Wtrailing-whitespace > +C ObjC C++ ObjC++ Alias(Wtrailing-whitespace=,blank,none) Warning > +Warn about trailing whitespace on lines except when in raw string literals. > Equivalent to Wtrailing-whitespace=blank when enabled or > Wtrailing-whitespace=none when disabled. > + > Wtrigraphs > C ObjC C++ ObjC++ CPP(warn_trigraphs) CppReason(CPP_W_TRIGRAPHS) > Var(cpp_warn_trigraphs) Init(2) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) > Warn if trigraphs are encountered that might affect the meaning of the > program. > --- gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-1.c.jj 2024-09-18 > 14:44:22.712636656 +0200 > +++ gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-1.c 2024-09-19 > 17:40:36.972655199 +0200 > @@ -0,0 +1,37 @@ > +/* { dg-do compile { target { c || c++11 } } } */ > +/* { dg-options "-Wtrailing-whitespace" } */ > + > +int i; > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +int j; > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +int \ > + k \ > + ; > +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* > } .-3 } */ > +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* > } .-3 } */ > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-3 } */ > + > + > + > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > + > + > + > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +const char *p = R"*|*( > + > + > +. > +)*|*"; > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +// This is a comment with trailing whitespace > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +/* This is a comment with trailing whitespace > +*/ > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-2 } */ > +// This is a comment with trailing whitespace > +/* This is a comment with trailing whitespace > +*/ > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .+1 } */ > + > \ No newline at end of file > --- gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-2.c.jj 2024-09-19 > 17:31:57.169567809 +0200 > +++ gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-2.c 2024-09-19 > 17:40:43.709563785 +0200 > @@ -0,0 +1,37 @@ > +/* { dg-do compile { target { c || c++11 } } } */ > +/* { dg-options "-Wtrailing-whitespace=blank" } */ > + > +int i; > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +int j; > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +int \ > + k \ > + ; > +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* > } .-3 } */ > +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* > } .-3 } */ > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-3 } */ > + > + > + > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > + > + > + > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +const char *p = R"*|*( > + > + > +. > +)*|*"; > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +// This is a comment with trailing whitespace > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +/* This is a comment with trailing whitespace > +*/ > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-2 } */ > +// This is a comment with trailing whitespace > +/* This is a comment with trailing whitespace > +*/ > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .+1 } */ > + > \ No newline at end of file > --- gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-3.c.jj 2024-09-19 > 17:32:20.467260617 +0200 > +++ gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-3.c 2024-09-19 > 17:40:50.284474568 +0200 > @@ -0,0 +1,43 @@ > +/* { dg-do compile { target { c || c++11 } } } */ > +/* { dg-options "-Wtrailing-whitespace=space" } */ > + > +int i; > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +int j; > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +int \ > + k \ > + ; > +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* > } .-3 } */ > +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* > } .-3 } */ > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-3 } */ > + > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > + > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > + > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > + > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > + > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > + > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +const char *p = R"*|*( > + > + > +. > +)*|*"; > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +// This is a comment with trailing whitespace > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +/* This is a comment with trailing whitespace > +*/ > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-2 } */ > +// This is a comment with trailing whitespace > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-1 } */ > +/* This is a comment with trailing whitespace > +*/ > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .-2 } */ > +/* { dg-warning "trailing whitespace" "" { target *-*-* } .+1 } */ > + > \ No newline at end of file > --- gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-4.c.jj 2024-09-19 > 17:33:02.531705971 +0200 > +++ gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-4.c 2024-09-19 > 17:41:21.131056009 +0200 > @@ -0,0 +1,28 @@ > +/* { dg-do compile { target { c || c++11 } } } */ > +/* { dg-options "-Wtrailing-whitespace=none" } */ > + > +int i; > +int j; > +int \ > + k \ > + ; > +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* > } .-3 } */ > +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* > } .-3 } */ > + > + > + > + > + > + > +const char *p = R"*|*( > + > + > +. > +)*|*"; > +// This is a comment with trailing whitespace > +/* This is a comment with trailing whitespace > +*/ > +// This is a comment with trailing whitespace > +/* This is a comment with trailing whitespace > +*/ > + > \ No newline at end of file > --- gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-5.c.jj 2024-09-19 > 17:33:45.427140375 +0200 > +++ gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-5.c 2024-09-19 > 17:41:28.352958013 +0200 > @@ -0,0 +1,28 @@ > +/* { dg-do compile { target { c || c++11 } } } */ > +/* { dg-options "-Wno-trailing-whitespace" } */ > + > +int i; > +int j; > +int \ > + k \ > + ; > +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* > } .-3 } */ > +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* > } .-3 } */ > + > + > + > + > + > + > +const char *p = R"*|*( > + > + > +. > +)*|*"; > +// This is a comment with trailing whitespace > +/* This is a comment with trailing whitespace > +*/ > +// This is a comment with trailing whitespace > +/* This is a comment with trailing whitespace > +*/ > + > \ No newline at end of file > > > Jakub >