]> granicus.if.org Git - clang/commitdiff
use the full spelling of a string literal token so that trigraphs
authorChris Lattner <sabre@nondot.org>
Wed, 18 Feb 2009 18:34:12 +0000 (18:34 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 18 Feb 2009 18:34:12 +0000 (18:34 +0000)
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

lib/Sema/SemaChecking.cpp
test/Sema/format-strings.c

index f469684e50323a3f6e555e4782a3c5a051bb2c8b..6ffca1b7b8724cda84841083337fdfa386cc5eb6 100644 (file)
@@ -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!
index 024e06ab591ff8ceb1868fcc99a0ecd9214e6845..5007bb0fa40f8d5f1249813ef523d72ace496843 100644 (file)
@@ -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) {