diff options
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/FormatString.cpp | 34 | ||||
-rw-r--r-- | lib/Analysis/PrintfFormatString.cpp | 17 | ||||
-rw-r--r-- | lib/Analysis/ScanfFormatString.cpp | 17 |
3 files changed, 38 insertions, 30 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; +} diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp index aa6d7424c0..2a9644a353 100644 --- a/lib/Analysis/PrintfFormatString.cpp +++ b/lib/Analysis/PrintfFormatString.cpp @@ -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); diff --git a/lib/Analysis/ScanfFormatString.cpp b/lib/Analysis/ScanfFormatString.cpp index 066d5d6fa1..5c7e6ef8f2 100644 --- a/lib/Analysis/ScanfFormatString.cpp +++ b/lib/Analysis/ScanfFormatString.cpp @@ -382,21 +382,8 @@ bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, } // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99. - if (isa<TypedefType>(PT) && (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>(PT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) + namedTypeToLengthModifier(PT, LM); // If fixing the length modifier was enough, we are done. const analyze_scanf::ScanfArgTypeResult &ATR = getArgType(Ctx); |