[cfe-commits] r116996 - in /cfe/trunk: lib/Analysis/PrintfFormatString.cpp lib/Sema/SemaChecking.cpp test/Sema/format-strings.c
Ted Kremenek
kremenek at apple.com
Wed Oct 20 21:00:58 PDT 2010
Author: kremenek
Date: Wed Oct 20 23:00:58 2010
New Revision: 116996
URL: http://llvm.org/viewvc/llvm-project?rev=116996&view=rev
Log:
Previously, the printf warnings would say your arguments type was 'int' when it was really a 'char'
or a 'short'. This fixes that and allows the hints to suggest 'h' modifiers for small ints.
Patch by Justin Bogner!
Modified:
cfe/trunk/lib/Analysis/PrintfFormatString.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/format-strings.c
Modified: cfe/trunk/lib/Analysis/PrintfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp?rev=116996&r1=116995&r2=116996&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/PrintfFormatString.cpp (original)
+++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp Wed Oct 20 23:00:58 2010
@@ -382,6 +382,18 @@
LM.setKind(LengthModifier::None);
break;
+ case BuiltinType::Char_U:
+ case BuiltinType::UChar:
+ case BuiltinType::Char_S:
+ case BuiltinType::SChar:
+ LM.setKind(LengthModifier::AsChar);
+ break;
+
+ case BuiltinType::Short:
+ case BuiltinType::UShort:
+ LM.setKind(LengthModifier::AsShort);
+ break;
+
case BuiltinType::WChar:
case BuiltinType::Long:
case BuiltinType::ULong:
@@ -399,8 +411,10 @@
}
// Set conversion specifier and disable any flags which do not apply to it.
- if (QT->isAnyCharacterType()) {
+ // Let typedefs to char fall through to int, as %c is silly for uint8_t.
+ if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) {
CS.setKind(ConversionSpecifier::cArg);
+ LM.setKind(LengthModifier::None);
Precision.setHowSpecified(OptionalAmount::NotSpecified);
HasAlternativeForm = 0;
HasLeadingZeroes = 0;
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=116996&r1=116995&r2=116996&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Wed Oct 20 23:00:58 2010
@@ -1603,9 +1603,12 @@
// or 'short' to an 'int'. This is done because printf is a varargs
// function.
if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Ex))
- if (ICE->getType() == S.Context.IntTy)
- if (ATR.matchesType(S.Context, ICE->getSubExpr()->getType()))
+ if (ICE->getType() == S.Context.IntTy) {
+ // All further checking is done on the subexpression.
+ Ex = ICE->getSubExpr();
+ if (ATR.matchesType(S.Context, Ex->getType()))
return true;
+ }
// We may be able to offer a FixItHint if it is a supported type.
PrintfSpecifier fixedFS = FS;
Modified: cfe/trunk/test/Sema/format-strings.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings.c?rev=116996&r1=116995&r2=116996&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings.c (original)
+++ cfe/trunk/test/Sema/format-strings.c Wed Oct 20 23:00:58 2010
@@ -174,7 +174,15 @@
printf("%.0Lf", (long double) 1.0); // no-warning
printf("%c\n", "x"); // expected-warning{{conversion specifies type 'int' but the argument has type 'char *'}}
printf("%c\n", 1.23); // expected-warning{{conversion specifies type 'int' but the argument has type 'double'}}
-}
+}
+
+typedef unsigned char uint8_t;
+
+void should_understand_small_integers() {
+ printf("%hhu", (short) 10); // expected-warning{{conversion specifies type 'unsigned char' but the argument has type 'short'}}
+ printf("%hu\n", (unsigned char) 1); // expected-warning{{conversion specifies type 'unsigned short' but the argument has type 'unsigned char'}}
+ printf("%hu\n", (uint8_t)1); // expected-warning{{conversion specifies type 'unsigned short' but the argument has type 'uint8_t'}}
+}
void test11(void *p, char *s) {
printf("%p", p); // no-warning
More information about the cfe-commits
mailing list