diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 1f2e72a0bb7346f11b2f3116be1752b6d643ee79..f758d7b941c03bac4c7dc4327218ad441ac13f81 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1466,6 +1466,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. diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls index b1593ef41401e7833b25ae023906fa010a3c25f9..c1738095e6dd5b0530178cc74fa4d4f2d80d7982 100644 --- a/gcc/c-family/c.opt.urls +++ b/gcc/c-family/c.opt.urls @@ -864,6 +864,12 @@ UrlSuffix(gcc/Warning-Options.html#index-Wno-traditional) Wtraditional-conversion UrlSuffix(gcc/Warning-Options.html#index-Wno-traditional-conversion) +Wtrailing-whitespace= +UrlSuffix(gcc/Warning-Options.html#index-Wno-trailing-whitespace) + +Wtrailing-whitespace +UrlSuffix(gcc/Warning-Options.html#index-Wno-trailing-whitespace) + Wtrigraphs UrlSuffix(gcc/Warning-Options.html#index-Wtrigraphs) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 575dffd2a2f5ab895ec2e35348ef5b8d2d5a9a59..4f4ca63754950d578f25e9474f610bf7e9b85d67 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -414,7 +414,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 @@ -8773,6 +8774,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 diff --git a/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-1.c b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-1.c new file mode 100644 index 0000000000000000000000000000000000000000..ccfed0013c9462d61ecaac8e1c89dcf2b21b0bd9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-1.c @@ -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 diff --git a/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-10.c b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-10.c new file mode 100644 index 0000000000000000000000000000000000000000..6a4e9cd457bd77795cfeccc59ce3833d0388cfe0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-10.c @@ -0,0 +1,29 @@ +/* This test uses intentionally DOS line endings (CR+LF). */ +/* { 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 diff --git a/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-2.c b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-2.c new file mode 100644 index 0000000000000000000000000000000000000000..b31c925026011bb2b447fd236beab0b1849c7194 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-2.c @@ -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 diff --git a/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-3.c b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-3.c new file mode 100644 index 0000000000000000000000000000000000000000..3c3a9ac4db74ed1b7d4d422dd7fee4e377c07a05 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-3.c @@ -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 diff --git a/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-4.c b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-4.c new file mode 100644 index 0000000000000000000000000000000000000000..ea01bb089494de8df2a61418b968b653581336bd --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-4.c @@ -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 diff --git a/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-5.c b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-5.c new file mode 100644 index 0000000000000000000000000000000000000000..075de3058f4b734f87ecbb1167441e497875f5e1 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-5.c @@ -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 diff --git a/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-6.c b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-6.c new file mode 100644 index 0000000000000000000000000000000000000000..751f90e984602da397b29d00c813834b785be988 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-6.c @@ -0,0 +1,38 @@ +/* This test uses intentionally DOS line endings (CR+LF). */ +/* { 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 diff --git a/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-7.c b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-7.c new file mode 100644 index 0000000000000000000000000000000000000000..6f9bac345668f19bc75adc4e49943eb82cef6af9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-7.c @@ -0,0 +1,38 @@ +/* This test uses intentionally DOS line endings (CR+LF). */ +/* { 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 diff --git a/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-8.c b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-8.c new file mode 100644 index 0000000000000000000000000000000000000000..29dae90e1e29effe8fc1c2fafc9d3435f59fdf38 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-8.c @@ -0,0 +1,44 @@ +/* This test uses intentionally DOS line endings (CR+LF). */ +/* { 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 diff --git a/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-9.c b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-9.c new file mode 100644 index 0000000000000000000000000000000000000000..9567a2fd34d222bd3867a7904450dbfa13479b3c --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/Wtrailing-whitespace-9.c @@ -0,0 +1,29 @@ +/* This test uses intentionally DOS line endings (CR+LF). */ +/* { 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 diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index be367b1f54afeccf3e26cf4717845e0905411bb0..3f05d085fcf9f2e67f91d5759d98f4e2ff59f1d1 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -598,6 +598,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 { @@ -722,7 +725,8 @@ enum cpp_warning_reason { CPP_W_INVALID_UTF8, CPP_W_UNICODE, CPP_W_HEADER_GUARD, - CPP_W_PRAGMA_ONCE_OUTSIDE_HEADER + CPP_W_PRAGMA_ONCE_OUTSIDE_HEADER, + CPP_W_TRAILING_WHITESPACE }; /* Callback for header lookup for HEADER, which is the name of a diff --git a/libcpp/internal.h b/libcpp/internal.h index 6c2a36ecd0ab5d43473f98ddde98ddc23320e3f2..a658a8c5739c1f1df5e45db13cd09bfe0c785dd9 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -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; }; diff --git a/libcpp/lex.cc b/libcpp/lex.cc index f3feadf9352facc153403b9150d0634be24252e8..bb5cd394ab4457a6c77f83e40a492d0527d1b98b 100644 --- a/libcpp/lex.cc +++ b/libcpp/lex.cc @@ -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 *pfile, int in_comment) 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 *pfile, int in_comment) 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 @@ -2507,6 +2531,12 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base) 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]);