From 54bbae5c0f5d9543ddf976080325306d7dcec2a1 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 23 Sep 2015 16:04:47 +0000 Subject: [Lex] A source-file new-line in a raw string literal results in a new-line Our string literal parser copied any source-file new-line characters into the execution string-literal. This is incorrect if the source-file new-line character was a \r\n sequence because new-line characters are merely \n. llvm-svn: 248392 --- clang/lib/Lex/LiteralSupport.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'clang/lib/Lex') diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index beacbc9df15..1a1b281bd91 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1417,10 +1417,23 @@ void StringLiteralParser::init(ArrayRef StringToks){ ThisTokEnd -= ThisTokBuf - Prefix; assert(ThisTokEnd >= ThisTokBuf && "malformed raw string literal"); - // Copy the string over - if (CopyStringFragment(StringToks[i], ThisTokBegin, - StringRef(ThisTokBuf, ThisTokEnd - ThisTokBuf))) - hadError = true; + // C++14 [lex.string]p4: A source-file new-line in a raw string literal + // results in a new-line in the resulting execution string-literal. + StringRef RemainingTokenSpan(ThisTokBuf, ThisTokEnd - ThisTokBuf); + while (!RemainingTokenSpan.empty()) { + // Split the string literal on \r\n boundaries. + size_t CRLFPos = RemainingTokenSpan.find("\r\n"); + StringRef BeforeCRLF = RemainingTokenSpan.substr(0, CRLFPos); + StringRef AfterCRLF = RemainingTokenSpan.substr(CRLFPos); + + // Copy everything before the \r\n sequence into the string literal. + if (CopyStringFragment(StringToks[i], ThisTokBegin, BeforeCRLF)) + hadError = true; + + // Point into the \n inside the \r\n sequence and operate on the + // remaining portion of the literal. + RemainingTokenSpan = AfterCRLF.substr(1); + } } else { if (ThisTokBuf[0] != '"') { // The file may have come from PCH and then changed after loading the -- cgit v1.2.3