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]);