aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-02-18 18:34:12 +0000
committerChris Lattner <sabre@nondot.org>2009-02-18 18:34:12 +0000
commitd0d082f2eba4e3ed4eb467d76fd227c6dcd6cce7 (patch)
treeea0e36306ec2e9ed40cc6675204d738076914864
parent07f192e1d7af64d63fd80eafd724b70a18ebfbd9 (diff)
use the full spelling of a string literal token so that trigraphs
and escaped newlines don't throw off the offset computation. On this testcase: printf("abc\ def" "%*d", (unsigned) 1, 1); Before: t.m:5:5: warning: field width should have type 'int', but argument has type 'unsigned int' def" ^ after: t.m:6:12: warning: field width should have type 'int', but argument has type 'unsigned int' "%*d", (unsigned) 1, 1); ^ ~~~~~~~~~~~~ git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64930 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaChecking.cpp9
-rw-r--r--test/Sema/format-strings.c9
2 files changed, 15 insertions, 3 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index f469684e50..6ffca1b7b8 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -31,6 +31,8 @@ SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL,
unsigned ByteNo) const {
assert(!SL->isWide() && "This doesn't work for wide strings yet");
+ llvm::SmallString<32> SpellingBuffer;
+
// Loop over all of the tokens in this string until we find the one that
// contains the byte we're looking for.
unsigned TokNo = 0;
@@ -61,8 +63,13 @@ SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL,
Token TheTok;
TheLexer.LexFromRawLexer(TheTok);
+ // Get the spelling of the token to remove trigraphs and escaped newlines.
+ SpellingBuffer.resize(TheTok.getLength());
+ const char *SpellingPtr = &SpellingBuffer[0];
+ unsigned TokLen = PP.getSpelling(TheTok, SpellingPtr);
+
// The length of the string is the token length minus the two quotes.
- unsigned TokNumBytes = TheTok.getLength()-2;
+ unsigned TokNumBytes = TokLen-2;
// If we found the token we're looking for, return the location.
// FIXME: This should consider character escapes!
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
index 024e06ab59..5007bb0fa4 100644
--- a/test/Sema/format-strings.c
+++ b/test/Sema/format-strings.c
@@ -30,8 +30,13 @@ void check_string_literal( FILE* fp, const char* s, char *buf, ... ) {
__builtin___vsnprintf_chk(buf,2,0,-1,s,ap); // no-warning
__builtin___vsnprintf_chk(buf,2,0,-1,global_fmt,ap); // expected-warning {{format string is not a string literal}}
- printf("abc"
- "%*d", (unsigned) 1, 1); // expected-warning {{field width should have type 'int'}}
+ // rdar://6079877
+ printf("abc"
+ "%*d", (unsigned) 1, 1); // expected-warning {{field width should have type 'int'}}
+ printf("abc\
+def"
+ "%*d", (unsigned) 1, 1); // expected-warning {{field width should have type 'int'}}
+
}
void check_conditional_literal(const char* s, int i) {