Teach format string analysis that "%zu" means size_t.

The code had it backwards, thinking size_t was signed, and using that for "%zd".

Also let the analysis get the types for (u)intmax_t while we are at it.

llvm-svn: 143099
This commit is contained in:
Hans Wennborg 2011-10-27 08:29:09 +00:00
parent b25abd1a54
commit 27541dbe1a
4 changed files with 40 additions and 11 deletions

View File

@ -835,6 +835,14 @@ public:
/// in <stddef.h>. The sizeof operator requires this (C99 6.5.3.4p4).
CanQualType getSizeType() const;
/// getIntMaxType - Return the unique type for "intmax_t" (C99 7.18.1.5),
/// defined in <stdint.h>.
CanQualType getIntMaxType() const;
/// getUIntMaxType - Return the unique type for "uintmax_t" (C99 7.18.1.5),
/// defined in <stdint.h>.
CanQualType getUIntMaxType() const;
/// getWCharType - In C++, this returns the unique wchar_t type. In C99, this
/// returns a type compatible with the type defined in <stddef.h> as defined
/// by the target.
@ -848,7 +856,7 @@ public:
/// Used when in C++, as a GCC extension.
QualType getUnsignedWCharType() const;
/// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
/// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17)
/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
QualType getPointerDiffType() const;

View File

@ -3001,6 +3001,16 @@ CanQualType ASTContext::getSizeType() const {
return getFromTargetType(Target->getSizeType());
}
/// getIntMaxType - Return the unique type for "intmax_t" (C99 7.18.1.5).
CanQualType ASTContext::getIntMaxType() const {
return getFromTargetType(Target->getIntMaxType());
}
/// getUIntMaxType - Return the unique type for "uintmax_t" (C99 7.18.1.5).
CanQualType ASTContext::getUIntMaxType() const {
return getFromTargetType(Target->getUIntMaxType());
}
/// getSignedWCharType - Return the type of "signed wchar_t".
/// Used when in C++, as a GCC extension.
QualType ASTContext::getSignedWCharType() const {
@ -3015,7 +3025,7 @@ QualType ASTContext::getUnsignedWCharType() const {
return UnsignedIntTy;
}
/// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
/// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17)
/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
QualType ASTContext::getPointerDiffType() const {
return getFromTargetType(Target->getPtrDiffType(0));

View File

@ -301,10 +301,10 @@ ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const {
case LengthModifier::AsShort: return Ctx.ShortTy;
case LengthModifier::AsLong: return Ctx.LongTy;
case LengthModifier::AsLongLong: return Ctx.LongLongTy;
case LengthModifier::AsIntMax:
// FIXME: Return unknown for now.
case LengthModifier::AsIntMax: return Ctx.getIntMaxType();
case LengthModifier::AsSizeT:
// FIXME: How to get the corresponding signed version of size_t?
return ArgTypeResult();
case LengthModifier::AsSizeT: return Ctx.getSizeType();
case LengthModifier::AsPtrDiff: return Ctx.getPointerDiffType();
}
@ -317,13 +317,9 @@ ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const {
case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy;
case LengthModifier::AsIntMax:
// FIXME: Return unknown for now.
return ArgTypeResult();
case LengthModifier::AsIntMax: return Ctx.getUIntMaxType();
case LengthModifier::AsSizeT:
// FIXME: How to get the corresponding unsigned
// version of size_t?
return ArgTypeResult();
return Ctx.getSizeType();
case LengthModifier::AsPtrDiff:
// FIXME: How to get the corresponding unsigned
// version of ptrdiff_t?

View File

@ -0,0 +1,15 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s
int printf(char const *, ...);
void test(void) {
// size_t
printf("%zu", (double)42); // expected-warning {{conversion specifies type 'unsigned long' but the argument has type 'double''}}
// intmax_t / uintmax_t
printf("%jd", (double)42); // expected-warning {{conversion specifies type 'long' but the argument has type 'double''}}
printf("%ju", (double)42); // expected-warning {{conversion specifies type 'unsigned long' but the argument has type 'double''}}
// ptrdiff_t
printf("%td", (double)42); // expected-warning {{conversion specifies type 'long' but the argument has type 'double''}}
}