diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -2446,44 +2446,69 @@ // Back up off the newline. --CurPtr; - // If this is a two-character newline sequence, skip the other character. - if (CurPtr[0] == '\n' || CurPtr[0] == '\r') { - // \n\n or \r\r -> not escaped newline. - if (CurPtr[0] == CurPtr[1]) - return false; - // \n\r or \r\n -> skip the newline. - --CurPtr; - } - - // If we have horizontal whitespace, skip over it. We allow whitespace - // between the slash and newline. bool HasSpace = false; - while (isHorizontalWhitespace(*CurPtr) || *CurPtr == 0) { - --CurPtr; - HasSpace = true; - } + while (true) { + // If this is a two-character newline sequence, skip the other character. + if (CurPtr[0] == '\n' || CurPtr[0] == '\r') { + // \n\n or \r\r -> not escaped newline. + if (CurPtr[0] == CurPtr[1]) + return false; + // \n\r or \r\n -> skip the newline. + --CurPtr; + } + + // If we have horizontal whitespace, skip over it. We allow whitespace + // between the slash and newline. + while (isHorizontalWhitespace(*CurPtr) || *CurPtr == 0) { + --CurPtr; + HasSpace = true; + } + + // If we have a slash, we know this is an escaped newline. + if (*CurPtr == '\\') { + // Found the *, we're done + if (CurPtr[-1] == '*') break; + + // Found another possible escaped newline + if (CurPtr[-1] == '\n' || CurPtr[-1] == '\r') { + --CurPtr; + continue; + } - // If we have a slash, we know this is an escaped newline. - if (*CurPtr == '\\') { - if (CurPtr[-1] != '*') return false; - } else { - // It isn't a slash, is it the ?? / trigraph? - if (CurPtr[0] != '/' || CurPtr[-1] != '?' || CurPtr[-2] != '?' || - CurPtr[-3] != '*') return false; + } else { + // It isn't a slash, is it the ?? / trigraph? + if (CurPtr[0] != '/' || CurPtr[-1] != '?' || CurPtr[-2] != '?') + return false; + + // This is the trigraph ending the comment. Emit a stern warning! + CurPtr -= 2; + + if (CurPtr[-1] == '*') { + // If no trigraphs are enabled, warn that we ignored this trigraph and + // ignore this * character. + if (!L->getLangOpts().Trigraphs) { + if (!L->isLexingRawMode()) + L->Diag(CurPtr, diag::trigraph_ignored_block_comment); + return false; + } + if (!L->isLexingRawMode()) + L->Diag(CurPtr, diag::trigraph_ends_block_comment); - // This is the trigraph ending the comment. Emit a stern warning! - CurPtr -= 2; + break; + } else if (CurPtr[-1] == '\n' || CurPtr[-1] == '\r') { + // If no trigraphs are enabled, warn that we ignored this trigraph + if (!L->getLangOpts().Trigraphs) { + if (!L->isLexingRawMode()) + L->Diag(CurPtr, diag::trigraph_ignored); + return false; + } + --CurPtr; + continue; + } - // If no trigraphs are enabled, warn that we ignored this trigraph and - // ignore this * character. - if (!L->getLangOpts().Trigraphs) { - if (!L->isLexingRawMode()) - L->Diag(CurPtr, diag::trigraph_ignored_block_comment); return false; } - if (!L->isLexingRawMode()) - L->Diag(CurPtr, diag::trigraph_ends_block_comment); } // Warn about having an escaped newline between the */ characters.