Author: majnemer Date: Wed Sep 23 11:04:47 2015 New Revision: 248392 URL: http://llvm.org/viewvc/llvm-project?rev=248392&view=rev Log: [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. Added: cfe/trunk/test/CXX/lex/lex.literal/lex.string/p4.cpp Modified: cfe/trunk/lib/Lex/LiteralSupport.cpp Modified: cfe/trunk/lib/Lex/LiteralSupport.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/LiteralSupport.cpp?rev=248392&r1=248391&r2=248392&view=diff ============================================================================== --- cfe/trunk/lib/Lex/LiteralSupport.cpp (original) +++ cfe/trunk/lib/Lex/LiteralSupport.cpp Wed Sep 23 11:04:47 2015 @@ -1417,10 +1417,23 @@ void StringLiteralParser::init(ArrayRef< 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 Added: cfe/trunk/test/CXX/lex/lex.literal/lex.string/p4.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.string/p4.cpp?rev=248392&view=auto ============================================================================== --- cfe/trunk/test/CXX/lex/lex.literal/lex.string/p4.cpp (added) +++ cfe/trunk/test/CXX/lex/lex.literal/lex.string/p4.cpp Wed Sep 23 11:04:47 2015 @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s +// expected-no-diagnostics + +// NOTE: This file intentionally uses DOS-style line endings to test +// that we don't propagate them into string literals as per [lex.string]p4. + +constexpr const char* p = R"(a\ +b +c)"; + +static_assert(p[0] == 'a', ""); +static_assert(p[1] == '\\', ""); +static_assert(p[2] == '\n', ""); +static_assert(p[3] == 'b', ""); +static_assert(p[4] == '\n', ""); +static_assert(p[5] == 'c', ""); +static_assert(p[6] == '\0', ""); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits