diff options
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r-- | clang/lib/Analysis/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/lib/Analysis/FormatString.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Analysis/OSLog.cpp | 177 | ||||
-rw-r--r-- | clang/lib/Analysis/PrintfFormatString.cpp | 43 |
4 files changed, 2 insertions, 222 deletions
diff --git a/clang/lib/Analysis/CMakeLists.txt b/clang/lib/Analysis/CMakeLists.txt index fdc9e6cee8e..6c74c797d9b 100644 --- a/clang/lib/Analysis/CMakeLists.txt +++ b/clang/lib/Analysis/CMakeLists.txt @@ -16,7 +16,6 @@ add_clang_library(clangAnalysis Dominators.cpp FormatString.cpp LiveVariables.cpp - OSLog.cpp ObjCNoReturn.cpp PostOrderCFGView.cpp PrintfFormatString.cpp diff --git a/clang/lib/Analysis/FormatString.cpp b/clang/lib/Analysis/FormatString.cpp index c62e537e92d..2a518cac394 100644 --- a/clang/lib/Analysis/FormatString.cpp +++ b/clang/lib/Analysis/FormatString.cpp @@ -591,8 +591,6 @@ const char *ConversionSpecifier::toString() const { case cArg: return "c"; case sArg: return "s"; case pArg: return "p"; - case PArg: - return "P"; case nArg: return "n"; case PercentArg: return "%"; case ScanListArg: return "["; @@ -868,7 +866,6 @@ bool FormatSpecifier::hasStandardConversionSpecifier( case ConversionSpecifier::ObjCObjArg: case ConversionSpecifier::ScanListArg: case ConversionSpecifier::PercentArg: - case ConversionSpecifier::PArg: return true; case ConversionSpecifier::CArg: case ConversionSpecifier::SArg: diff --git a/clang/lib/Analysis/OSLog.cpp b/clang/lib/Analysis/OSLog.cpp deleted file mode 100644 index b57e0d1d13f..00000000000 --- a/clang/lib/Analysis/OSLog.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// TODO: header template - -#include "clang/Analysis/Analyses/OSLog.h" -#include "clang/AST/Attr.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/ExprObjC.h" -#include "clang/Analysis/Analyses/FormatString.h" -#include "clang/Basic/Builtins.h" -#include "llvm/ADT/SmallBitVector.h" - -using namespace clang; -using llvm::APInt; - -using clang::analyze_os_log::OSLogBufferItem; -using clang::analyze_os_log::OSLogBufferLayout; - -class OSLogFormatStringHandler - : public analyze_format_string::FormatStringHandler { -private: - struct ArgData { - const Expr *E = nullptr; - Optional<OSLogBufferItem::Kind> Kind; - Optional<unsigned> Size; - unsigned char Flags = 0; - }; - SmallVector<ArgData, 4> ArgsData; - ArrayRef<const Expr *> Args; - - OSLogBufferItem::Kind - getKind(analyze_format_string::ConversionSpecifier::Kind K) { - switch (K) { - case clang::analyze_format_string::ConversionSpecifier::sArg: // "%s" - return OSLogBufferItem::StringKind; - case clang::analyze_format_string::ConversionSpecifier::SArg: // "%S" - return OSLogBufferItem::WideStringKind; - case clang::analyze_format_string::ConversionSpecifier::PArg: { // "%P" - return OSLogBufferItem::PointerKind; - case clang::analyze_format_string::ConversionSpecifier::ObjCObjArg: // "%@" - return OSLogBufferItem::ObjCObjKind; - case clang::analyze_format_string::ConversionSpecifier::PrintErrno: // "%m" - return OSLogBufferItem::ErrnoKind; - default: - return OSLogBufferItem::ScalarKind; - } - } - } - -public: - OSLogFormatStringHandler(ArrayRef<const Expr *> Args) : Args(Args) { - ArgsData.reserve(Args.size()); - } - - virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, - const char *StartSpecifier, - unsigned SpecifierLen) { - if (!FS.consumesDataArgument() && - FS.getConversionSpecifier().getKind() != - clang::analyze_format_string::ConversionSpecifier::PrintErrno) - return false; - - ArgsData.emplace_back(); - unsigned ArgIndex = FS.getArgIndex(); - if (ArgIndex < Args.size()) - ArgsData.back().E = Args[ArgIndex]; - - // First get the Kind - ArgsData.back().Kind = getKind(FS.getConversionSpecifier().getKind()); - if (ArgsData.back().Kind != OSLogBufferItem::ErrnoKind && - !ArgsData.back().E) { - // missing argument - ArgsData.pop_back(); - return false; - } - - switch (FS.getConversionSpecifier().getKind()) { - case clang::analyze_format_string::ConversionSpecifier::sArg: // "%s" - case clang::analyze_format_string::ConversionSpecifier::SArg: { // "%S" - auto &precision = FS.getPrecision(); - switch (precision.getHowSpecified()) { - case clang::analyze_format_string::OptionalAmount::NotSpecified: // "%s" - break; - case clang::analyze_format_string::OptionalAmount::Constant: // "%.16s" - ArgsData.back().Size = precision.getConstantAmount(); - break; - case clang::analyze_format_string::OptionalAmount::Arg: // "%.*s" - ArgsData.back().Kind = OSLogBufferItem::CountKind; - break; - case clang::analyze_format_string::OptionalAmount::Invalid: - return false; - } - break; - } - case clang::analyze_format_string::ConversionSpecifier::PArg: { // "%P" - auto &precision = FS.getPrecision(); - switch (precision.getHowSpecified()) { - case clang::analyze_format_string::OptionalAmount::NotSpecified: // "%P" - return false; // length must be supplied with pointer format specifier - case clang::analyze_format_string::OptionalAmount::Constant: // "%.16P" - ArgsData.back().Size = precision.getConstantAmount(); - break; - case clang::analyze_format_string::OptionalAmount::Arg: // "%.*P" - ArgsData.back().Kind = OSLogBufferItem::CountKind; - break; - case clang::analyze_format_string::OptionalAmount::Invalid: - return false; - } - break; - } - default: - break; - } - - if (FS.isPrivate()) { - ArgsData.back().Flags |= OSLogBufferItem::IsPrivate; - } - if (FS.isPublic()) { - ArgsData.back().Flags |= OSLogBufferItem::IsPublic; - } - return true; - } - - void computeLayout(ASTContext &Ctx, OSLogBufferLayout &Layout) const { - Layout.Items.clear(); - for (auto &Data : ArgsData) { - if (Data.Size) - Layout.Items.emplace_back(Ctx, CharUnits::fromQuantity(*Data.Size), - Data.Flags); - if (Data.Kind) { - CharUnits Size; - if (*Data.Kind == OSLogBufferItem::ErrnoKind) - Size = CharUnits::Zero(); - else - Size = Ctx.getTypeSizeInChars(Data.E->getType()); - Layout.Items.emplace_back(*Data.Kind, Data.E, Size, Data.Flags); - } else { - auto Size = Ctx.getTypeSizeInChars(Data.E->getType()); - Layout.Items.emplace_back(OSLogBufferItem::ScalarKind, Data.E, Size, - Data.Flags); - } - } - } -}; - -bool clang::analyze_os_log::computeOSLogBufferLayout( - ASTContext &Ctx, const CallExpr *E, OSLogBufferLayout &Layout) { - ArrayRef<const Expr *> Args(E->getArgs(), E->getArgs() + E->getNumArgs()); - - const Expr *StringArg; - ArrayRef<const Expr *> VarArgs; - switch (E->getBuiltinCallee()) { - case Builtin::BI__builtin_os_log_format_buffer_size: - assert(E->getNumArgs() >= 1 && - "__builtin_os_log_format_buffer_size takes at least 1 argument"); - StringArg = E->getArg(0); - VarArgs = Args.slice(1); - break; - case Builtin::BI__builtin_os_log_format: - assert(E->getNumArgs() >= 2 && - "__builtin_os_log_format takes at least 2 arguments"); - StringArg = E->getArg(1); - VarArgs = Args.slice(2); - break; - default: - llvm_unreachable("non-os_log builtin passed to computeOSLogBufferLayout"); - } - - const StringLiteral *Lit = cast<StringLiteral>(StringArg->IgnoreParenCasts()); - assert(Lit && (Lit->isAscii() || Lit->isUTF8())); - StringRef Data = Lit->getString(); - OSLogFormatStringHandler H(VarArgs); - ParsePrintfString(H, Data.begin(), Data.end(), Ctx.getLangOpts(), - Ctx.getTargetInfo(), /*isFreeBSDKPrintf*/ false); - - H.computeLayout(Ctx, Layout); - return true; -} diff --git a/clang/lib/Analysis/PrintfFormatString.cpp b/clang/lib/Analysis/PrintfFormatString.cpp index ed7193ecb43..ac6cef9d084 100644 --- a/clang/lib/Analysis/PrintfFormatString.cpp +++ b/clang/lib/Analysis/PrintfFormatString.cpp @@ -119,39 +119,6 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, return true; } - const char *OSLogVisibilityFlagsStart = nullptr, - *OSLogVisibilityFlagsEnd = nullptr; - if (*I == '{') { - OSLogVisibilityFlagsStart = I++; - // Find the end of the modifier. - while (I != E && *I != '}') { - I++; - } - if (I == E) { - if (Warn) - H.HandleIncompleteSpecifier(Start, E - Start); - return true; - } - assert(*I == '}'); - OSLogVisibilityFlagsEnd = I++; - - // Just see if 'private' or 'public' is the first word. os_log itself will - // do any further parsing. - const char *P = OSLogVisibilityFlagsStart + 1; - while (P < OSLogVisibilityFlagsEnd && isspace(*P)) - P++; - const char *WordStart = P; - while (P < OSLogVisibilityFlagsEnd && (isalnum(*P) || *P == '_')) - P++; - const char *WordEnd = P; - StringRef Word(WordStart, WordEnd - WordStart); - if (Word == "private") { - FS.setIsPrivate(WordStart); - } else if (Word == "public") { - FS.setIsPublic(WordStart); - } - } - // Look for flags (if any). bool hasMore = true; for ( ; I != E; ++I) { @@ -286,10 +253,6 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, // POSIX specific. case 'C': k = ConversionSpecifier::CArg; break; case 'S': k = ConversionSpecifier::SArg; break; - // Apple extension for os_log - case 'P': - k = ConversionSpecifier::PArg; - break; // Objective-C. case '@': k = ConversionSpecifier::ObjCObjArg; break; // Glibc specific. @@ -338,7 +301,7 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, conversionPosition); return true; } - + PrintfConversionSpecifier CS(conversionPosition, k); FS.setConversionSpecifier(CS); if (CS.consumesDataArgument() && !FS.usesPositionalArg()) @@ -578,7 +541,6 @@ ArgType PrintfSpecifier::getArgType(ASTContext &Ctx, return Ctx.IntTy; return ArgType(Ctx.WideCharTy, "wchar_t"); case ConversionSpecifier::pArg: - case ConversionSpecifier::PArg: return ArgType::CPointerTy; case ConversionSpecifier::ObjCObjArg: return ArgType::ObjCPointerTy; @@ -938,7 +900,7 @@ bool PrintfSpecifier::hasValidPrecision() const { if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) return true; - // Precision is only valid with the diouxXaAeEfFgGsP conversions + // Precision is only valid with the diouxXaAeEfFgGs conversions switch (CS.getKind()) { case ConversionSpecifier::dArg: case ConversionSpecifier::DArg: @@ -960,7 +922,6 @@ bool PrintfSpecifier::hasValidPrecision() const { case ConversionSpecifier::sArg: case ConversionSpecifier::FreeBSDrArg: case ConversionSpecifier::FreeBSDyArg: - case ConversionSpecifier::PArg: return true; default: |