aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/FormatString.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2012-07-27 19:17:46 +0000
committerHans Wennborg <hans@hanshq.net>2012-07-27 19:17:46 +0000
commit4684778993c667246039b4664acbce59dc99440c (patch)
tree58ef4c76c3fa9b9e318c27634a3eae94cdadd0fb /lib/Analysis/FormatString.cpp
parente61354b274ec5aa6acf3d15271896ce7596bb123 (diff)
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". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160886 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/FormatString.cpp')
-rw-r--r--lib/Analysis/FormatString.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/Analysis/FormatString.cpp b/lib/Analysis/FormatString.cpp
index caceeac113..a68b9bb324 100644
--- a/lib/Analysis/FormatString.cpp
+++ b/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;
+}