[cfe-commits] r104684 - in /cfe/trunk: include/clang/Lex/LiteralSupport.h lib/Lex/LiteralSupport.cpp lib/Sema/SemaChecking.cpp test/Sema/format-strings.c
Douglas Gregor
dgregor at apple.com
Tue May 25 22:35:51 PDT 2010
Author: dgregor
Date: Wed May 26 00:35:51 2010
New Revision: 104684
URL: http://llvm.org/viewvc/llvm-project?rev=104684&view=rev
Log:
Tell the string literal parser when it's not permitted to emit
diagnostics. That would be while we're parsing string literals for the
sole purpose of producing a diagnostic about them. Fixes
<rdar://problem/8026030>.
Modified:
cfe/trunk/include/clang/Lex/LiteralSupport.h
cfe/trunk/lib/Lex/LiteralSupport.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/format-strings.c
Modified: cfe/trunk/include/clang/Lex/LiteralSupport.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/LiteralSupport.h?rev=104684&r1=104683&r2=104684&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/LiteralSupport.h (original)
+++ cfe/trunk/include/clang/Lex/LiteralSupport.h Wed May 26 00:35:51 2010
@@ -147,7 +147,7 @@
char *ResultPtr; // cursor
public:
StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
- Preprocessor &PP);
+ Preprocessor &PP, bool Complain = true);
bool hadError;
bool AnyWide;
bool Pascal;
@@ -164,7 +164,7 @@
/// specified byte of the string data represented by Token. This handles
/// advancing over escape sequences in the string.
static unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo,
- Preprocessor &PP);
+ Preprocessor &PP, bool Complain = true);
};
} // end namespace clang
Modified: cfe/trunk/lib/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/LiteralSupport.cpp?rev=104684&r1=104683&r2=104684&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/LiteralSupport.cpp (original)
+++ cfe/trunk/lib/Lex/LiteralSupport.cpp Wed May 26 00:35:51 2010
@@ -34,7 +34,7 @@
static unsigned ProcessCharEscape(const char *&ThisTokBuf,
const char *ThisTokEnd, bool &HadError,
SourceLocation Loc, bool IsWide,
- Preprocessor &PP) {
+ Preprocessor &PP, bool Complain) {
// Skip the '\' char.
++ThisTokBuf;
@@ -54,11 +54,13 @@
ResultChar = 8;
break;
case 'e':
- PP.Diag(Loc, diag::ext_nonstandard_escape) << "e";
+ if (Complain)
+ PP.Diag(Loc, diag::ext_nonstandard_escape) << "e";
ResultChar = 27;
break;
case 'E':
- PP.Diag(Loc, diag::ext_nonstandard_escape) << "E";
+ if (Complain)
+ PP.Diag(Loc, diag::ext_nonstandard_escape) << "E";
ResultChar = 27;
break;
case 'f':
@@ -79,7 +81,8 @@
case 'x': { // Hex escape.
ResultChar = 0;
if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
- PP.Diag(Loc, diag::err_hex_escape_no_digits);
+ if (Complain)
+ PP.Diag(Loc, diag::err_hex_escape_no_digits);
HadError = 1;
break;
}
@@ -106,7 +109,7 @@
}
// Check for overflow.
- if (Overflow) // Too many digits to fit in
+ if (Overflow && Complain) // Too many digits to fit in
PP.Diag(Loc, diag::warn_hex_escape_too_large);
break;
}
@@ -132,7 +135,8 @@
: PP.getTargetInfo().getCharWidth();
if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
- PP.Diag(Loc, diag::warn_octal_escape_too_large);
+ if (Complain)
+ PP.Diag(Loc, diag::warn_octal_escape_too_large);
ResultChar &= ~0U >> (32-CharWidth);
}
break;
@@ -141,10 +145,14 @@
// Otherwise, these are not valid escapes.
case '(': case '{': case '[': case '%':
// GCC accepts these as extensions. We warn about them as such though.
- PP.Diag(Loc, diag::ext_nonstandard_escape)
- << std::string()+(char)ResultChar;
+ if (Complain)
+ PP.Diag(Loc, diag::ext_nonstandard_escape)
+ << std::string()+(char)ResultChar;
break;
default:
+ if (!Complain)
+ break;
+
if (isgraph(ThisTokBuf[0]))
PP.Diag(Loc, diag::ext_unknown_escape) << std::string()+(char)ResultChar;
else
@@ -161,7 +169,8 @@
/// we will likely rework our support for UCN's.
static void ProcessUCNEscape(const char *&ThisTokBuf, const char *ThisTokEnd,
char *&ResultBuf, bool &HadError,
- SourceLocation Loc, bool IsWide, Preprocessor &PP)
+ SourceLocation Loc, bool IsWide, Preprocessor &PP,
+ bool Complain)
{
// FIXME: Add a warning - UCN's are only valid in C++ & C99.
// FIXME: Handle wide strings.
@@ -173,7 +182,8 @@
ThisTokBuf += 2;
if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
- PP.Diag(Loc, diag::err_ucn_escape_no_digits);
+ if (Complain)
+ PP.Diag(Loc, diag::err_ucn_escape_no_digits);
HadError = 1;
return;
}
@@ -189,8 +199,9 @@
}
// If we didn't consume the proper number of digits, there is a problem.
if (UcnLen) {
- PP.Diag(PP.AdvanceToTokenCharacter(Loc, ThisTokBuf-ThisTokBegin),
- diag::err_ucn_escape_incomplete);
+ if (Complain)
+ PP.Diag(PP.AdvanceToTokenCharacter(Loc, ThisTokBuf-ThisTokBegin),
+ diag::err_ucn_escape_incomplete);
HadError = 1;
return;
}
@@ -199,7 +210,8 @@
(UcnVal != 0x24 && UcnVal != 0x40 && UcnVal != 0x60 )) // $, @, `
|| (UcnVal >= 0xD800 && UcnVal <= 0xDFFF)
|| (UcnVal > 0x10FFFF)) /* the maximum legal UTF32 value */ {
- PP.Diag(Loc, diag::err_ucn_escape_invalid);
+ if (Complain)
+ PP.Diag(Loc, diag::err_ucn_escape_invalid);
HadError = 1;
return;
}
@@ -660,7 +672,8 @@
if (begin[0] != '\\') // If this is a normal character, consume it.
ResultChar = *begin++;
else // Otherwise, this is an escape character.
- ResultChar = ProcessCharEscape(begin, end, HadError, Loc, IsWide, PP);
+ ResultChar = ProcessCharEscape(begin, end, HadError, Loc, IsWide, PP,
+ /*Complain=*/true);
// If this is a multi-character constant (e.g. 'abc'), handle it. These are
// implementation defined (C99 6.4.4.4p10).
@@ -746,7 +759,7 @@
///
StringLiteralParser::
StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
- Preprocessor &pp) : PP(pp) {
+ Preprocessor &pp, bool Complain) : PP(pp) {
// Scan all of the string portions, remember the max individual token length,
// computing a bound on the concatenated string length, and see whether any
// piece is a wide-string. If any of the string portions is a wide-string
@@ -871,13 +884,14 @@
// Is this a Universal Character Name escape?
if (ThisTokBuf[1] == 'u' || ThisTokBuf[1] == 'U') {
ProcessUCNEscape(ThisTokBuf, ThisTokEnd, ResultPtr,
- hadError, StringToks[i].getLocation(), ThisIsWide, PP);
+ hadError, StringToks[i].getLocation(), ThisIsWide, PP,
+ Complain);
continue;
}
// Otherwise, this is a non-UCN escape character. Process it.
unsigned ResultChar = ProcessCharEscape(ThisTokBuf, ThisTokEnd, hadError,
StringToks[i].getLocation(),
- ThisIsWide, PP);
+ ThisIsWide, PP, Complain);
// Note: our internal rep of wide char tokens is always little-endian.
*ResultPtr++ = ResultChar & 0xFF;
@@ -893,7 +907,7 @@
ResultBuf[0] = ResultPtr-&ResultBuf[0]-1;
// Verify that pascal strings aren't too large.
- if (GetStringLength() > 256) {
+ if (GetStringLength() > 256 && Complain) {
PP.Diag(StringToks[0].getLocation(), diag::err_pascal_string_too_long)
<< SourceRange(StringToks[0].getLocation(),
StringToks[NumStringToks-1].getLocation());
@@ -909,7 +923,8 @@
/// advancing over escape sequences in the string.
unsigned StringLiteralParser::getOffsetOfStringByte(const Token &Tok,
unsigned ByteNo,
- Preprocessor &PP) {
+ Preprocessor &PP,
+ bool Complain) {
// Get the spelling of the token.
llvm::SmallString<16> SpellingBuffer;
SpellingBuffer.resize(Tok.getLength());
@@ -945,7 +960,7 @@
// Otherwise, this is an escape character. Advance over it.
bool HadError = false;
ProcessCharEscape(SpellingPtr, SpellingEnd, HadError,
- Tok.getLocation(), false, PP);
+ Tok.getLocation(), false, PP, Complain);
assert(!HadError && "This method isn't valid on erroneous strings");
--ByteNo;
}
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=104684&r1=104683&r2=104684&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Wed May 26 00:35:51 2010
@@ -75,14 +75,15 @@
TheLexer.LexFromRawLexer(TheTok);
// Use the StringLiteralParser to compute the length of the string in bytes.
- StringLiteralParser SLP(&TheTok, 1, PP);
+ StringLiteralParser SLP(&TheTok, 1, PP, /*Complain=*/false);
unsigned TokNumBytes = SLP.GetStringLength();
// If the byte is in this token, return the location of the byte.
if (ByteNo < TokNumBytes ||
(ByteNo == TokNumBytes && TokNo == SL->getNumConcatenated())) {
unsigned Offset =
- StringLiteralParser::getOffsetOfStringByte(TheTok, ByteNo, PP);
+ StringLiteralParser::getOffsetOfStringByte(TheTok, ByteNo, PP,
+ /*Complain=*/false);
// Now that we know the offset of the token in the spelling, use the
// preprocessor to get the offset in the original source.
Modified: cfe/trunk/test/Sema/format-strings.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings.c?rev=104684&r1=104683&r2=104684&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings.c (original)
+++ cfe/trunk/test/Sema/format-strings.c Wed May 26 00:35:51 2010
@@ -251,3 +251,6 @@
myprintf_PR_6697("%1$s\n", 1, (int) 0); // expected-warning{{conversion specifies type 'char *' but the argument has type 'int'}}
}
+void rdar8026030(FILE *fp) {
+ fprintf(fp, "\%"); // expected-warning{{incomplete format specifier}}
+}
More information about the cfe-commits
mailing list