--- libcpp/include/cpplib.h.jj	2024-09-13 16:09:32.690455174 +0200
+++ libcpp/include/cpplib.h	2024-09-18 13:01:26.289338279 +0200
@@ -594,6 +594,9 @@ struct cpp_options
   /* True if -finput-charset= option has been used explicitly.  */
   bool cpp_input_charset_explicit;
 
+  /* True if -Wtrailing-blanks.  */
+  bool cpp_warn_trailing_blanks;
+
   /* 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_BLANKS
 };
 
 /* 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-18 12:36:04.386099371 +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, 'B' trailing blanks, 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-18 14:00:46.344062046 +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,11 @@ _cpp_clean_line (cpp_reader *pfile)
 		}
 	    }
 	}
+     done:
+      if (d > buffer->next_line
+	  && ISBLANK (d[-1])
+	  && CPP_OPTION (pfile, cpp_warn_trailing_blanks))
+	add_line_note (buffer, d - 1, 'B');
     }
   else
     {
@@ -955,7 +960,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 +1017,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_blanks))
+		cpp_warning_with_line (pfile, CPP_W_TRAILING_BLANKS,
+				       pfile->line_table->highest_line, col,
+				       "trailing blanks");
+	    }
 
 	  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 +1054,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 == 'B')
+	cpp_warning_with_line (pfile, CPP_W_TRAILING_BLANKS,
+			       pfile->line_table->highest_line, col,
+			       "trailing blanks");
       else if (note->type == 0)
 	/* Already processed in lex_raw_string.  */;
       else
@@ -2539,6 +2554,12 @@ lex_raw_string (cpp_reader *pfile, cpp_t
 	    note->type = 0;
 	    note++;
 	    break;
+
+	  case 'B':
+	    /* Don't warn about trailing blanks 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-18 14:46:39.584782466 +0200
@@ -8996,6 +8996,13 @@ will always be false.
 
 This warning is enabled by @option{-Wall}.
 
+@opindex Wtrailing-blanks
+@opindex Wno-trailing-blanks
+@item -Wtrailing-blanks
+Warn about trailing blanks (spaces or horizontal tabs) at the end of lines,
+including inside of comments, but excluding trailing blanks in raw string
+literals.  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-18 13:01:56.404927852 +0200
@@ -1450,6 +1450,10 @@ 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.
 
+Wtrailing-blanks
+C ObjC C++ ObjC++ CPP(cpp_warn_trailing_blanks) CppReason(CPP_W_TRAILING_BLANKS) Var(warn_trailing_blanks) Init(0) Warning
+Warn about trailing blanks on lines except when in raw string literals.
+
 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-blanks.c.jj	2024-09-18 14:44:22.712636656 +0200
+++ gcc/testsuite/c-c++-common/cpp/Wtrailing-blanks.c	2024-09-18 13:21:20.898071467 +0200
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { c || c++11 } } } */
+/* { dg-options "-Wtrailing-blanks" } */
+
+int i;   
+/* { dg-warning "trailing blanks" "" { target *-*-* } .-1 } */
+int j;		
+/* { dg-warning "trailing blanks" "" { 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 blanks" "" { target *-*-* } .-3 } */
+
+ 
+ 
+/* { dg-warning "trailing blanks" "" { target *-*-* } .-1 } */
+const char *p = R"*|*(		
+  
+        
+.
+)*|*";	 
+/* { dg-warning "trailing blanks" "" { target *-*-* } .-1 } */
+// This is a comment with trailing blank 
+/* { dg-warning "trailing blanks" "" { target *-*-* } .-1 } */
+/* This is a comment with trailing blanks	
+*/
+/* { dg-warning "trailing blanks" "" { target *-*-* } .-2 } */
+/* { dg-warning "trailing blanks" "" { target *-*-* } .+1 } */
+    
\ No newline at end of file
