diff options
author | Hans Wennborg <hans@hanshq.net> | 2012-07-27 19:17:46 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2012-07-27 19:17:46 +0000 |
commit | 08574d3559792373a2d5da6628fb55254a03549b (patch) | |
tree | 8e8c1f4e567e1d8a341770d2fff70636c5b39706 /clang/lib/Analysis/FormatString.cpp | |
parent | c77a3b1aab7aebda612463fae7dbdb41ffe9466c (diff) | |
download | bcm5719-llvm-08574d3559792373a2d5da6628fb55254a03549b.tar.gz bcm5719-llvm-08574d3559792373a2d5da6628fb55254a03549b.zip |
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
Diffstat (limited to 'clang/lib/Analysis/FormatString.cpp')
-rw-r--r-- | clang/lib/Analysis/FormatString.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/clang/lib/Analysis/FormatString.cpp b/clang/lib/Analysis/FormatString.cpp index caceeac113b..a68b9bb3240 100644 --- a/clang/lib/Analysis/FormatString.cpp +++ b/clang/lib/Analysis/FormatString.cpp @@ -681,3 +681,37 @@ bool FormatSpecifier::hasStandardLengthConversionCombination() const { } return true; } + +bool FormatSpecifier::namedTypeToLengthModifier(QualType QT, + LengthModifier &LM) { + assert(isa<TypedefType>(QT) && "Expected a TypedefType"); + const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl(); + + for (;;) { + const IdentifierInfo *Identifier = Typedef->getIdentifier(); + if (Identifier->getName() == "size_t") { + LM.setKind(LengthModifier::AsSizeT); + return true; + } else if (Identifier->getName() == "ssize_t") { + // Not C99, but common in Unix. + LM.setKind(LengthModifier::AsSizeT); + return true; + } else if (Identifier->getName() == "intmax_t") { + LM.setKind(LengthModifier::AsIntMax); + return true; + } else if (Identifier->getName() == "uintmax_t") { + LM.setKind(LengthModifier::AsIntMax); + return true; + } else if (Identifier->getName() == "ptrdiff_t") { + LM.setKind(LengthModifier::AsPtrDiff); + return true; + } + + QualType T = Typedef->getUnderlyingType(); + if (!isa<TypedefType>(T)) + break; + + Typedef = cast<TypedefType>(T)->getDecl(); + } + return false; +} |