@@ -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
@@ -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;
};
@@ -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]);
@@ -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
@@ -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.
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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