Make -Wformat walk the typedef chain when looking for size_t, etc.

Clang's -Wformat fix-its currently suggest using "%zu" for values of
type size_t (in C99 or C++11 mode). However, for a type such as
std::vector<T>::size_type, it does not notice that type is actually
typedeffed to size_t, and instead suggests a format for the underlying
type, such as "%lu" or "%u".

This commit makes the format string fix mechanism walk the typedef chain
so that it notices if the type is size_t, even if that isn't "at the
top".

llvm-svn: 160886
This commit is contained in:
Hans Wennborg
2012-07-27 19:17:46 +00:00
parent c77a3b1aab
commit 08574d3559
5 changed files with 76 additions and 30 deletions

View File

@@ -447,21 +447,8 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
}
// 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);
}
}
if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x))
namedTypeToLengthModifier(QT, LM);
// If fixing the length modifier was enough, we are done.
const analyze_printf::ArgTypeResult &ATR = getArgType(Ctx, IsObjCLiteral);