Suggest %zu for size_t args to printf.

For PR11152. Make PrintSpecifier::fixType() suggest "%zu" for size_t, etc.
rather than looking at the underlying type and suggesting "%llu" or other
platform-specific length modifiers. Applies to C99 and C++11.

llvm-svn: 142342
This commit is contained in:
Hans Wennborg
2011-10-18 08:10:06 +00:00
parent 2b7a1ff77f
commit f99d04f841
4 changed files with 38 additions and 3 deletions

View File

@@ -355,7 +355,7 @@ ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const {
return ArgTypeResult();
}
bool PrintfSpecifier::fixType(QualType QT) {
bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt) {
// Handle strings first (char *, wchar_t *)
if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
CS.setKind(ConversionSpecifier::sArg);
@@ -438,6 +438,23 @@ bool PrintfSpecifier::fixType(QualType QT) {
break;
}
// Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) {
const IdentifierInfo *Identifier = QT.getBaseTypeIdentifier();
if (Identifier->getName() == "size_t") {
LM.setKind(LengthModifier::AsSizeT);
} else if (Identifier->getName() == "ssize_t") {
// Not C99, but common in Unix.
LM.setKind(LengthModifier::AsSizeT);
} else if (Identifier->getName() == "intmax_t") {
LM.setKind(LengthModifier::AsIntMax);
} else if (Identifier->getName() == "uintmax_t") {
LM.setKind(LengthModifier::AsIntMax);
} else if (Identifier->getName() == "ptrdiff_t") {
LM.setKind(LengthModifier::AsPtrDiff);
}
}
// Set conversion specifier and disable any flags which do not apply to it.
// Let typedefs to char fall through to int, as %c is silly for uint8_t.
if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) {