For printf checking, handle nested typedefs for darwin-specific checking.

Fixes <rdar://problem/13491605>.

llvm-svn: 177931
This commit is contained in:
Ted Kremenek 2013-03-25 22:28:37 +00:00
parent 780420ea4e
commit cd3d440b82
2 changed files with 13 additions and 1 deletions

View File

@ -2803,7 +2803,9 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
// casts to primitive types that are known to be large enough.
bool ShouldNotPrintDirectly = false;
if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
if (const TypedefType *UserTy = IntendedTy->getAs<TypedefType>()) {
// Use a 'while' to peel off layers of typedefs.
QualType TyTy = IntendedTy;
while (const TypedefType *UserTy = TyTy->getAs<TypedefType>()) {
StringRef Name = UserTy->getDecl()->getName();
QualType CastTy = llvm::StringSwitch<QualType>(Name)
.Case("NSInteger", S.Context.LongTy)
@ -2815,7 +2817,9 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
if (!CastTy.isNull()) {
ShouldNotPrintDirectly = true;
IntendedTy = CastTy;
break;
}
TyTy = UserTy->desugar();
}
}

View File

@ -23,6 +23,8 @@ typedef long SInt32;
typedef unsigned long UInt32;
#endif
typedef SInt32 OSStatus;
NSInteger getNSInteger();
NSUInteger getNSUInteger();
SInt32 getSInt32();
@ -210,3 +212,9 @@ void testCapitals() {
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:14}:"d"
// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:14}:"%D"
}
void testLayeredTypedefs(OSStatus i) {
printf("%s", i); // expected-warning {{values of type 'OSStatus' should not be used as format arguments}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"d"
}