From 48b80c78b02efd7c4a7e3a7530d05b8aa9d3b649 Mon Sep 17 00:00:00 2001
From: Reid Kleckner <reid@kleckner.net>
Date: Wed, 25 Sep 2013 16:42:48 +0000
Subject: [PATCH] PR17359: Fix off-by-one OOB on _Pragma("") and an unescaping
 bug

Previously the code would reduce a run of backslashes to a single
backslash, and now it will properly leave behind every other backslash.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@191382 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Lex/Pragma.cpp          | 14 +++++++-------
 test/Preprocessor/_Pragma.c |  3 +++
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 8d3dedc375..4c6d889bf3 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -263,14 +263,14 @@ void Preprocessor::Handle_Pragma(Token &Tok) {
 
     // Remove escaped quotes and escapes.
     unsigned ResultPos = 1;
-    for (unsigned i = 1, e = StrVal.size() - 2; i != e; ++i) {
-      if (StrVal[i] != '\\' ||
-          (StrVal[i + 1] != '\\' && StrVal[i + 1] != '"')) {
-        // \\ -> '\' and \" -> '"'.
-        StrVal[ResultPos++] = StrVal[i];
-      }
+    for (unsigned i = 1, e = StrVal.size() - 1; i != e; ++i) {
+      // Skip escapes.  \\ -> '\' and \" -> '"'.
+      if (StrVal[i] == '\\' && i + 1 < e &&
+          (StrVal[i + 1] == '\\' || StrVal[i + 1] == '"'))
+        ++i;
+      StrVal[ResultPos++] = StrVal[i];
     }
-    StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 2);
+    StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
   }
 
   // Remove the front quote, replacing it with a space, so that the pragma
diff --git a/test/Preprocessor/_Pragma.c b/test/Preprocessor/_Pragma.c
index 0a83b149ff..15725a4222 100644
--- a/test/Preprocessor/_Pragma.c
+++ b/test/Preprocessor/_Pragma.c
@@ -5,6 +5,9 @@ _Pragma ("GCC system_header")  // expected-warning {{system_header ignored in ma
 // rdar://6880630
 _Pragma("#define macro")    // expected-warning {{unknown pragma ignored}}
 
+_Pragma("") // expected-warning {{unknown pragma ignored}}
+_Pragma("message(\"foo \\\\\\\\ bar\")") // expected-warning {{foo \\ bar}}
+
 #ifdef macro
 #error #define invalid
 #endif
-- 
2.40.0