Author: mehdi_amini Date: Mon Oct 24 14:41:36 2016 New Revision: 285007 URL: http://llvm.org/viewvc/llvm-project?rev=285007&view=rev Log: Revert "Add support for __builtin_os_log_format[_buffer_size]"
This reverts commit r284990, two opencl test are broken Removed: cfe/trunk/include/clang/Analysis/Analyses/OSLog.h cfe/trunk/lib/Analysis/OSLog.cpp cfe/trunk/test/CodeGenObjC/os_log.m cfe/trunk/test/SemaObjC/format-strings-oslog.m Modified: cfe/trunk/include/clang/Analysis/Analyses/FormatString.h cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Analysis/CMakeLists.txt cfe/trunk/lib/Analysis/FormatString.cpp cfe/trunk/lib/Analysis/PrintfFormatString.cpp cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Sema/SemaChecking.cpp cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/test/CodeGen/builtins.c Modified: cfe/trunk/include/clang/Analysis/Analyses/FormatString.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/FormatString.h?rev=285007&r1=285006&r2=285007&view=diff ============================================================================== --- cfe/trunk/include/clang/Analysis/Analyses/FormatString.h (original) +++ cfe/trunk/include/clang/Analysis/Analyses/FormatString.h Mon Oct 24 14:41:36 2016 @@ -35,7 +35,7 @@ class OptionalFlag { public: OptionalFlag(const char *Representation) : representation(Representation), flag(false) {} - bool isSet() const { return flag; } + bool isSet() { return flag; } void set() { flag = true; } void clear() { flag = false; } void setPosition(const char *position) { @@ -122,13 +122,12 @@ class ConversionSpecifier { public: enum Kind { InvalidSpecifier = 0, - // C99 conversion specifiers. + // C99 conversion specifiers. cArg, dArg, DArg, // Apple extension iArg, - IntArgBeg = dArg, - IntArgEnd = iArg, + IntArgBeg = dArg, IntArgEnd = iArg, oArg, OArg, // Apple extension @@ -136,8 +135,7 @@ public: UArg, // Apple extension xArg, XArg, - UIntArgBeg = oArg, - UIntArgEnd = XArg, + UIntArgBeg = oArg, UIntArgEnd = XArg, fArg, FArg, @@ -147,8 +145,7 @@ public: GArg, aArg, AArg, - DoubleArgBeg = fArg, - DoubleArgEnd = AArg, + DoubleArgBeg = fArg, DoubleArgEnd = AArg, sArg, pArg, @@ -157,19 +154,13 @@ public: CArg, SArg, - // Apple extension: P specifies to os_log that the data being pointed to is - // to be copied by os_log. The precision indicates the number of bytes to - // copy. - PArg, - // ** Printf-specific ** ZArg, // MS extension // Objective-C specific specifiers. - ObjCObjArg, // '@' - ObjCBeg = ObjCObjArg, - ObjCEnd = ObjCObjArg, + ObjCObjArg, // '@' + ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg, // FreeBSD kernel specific specifiers. FreeBSDbArg, @@ -178,15 +169,13 @@ public: FreeBSDyArg, // GlibC specific specifiers. - PrintErrno, // 'm' + PrintErrno, // 'm' - PrintfConvBeg = ObjCObjArg, - PrintfConvEnd = PrintErrno, + PrintfConvBeg = ObjCObjArg, PrintfConvEnd = PrintErrno, // ** Scanf-specific ** ScanListArg, // '[' - ScanfConvBeg = ScanListArg, - ScanfConvEnd = ScanListArg + ScanfConvBeg = ScanListArg, ScanfConvEnd = ScanListArg }; ConversionSpecifier(bool isPrintf = true) @@ -448,15 +437,13 @@ class PrintfSpecifier : public analyze_f OptionalFlag HasAlternativeForm; // '#' OptionalFlag HasLeadingZeroes; // '0' OptionalFlag HasObjCTechnicalTerm; // '[tt]' - OptionalFlag IsPrivate; // '{private}' - OptionalFlag IsPublic; // '{public}' OptionalAmount Precision; public: - PrintfSpecifier() - : FormatSpecifier(/* isPrintf = */ true), HasThousandsGrouping("'"), - IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "), - HasAlternativeForm("#"), HasLeadingZeroes("0"), - HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public") {} + PrintfSpecifier() : + FormatSpecifier(/* isPrintf = */ true), + HasThousandsGrouping("'"), IsLeftJustified("-"), HasPlusPrefix("+"), + HasSpacePrefix(" "), HasAlternativeForm("#"), HasLeadingZeroes("0"), + HasObjCTechnicalTerm("tt") {} static PrintfSpecifier Parse(const char *beg, const char *end); @@ -485,8 +472,6 @@ public: void setHasObjCTechnicalTerm(const char *position) { HasObjCTechnicalTerm.setPosition(position); } - void setIsPrivate(const char *position) { IsPrivate.setPosition(position); } - void setIsPublic(const char *position) { IsPublic.setPosition(position); } void setUsesPositionalArg() { UsesPositionalArg = true; } // Methods for querying the format specifier. @@ -524,8 +509,6 @@ public: const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; } const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; } const OptionalFlag &hasObjCTechnicalTerm() const { return HasObjCTechnicalTerm; } - const OptionalFlag &isPrivate() const { return IsPrivate; } - const OptionalFlag &isPublic() const { return IsPublic; } bool usesPositionalArg() const { return UsesPositionalArg; } /// Changes the specifier and length according to a QualType, retaining any Removed: cfe/trunk/include/clang/Analysis/Analyses/OSLog.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/OSLog.h?rev=285006&view=auto ============================================================================== --- cfe/trunk/include/clang/Analysis/Analyses/OSLog.h (original) +++ cfe/trunk/include/clang/Analysis/Analyses/OSLog.h (removed) @@ -1,155 +0,0 @@ -//= OSLog.h - Analysis of calls to os_log builtins --*- C++ -*-===============// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines APIs for determining the layout of the data buffer for -// os_log() and os_trace(). -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H -#define LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H - -#include "clang/AST/ASTContext.h" -#include "clang/AST/Expr.h" - -namespace clang { -namespace analyze_os_log { - -/// An OSLogBufferItem represents a single item in the data written by a call -/// to os_log() or os_trace(). -class OSLogBufferItem { -public: - enum Kind { - // The item is a scalar (int, float, raw pointer, etc.). No further copying - // is required. This is the only kind allowed by os_trace(). - ScalarKind = 0, - - // The item is a count, which describes the length of the following item to - // be copied. A count may only be followed by an item of kind StringKind, - // WideStringKind, or PointerKind. - CountKind, - - // The item is a pointer to a C string. If preceded by a count 'n', - // os_log() will copy at most 'n' bytes from the pointer. - StringKind, - - // The item is a pointer to a block of raw data. This item must be preceded - // by a count 'n'. os_log() will copy exactly 'n' bytes from the pointer. - PointerKind, - - // The item is a pointer to an Objective-C object. os_log() may retain the - // object for later processing. - ObjCObjKind, - - // The item is a pointer to wide-char string. - WideStringKind, - - // The item is corresponding to the '%m' format specifier, no value is - // populated in the buffer and the runtime is loading the errno value. - ErrnoKind - }; - - enum { - // The item is marked "private" in the format string. - IsPrivate = 0x1, - - // The item is marked "public" in the format string. - IsPublic = 0x2 - }; - -private: - Kind TheKind = ScalarKind; - const Expr *TheExpr = nullptr; - CharUnits ConstValue; - CharUnits Size; // size of the data, not including the header bytes - unsigned Flags = 0; - -public: - OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags) - : TheKind(kind), TheExpr(expr), Size(size), Flags(flags) {} - - OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags) - : TheKind(CountKind), ConstValue(value), - Size(Ctx.getTypeSizeInChars(Ctx.IntTy)), Flags(flags) {} - - unsigned char getDescriptorByte() const { - unsigned char result = 0; - if (getIsPrivate()) - result |= IsPrivate; - if (getIsPublic()) - result |= IsPublic; - result |= ((unsigned)getKind()) << 4; - return result; - } - - unsigned char getSizeByte() const { return size().getQuantity(); } - - Kind getKind() const { return TheKind; } - bool getIsPrivate() const { return (Flags & IsPrivate) != 0; } - bool getIsPublic() const { return (Flags & IsPublic) != 0; } - - const Expr *getExpr() const { return TheExpr; } - CharUnits getConstValue() const { return ConstValue; } - CharUnits size() const { return Size; } -}; - -class OSLogBufferLayout { -public: - SmallVector<OSLogBufferItem, 4> Items; - - enum Flags { HasPrivateItems = 1, HasNonScalarItems = 1 << 1 }; - - CharUnits size() const { - CharUnits result; - result += CharUnits::fromQuantity(2); // summary byte, num-args byte - for (auto &item : Items) { - // descriptor byte, size byte - result += item.size() + CharUnits::fromQuantity(2); - } - return result; - } - - bool hasPrivateItems() const { - return llvm::any_of( - Items, [](const OSLogBufferItem &Item) { return Item.getIsPrivate(); }); - } - - bool hasPublicItems() const { - return llvm::any_of( - Items, [](const OSLogBufferItem &Item) { return Item.getIsPublic(); }); - } - - bool hasNonScalar() const { - return llvm::any_of(Items, [](const OSLogBufferItem &Item) { - return Item.getKind() != OSLogBufferItem::ScalarKind; - }); - } - - unsigned char getSummaryByte() const { - unsigned char result = 0; - if (hasPrivateItems()) - result |= HasPrivateItems; - if (hasNonScalar()) - result |= HasNonScalarItems; - return result; - } - - unsigned char getNumArgsByte() const { return Items.size(); } -}; - -// Given a call 'E' to one of the builtins __builtin_os_log_format() or -// __builtin_os_log_format_buffer_size(), compute the layout of the buffer that -// the call will write into and store it in 'layout'. Returns 'false' if there -// was some error encountered while computing the layout, and 'true' otherwise. -bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, - OSLogBufferLayout &layout); - -} // namespace analyze_os_log -} // namespace clang -#endif Modified: cfe/trunk/include/clang/Basic/Builtins.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=285007&r1=285006&r2=285007&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Builtins.def (original) +++ cfe/trunk/include/clang/Basic/Builtins.def Mon Oct 24 14:41:36 2016 @@ -1384,10 +1384,6 @@ LANGBUILTIN(to_global, "v*v*", "tn", OCL LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG) LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG) -// Builtins for os_log/os_trace -BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut") -BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt") - #undef BUILTIN #undef LIBBUILTIN #undef LANGBUILTIN Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=285007&r1=285006&r2=285007&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct 24 14:41:36 2016 @@ -7413,12 +7413,6 @@ def warn_format_non_standard: Warning< def warn_format_non_standard_conversion_spec: Warning< "using length modifier '%0' with conversion specifier '%1' is not supported by ISO C">, InGroup<FormatNonStandard>, DefaultIgnore; -def warn_format_invalid_annotation : Warning< - "using '%0' format specifier annotation outside of os_log()/os_trace()">, - InGroup<Format>; -def warn_format_P_no_precision : Warning< - "using '%%P' format specifier without precision">, - InGroup<Format>; def warn_printf_ignored_flag: Warning< "flag '%0' is ignored when flag '%1' is present">, InGroup<Format>; @@ -7555,15 +7549,6 @@ def warn_cfstring_truncated : Warning< "belong to the input codeset UTF-8">, InGroup<DiagGroup<"CFString-literal">>; -// os_log checking -// TODO: separate diagnostic for os_trace() -def err_os_log_format_not_string_constant : Error< - "os_log() format argument is not a string constant">; -def err_os_log_argument_too_big : Error< - "os_log() argument %d is too big (%d bytes, max %d)">; -def warn_os_log_format_narg : Error< - "os_log() '%%n' format specifier is not allowed">, DefaultError; - // Statements. def err_continue_not_in_loop : Error< "'continue' statement not in loop statement">; Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=285007&r1=285006&r2=285007&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Mon Oct 24 14:41:36 2016 @@ -9679,7 +9679,6 @@ private: VariadicCallType CallType); bool CheckObjCString(Expr *Arg); - ExprResult CheckOSLogFormatStringArg(Expr *Arg); ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, CallExpr *TheCall); @@ -9702,7 +9701,6 @@ private: bool SemaBuiltinVAStartARM(CallExpr *Call); bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs); - bool SemaBuiltinOSLogFormat(CallExpr *TheCall); public: // Used by C++ template instantiation. @@ -9740,7 +9738,6 @@ public: FST_Kprintf, FST_FreeBSDKPrintf, FST_OSTrace, - FST_OSLog, FST_Unknown }; static FormatStringType GetFormatStringType(const FormatAttr *Format); Modified: cfe/trunk/lib/Analysis/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=285007&r1=285006&r2=285007&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/CMakeLists.txt (original) +++ cfe/trunk/lib/Analysis/CMakeLists.txt Mon Oct 24 14:41:36 2016 @@ -16,7 +16,6 @@ add_clang_library(clangAnalysis Dominators.cpp FormatString.cpp LiveVariables.cpp - OSLog.cpp ObjCNoReturn.cpp PostOrderCFGView.cpp PrintfFormatString.cpp Modified: cfe/trunk/lib/Analysis/FormatString.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/FormatString.cpp?rev=285007&r1=285006&r2=285007&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/FormatString.cpp (original) +++ cfe/trunk/lib/Analysis/FormatString.cpp Mon Oct 24 14:41:36 2016 @@ -591,8 +591,6 @@ const char *ConversionSpecifier::toStrin 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::hasStandardConvers case ConversionSpecifier::ObjCObjArg: case ConversionSpecifier::ScanListArg: case ConversionSpecifier::PercentArg: - case ConversionSpecifier::PArg: return true; case ConversionSpecifier::CArg: case ConversionSpecifier::SArg: Removed: cfe/trunk/lib/Analysis/OSLog.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/OSLog.cpp?rev=285006&view=auto ============================================================================== --- cfe/trunk/lib/Analysis/OSLog.cpp (original) +++ cfe/trunk/lib/Analysis/OSLog.cpp (removed) @@ -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; -} Modified: cfe/trunk/lib/Analysis/PrintfFormatString.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp?rev=285007&r1=285006&r2=285007&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/PrintfFormatString.cpp (original) +++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp Mon Oct 24 14:41:36 2016 @@ -119,39 +119,6 @@ static PrintfSpecifierResult ParsePrintf 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 ParsePrintf // 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 ParsePrintf conversionPosition); return true; } - + PrintfConversionSpecifier CS(conversionPosition, k); FS.setConversionSpecifier(CS); if (CS.consumesDataArgument() && !FS.usesPositionalArg()) @@ -578,7 +541,6 @@ ArgType PrintfSpecifier::getArgType(ASTC 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( 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( case ConversionSpecifier::sArg: case ConversionSpecifier::FreeBSDrArg: case ConversionSpecifier::FreeBSDyArg: - case ConversionSpecifier::PArg: return true; default: Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=285007&r1=285006&r2=285007&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Mon Oct 24 14:41:36 2016 @@ -11,15 +11,14 @@ // //===----------------------------------------------------------------------===// +#include "CodeGenFunction.h" #include "CGCXXABI.h" #include "CGObjCRuntime.h" #include "CGOpenCLRuntime.h" -#include "CodeGenFunction.h" #include "CodeGenModule.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" -#include "clang/Analysis/Analyses/OSLog.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" @@ -565,18 +564,6 @@ Value *CodeGenFunction::EmitMSVCBuiltinE llvm_unreachable("Incorrect MSVC intrinsic!"); } -namespace { -// ARC cleanup for __builtin_os_log_format -struct CallObjCArcUse final : EHScopeStack::Cleanup { - CallObjCArcUse(llvm::Value *object) : object(object) {} - llvm::Value *object; - - void Emit(CodeGenFunction &CGF, Flags flags) override { - CGF.EmitARCIntrinsicUse(object); - } -}; -} - RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue) { @@ -2610,76 +2597,6 @@ RValue CodeGenFunction::EmitBuiltinExpr( // Fall through - it's already mapped to the intrinsic by GCCBuiltin. break; } - case Builtin::BI__builtin_os_log_format: { - assert(E->getNumArgs() >= 2 && - "__builtin_os_log_format takes at least 2 arguments"); - analyze_os_log::OSLogBufferLayout Layout; - analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout); - Address BufAddr = EmitPointerWithAlignment(E->getArg(0)); - // Ignore argument 1, the format string. It is not currently used. - CharUnits Offset; - Builder.CreateStore( - Builder.getInt8(Layout.getSummaryByte()), - Builder.CreateConstByteGEP(BufAddr, Offset++, "summary")); - Builder.CreateStore( - Builder.getInt8(Layout.getNumArgsByte()), - Builder.CreateConstByteGEP(BufAddr, Offset++, "numArgs")); - - llvm::SmallVector<llvm::Value *, 4> RetainableOperands; - for (const auto &Item : Layout.Items) { - Builder.CreateStore( - Builder.getInt8(Item.getDescriptorByte()), - Builder.CreateConstByteGEP(BufAddr, Offset++, "argDescriptor")); - Builder.CreateStore( - Builder.getInt8(Item.getSizeByte()), - Builder.CreateConstByteGEP(BufAddr, Offset++, "argSize")); - Address Addr = Builder.CreateConstByteGEP(BufAddr, Offset); - if (const Expr *TheExpr = Item.getExpr()) { - Addr = Builder.CreateElementBitCast( - Addr, ConvertTypeForMem(TheExpr->getType())); - // Check if this is a retainable type. - if (TheExpr->getType()->isObjCRetainableType()) { - assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar && - "Only scalar can be a ObjC retainable type"); - llvm::Value *SV = EmitScalarExpr(TheExpr, /*Ignore*/ false); - RValue RV = RValue::get(SV); - LValue LV = MakeAddrLValue(Addr, TheExpr->getType()); - EmitStoreThroughLValue(RV, LV); - // Check if the object is constant, if not, save it in - // RetainableOperands. - if (!isa<Constant>(SV)) - RetainableOperands.push_back(SV); - } else { - EmitAnyExprToMem(TheExpr, Addr, Qualifiers(), /*isInit*/ true); - } - } else { - Addr = Builder.CreateElementBitCast(Addr, Int32Ty); - Builder.CreateStore( - Builder.getInt32(Item.getConstValue().getQuantity()), Addr); - } - Offset += Item.size(); - } - - // Push a clang.arc.use cleanup for each object in RetainableOperands. The - // cleanup will cause the use to appear after the final log call, keeping - // the object valid while itâs held in the log buffer. Note that if thereâs - // a release cleanup on the object, it will already be active; since - // cleanups are emitted in reverse order, the use will occur before the - // object is released. - if (!RetainableOperands.empty() && getLangOpts().ObjCAutoRefCount && - CGM.getCodeGenOpts().OptimizationLevel != 0) - for (llvm::Value *object : RetainableOperands) - pushFullExprCleanup<CallObjCArcUse>(getARCCleanupKind(), object); - - return RValue::get(BufAddr.getPointer()); - } - - case Builtin::BI__builtin_os_log_format_buffer_size: { - analyze_os_log::OSLogBufferLayout Layout; - analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout); - return RValue::get(ConstantInt::get(ConvertType(E->getType()), - Layout.size().getQuantity())); - } } // If this is an alias for a lib function (e.g. __builtin_sin), emit Modified: cfe/trunk/lib/Sema/SemaChecking.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=285007&r1=285006&r2=285007&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaChecking.cpp (original) +++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Oct 24 14:41:36 2016 @@ -1065,12 +1065,6 @@ Sema::CheckBuiltinFunctionCall(FunctionD case Builtin::BIget_kernel_preferred_work_group_size_multiple: if (SemaOpenCLBuiltinKernelWorkGroupSize(*this, TheCall)) return ExprError(); - case Builtin::BI__builtin_os_log_format: - case Builtin::BI__builtin_os_log_format_buffer_size: - if (SemaBuiltinOSLogFormat(TheCall)) { - return ExprError(); - } - break; } // Since the target specific builtins for each arch overlap, only check those @@ -3484,31 +3478,6 @@ bool Sema::CheckObjCString(Expr *Arg) { return false; } -/// CheckObjCString - Checks that the format string argument to the os_log() -/// and os_trace() functions is correct, and converts it to const char *. -ExprResult Sema::CheckOSLogFormatStringArg(Expr *Arg) { - Arg = Arg->IgnoreParenCasts(); - auto *Literal = dyn_cast<StringLiteral>(Arg); - if (!Literal) { - if (auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) { - Literal = ObjcLiteral->getString(); - } - } - - if (!Literal || (!Literal->isAscii() && !Literal->isUTF8())) { - return ExprError( - Diag(Arg->getLocStart(), diag::err_os_log_format_not_string_constant) - << Arg->getSourceRange()); - } - - ExprResult Result(Literal); - QualType ResultTy = Context.getPointerType(Context.CharTy.withConst()); - InitializedEntity Entity = - InitializedEntity::InitializeParameter(Context, ResultTy, false); - Result = PerformCopyInitialization(Entity, SourceLocation(), Result); - return Result; -} - /// Check the arguments to '__builtin_va_start' or '__builtin_ms_va_start' /// for validity. Emit an error and return true on failure; return false /// on success. @@ -3970,86 +3939,6 @@ bool Sema::SemaBuiltinAssumeAligned(Call return false; } -bool Sema::SemaBuiltinOSLogFormat(CallExpr *TheCall) { - unsigned BuiltinID = - cast<FunctionDecl>(TheCall->getCalleeDecl())->getBuiltinID(); - bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size; - - unsigned NumArgs = TheCall->getNumArgs(); - unsigned NumRequiredArgs = IsSizeCall ? 1 : 2; - if (NumArgs < NumRequiredArgs) { - return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) - << 0 /* function call */ << NumRequiredArgs << NumArgs - << TheCall->getSourceRange(); - } - if (NumArgs >= NumRequiredArgs + 0x100) { - return Diag(TheCall->getLocEnd(), - diag::err_typecheck_call_too_many_args_at_most) - << 0 /* function call */ << (NumRequiredArgs + 0xff) << NumArgs - << TheCall->getSourceRange(); - } - unsigned i = 0; - - // For formatting call, check buffer arg. - if (!IsSizeCall) { - ExprResult Arg(TheCall->getArg(i)); - InitializedEntity Entity = InitializedEntity::InitializeParameter( - Context, Context.VoidPtrTy, false); - Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg); - if (Arg.isInvalid()) - return true; - TheCall->setArg(i, Arg.get()); - i++; - } - - // Check string literal arg. - unsigned FormatIdx = i; - { - ExprResult Arg = CheckOSLogFormatStringArg(TheCall->getArg(i)); - if (Arg.isInvalid()) - return true; - TheCall->setArg(i, Arg.get()); - i++; - } - - // Make sure variadic args are scalar. - unsigned FirstDataArg = i; - while (i < NumArgs) { - ExprResult Arg = DefaultVariadicArgumentPromotion( - TheCall->getArg(i), VariadicFunction, nullptr); - if (Arg.isInvalid()) - return true; - CharUnits ArgSize = Context.getTypeSizeInChars(Arg.get()->getType()); - if (ArgSize.getQuantity() >= 0x100) { - return Diag(Arg.get()->getLocEnd(), diag::err_os_log_argument_too_big) - << i << (int)ArgSize.getQuantity() << 0xff - << TheCall->getSourceRange(); - } - TheCall->setArg(i, Arg.get()); - i++; - } - - // Check formatting specifiers. NOTE: We're only doing this for the non-size - // call to avoid duplicate diagnostics. - if (!IsSizeCall) { - llvm::SmallBitVector CheckedVarArgs(NumArgs, false); - ArrayRef<const Expr *> Args(TheCall->getArgs(), TheCall->getNumArgs()); - bool Success = CheckFormatArguments( - Args, /*HasVAListArg*/ false, FormatIdx, FirstDataArg, FST_OSLog, - VariadicFunction, TheCall->getLocStart(), SourceRange(), - CheckedVarArgs); - if (!Success) - return true; - } - - if (IsSizeCall) { - TheCall->setType(Context.getSizeType()); - } else { - TheCall->setType(Context.VoidPtrTy); - } - return false; -} - /// SemaBuiltinConstantArg - Handle a check if argument ArgNum of CallExpr /// TheCall is a constant expression. bool Sema::SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum, @@ -4680,16 +4569,15 @@ checkFormatStringExpr(Sema &S, const Exp Sema::FormatStringType Sema::GetFormatStringType(const FormatAttr *Format) { return llvm::StringSwitch<FormatStringType>(Format->getType()->getName()) - .Case("scanf", FST_Scanf) - .Cases("printf", "printf0", FST_Printf) - .Cases("NSString", "CFString", FST_NSString) - .Case("strftime", FST_Strftime) - .Case("strfmon", FST_Strfmon) - .Cases("kprintf", "cmn_err", "vcmn_err", "zcmn_err", FST_Kprintf) - .Case("freebsd_kprintf", FST_FreeBSDKPrintf) - .Case("os_trace", FST_OSLog) - .Case("os_log", FST_OSLog) - .Default(FST_Unknown); + .Case("scanf", FST_Scanf) + .Cases("printf", "printf0", FST_Printf) + .Cases("NSString", "CFString", FST_NSString) + .Case("strftime", FST_Strftime) + .Case("strfmon", FST_Strfmon) + .Cases("kprintf", "cmn_err", "vcmn_err", "zcmn_err", FST_Kprintf) + .Case("freebsd_kprintf", FST_FreeBSDKPrintf) + .Case("os_trace", FST_OSTrace) + .Default(FST_Unknown); } /// CheckFormatArguments - Check calls to printf and scanf (and similar @@ -4799,7 +4687,6 @@ protected: Sema &S; const FormatStringLiteral *FExpr; const Expr *OrigFormatExpr; - const Sema::FormatStringType FSType; const unsigned FirstDataArg; const unsigned NumDataArgs; const char *Beg; // Start of format string. @@ -4816,19 +4703,20 @@ protected: public: CheckFormatHandler(Sema &s, const FormatStringLiteral *fexpr, - const Expr *origFormatExpr, - const Sema::FormatStringType type, unsigned firstDataArg, + const Expr *origFormatExpr, unsigned firstDataArg, unsigned numDataArgs, const char *beg, bool hasVAListArg, - ArrayRef<const Expr *> Args, unsigned formatIdx, - bool inFunctionCall, Sema::VariadicCallType callType, + ArrayRef<const Expr *> Args, + unsigned formatIdx, bool inFunctionCall, + Sema::VariadicCallType callType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg) - : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(type), - FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg), - HasVAListArg(hasVAListArg), Args(Args), FormatIdx(formatIdx), - usesPositionalArgs(false), atFirstArg(true), - inFunctionCall(inFunctionCall), CallType(callType), - CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) { + : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), + FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), + Beg(beg), HasVAListArg(hasVAListArg), + Args(Args), FormatIdx(formatIdx), + usesPositionalArgs(false), atFirstArg(true), + inFunctionCall(inFunctionCall), CallType(callType), + CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) { CoveredArgs.resize(numDataArgs); CoveredArgs.reset(); } @@ -5251,28 +5139,24 @@ void CheckFormatHandler::EmitFormatDiagn namespace { class CheckPrintfHandler : public CheckFormatHandler { + bool ObjCContext; + public: CheckPrintfHandler(Sema &s, const FormatStringLiteral *fexpr, - const Expr *origFormatExpr, - const Sema::FormatStringType type, unsigned firstDataArg, - unsigned numDataArgs, bool isObjC, const char *beg, - bool hasVAListArg, ArrayRef<const Expr *> Args, + const Expr *origFormatExpr, unsigned firstDataArg, + unsigned numDataArgs, bool isObjC, + const char *beg, bool hasVAListArg, + ArrayRef<const Expr *> Args, unsigned formatIdx, bool inFunctionCall, Sema::VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg) - : CheckFormatHandler(s, fexpr, origFormatExpr, type, firstDataArg, - numDataArgs, beg, hasVAListArg, Args, formatIdx, - inFunctionCall, CallType, CheckedVarArgs, - UncoveredArg) {} - - bool isObjCContext() const { return FSType == Sema::FST_NSString; } - - /// Returns true if '%@' specifiers are allowed in the format string. - bool allowsObjCArg() const { - return FSType == Sema::FST_NSString || FSType == Sema::FST_OSLog || - FSType == Sema::FST_OSTrace; - } + : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg, + numDataArgs, beg, hasVAListArg, Args, + formatIdx, inFunctionCall, CallType, CheckedVarArgs, + UncoveredArg), + ObjCContext(isObjC) + {} bool HandleInvalidPrintfConversionSpecifier( const analyze_printf::PrintfSpecifier &FS, @@ -5626,54 +5510,11 @@ CheckPrintfHandler::HandlePrintfSpecifie // Check for using an Objective-C specific conversion specifier // in a non-ObjC literal. - if (!allowsObjCArg() && CS.isObjCArg()) { + if (!ObjCContext && CS.isObjCArg()) { return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier, specifierLen); } - // %P can only be used with os_log. - if (FSType != Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::PArg) { - return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier, - specifierLen); - } - - // %n is not allowed with os_log. - if (FSType == Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::nArg) { - EmitFormatDiagnostic(S.PDiag(diag::warn_os_log_format_narg), - getLocationOfByte(CS.getStart()), - /*IsStringLocation*/ false, - getSpecifierRange(startSpecifier, specifierLen)); - - return true; - } - - // Only scalars are allowed for os_trace. - if (FSType == Sema::FST_OSTrace && - (CS.getKind() == ConversionSpecifier::PArg || - CS.getKind() == ConversionSpecifier::sArg || - CS.getKind() == ConversionSpecifier::ObjCObjArg)) { - return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier, - specifierLen); - } - - // Check for use of public/private annotation outside of os_log(). - if (FSType != Sema::FST_OSLog) { - if (FS.isPublic().isSet()) { - EmitFormatDiagnostic(S.PDiag(diag::warn_format_invalid_annotation) - << "public", - getLocationOfByte(FS.isPublic().getPosition()), - /*IsStringLocation*/ false, - getSpecifierRange(startSpecifier, specifierLen)); - } - if (FS.isPrivate().isSet()) { - EmitFormatDiagnostic(S.PDiag(diag::warn_format_invalid_annotation) - << "private", - getLocationOfByte(FS.isPrivate().getPosition()), - /*IsStringLocation*/ false, - getSpecifierRange(startSpecifier, specifierLen)); - } - } - // Check for invalid use of field width if (!FS.hasValidFieldWidth()) { HandleInvalidAmount(FS, FS.getFieldWidth(), /* field width */ 0, @@ -5686,15 +5527,6 @@ CheckPrintfHandler::HandlePrintfSpecifie startSpecifier, specifierLen); } - // Precision is mandatory for %P specifier. - if (CS.getKind() == ConversionSpecifier::PArg && - FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) { - EmitFormatDiagnostic(S.PDiag(diag::warn_format_P_no_precision), - getLocationOfByte(startSpecifier), - /*IsStringLocation*/ false, - getSpecifierRange(startSpecifier, specifierLen)); - } - // Check each flag does not conflict with any other component. if (!FS.hasValidThousandsGroupingPrefix()) HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen); @@ -5844,7 +5676,8 @@ CheckPrintfHandler::checkFormatExpr(cons using namespace analyze_printf; // Now type check the data expression that matches the // format specifier. - const analyze_printf::ArgType &AT = FS.getArgType(S.Context, isObjCContext()); + const analyze_printf::ArgType &AT = FS.getArgType(S.Context, + ObjCContext); if (!AT.isValid()) return true; @@ -5899,7 +5732,7 @@ CheckPrintfHandler::checkFormatExpr(cons // If the argument is an integer of some kind, believe the %C and suggest // a cast instead of changing the conversion specifier. QualType IntendedTy = ExprTy; - if (isObjCContext() && + if (ObjCContext && FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) { if (ExprTy->isIntegralOrUnscopedEnumerationType() && !ExprTy->isCharType()) { @@ -5940,8 +5773,8 @@ CheckPrintfHandler::checkFormatExpr(cons // We may be able to offer a FixItHint if it is a supported type. PrintfSpecifier fixedFS = FS; - bool success = - fixedFS.fixType(IntendedTy, S.getLangOpts(), S.Context, isObjCContext()); + bool success = fixedFS.fixType(IntendedTy, S.getLangOpts(), + S.Context, ObjCContext); if (success) { // Get the fix string from the fixed format specifier @@ -6097,18 +5930,19 @@ namespace { class CheckScanfHandler : public CheckFormatHandler { public: CheckScanfHandler(Sema &s, const FormatStringLiteral *fexpr, - const Expr *origFormatExpr, Sema::FormatStringType type, - unsigned firstDataArg, unsigned numDataArgs, - const char *beg, bool hasVAListArg, - ArrayRef<const Expr *> Args, unsigned formatIdx, - bool inFunctionCall, Sema::VariadicCallType CallType, + const Expr *origFormatExpr, unsigned firstDataArg, + unsigned numDataArgs, const char *beg, bool hasVAListArg, + ArrayRef<const Expr *> Args, + unsigned formatIdx, bool inFunctionCall, + Sema::VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg) - : CheckFormatHandler(s, fexpr, origFormatExpr, type, firstDataArg, - numDataArgs, beg, hasVAListArg, Args, formatIdx, - inFunctionCall, CallType, CheckedVarArgs, - UncoveredArg) {} - + : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg, + numDataArgs, beg, hasVAListArg, + Args, formatIdx, inFunctionCall, CallType, + CheckedVarArgs, UncoveredArg) + {} + bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS, const char *startSpecifier, unsigned specifierLen) override; @@ -6318,13 +6152,13 @@ static void CheckFormatString(Sema &S, c } if (Type == Sema::FST_Printf || Type == Sema::FST_NSString || - Type == Sema::FST_FreeBSDKPrintf || Type == Sema::FST_OSLog || - Type == Sema::FST_OSTrace) { - CheckPrintfHandler H( - S, FExpr, OrigFormatExpr, Type, firstDataArg, numDataArgs, - (Type == Sema::FST_NSString || Type == Sema::FST_OSTrace), Str, - HasVAListArg, Args, format_idx, inFunctionCall, CallType, - CheckedVarArgs, UncoveredArg); + Type == Sema::FST_FreeBSDKPrintf || Type == Sema::FST_OSTrace) { + CheckPrintfHandler H(S, FExpr, OrigFormatExpr, firstDataArg, + numDataArgs, (Type == Sema::FST_NSString || + Type == Sema::FST_OSTrace), + Str, HasVAListArg, Args, format_idx, + inFunctionCall, CallType, CheckedVarArgs, + UncoveredArg); if (!analyze_format_string::ParsePrintfString(H, Str, Str + StrLen, S.getLangOpts(), @@ -6332,9 +6166,10 @@ static void CheckFormatString(Sema &S, c Type == Sema::FST_FreeBSDKPrintf)) H.DoneProcessing(); } else if (Type == Sema::FST_Scanf) { - CheckScanfHandler H(S, FExpr, OrigFormatExpr, Type, firstDataArg, - numDataArgs, Str, HasVAListArg, Args, format_idx, - inFunctionCall, CallType, CheckedVarArgs, UncoveredArg); + CheckScanfHandler H(S, FExpr, OrigFormatExpr, firstDataArg, numDataArgs, + Str, HasVAListArg, Args, format_idx, + inFunctionCall, CallType, CheckedVarArgs, + UncoveredArg); if (!analyze_format_string::ParseScanfString(H, Str, Str + StrLen, S.getLangOpts(), Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=285007&r1=285006&r2=285007&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Oct 24 14:41:36 2016 @@ -2804,21 +2804,20 @@ enum FormatAttrKind { /// types. static FormatAttrKind getFormatAttrKind(StringRef Format) { return llvm::StringSwitch<FormatAttrKind>(Format) - // Check for formats that get handled specially. - .Case("NSString", NSStringFormat) - .Case("CFString", CFStringFormat) - .Case("strftime", StrftimeFormat) + // Check for formats that get handled specially. + .Case("NSString", NSStringFormat) + .Case("CFString", CFStringFormat) + .Case("strftime", StrftimeFormat) - // Otherwise, check for supported formats. - .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat) - .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat) - .Case("kprintf", SupportedFormat) // OpenBSD. - .Case("freebsd_kprintf", SupportedFormat) // FreeBSD. - .Case("os_trace", SupportedFormat) - .Case("os_log", SupportedFormat) + // Otherwise, check for supported formats. + .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat) + .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat) + .Case("kprintf", SupportedFormat) // OpenBSD. + .Case("freebsd_kprintf", SupportedFormat) // FreeBSD. + .Case("os_trace", SupportedFormat) - .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat) - .Default(InvalidFormat); + .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat) + .Default(InvalidFormat); } /// Handle __attribute__((init_priority(priority))) attributes based on Modified: cfe/trunk/test/CodeGen/builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins.c?rev=285007&r1=285006&r2=285007&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/builtins.c (original) +++ cfe/trunk/test/CodeGen/builtins.c Mon Oct 24 14:41:36 2016 @@ -355,6 +355,8 @@ void test_float_builtin_ops(float F, dou } +// __builtin_longjmp isn't supported on all platforms, so only test it on X86. +#ifdef __x86_64__ // CHECK-LABEL: define void @test_builtin_longjmp void test_builtin_longjmp(void **buffer) { // CHECK: [[BITCAST:%.*]] = bitcast @@ -362,147 +364,10 @@ void test_builtin_longjmp(void **buffer) __builtin_longjmp(buffer, 1); // CHECK-NEXT: unreachable } +#endif // CHECK-LABEL: define i64 @test_builtin_readcyclecounter long long test_builtin_readcyclecounter() { // CHECK: call i64 @llvm.readcyclecounter() return __builtin_readcyclecounter(); } - -// CHECK-LABEL: define void @test_builtin_os_log -// CHECK: (i8* [[BUF:%.*]], i32 [[I:%.*]], i8* [[DATA:%.*]]) -void test_builtin_os_log(void *buf, int i, const char *data) { - volatile int len; - // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8 - // CHECK: store i32 [[I]], i32* [[I_ADDR:%.*]], align 4 - // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8 - - // CHECK: store volatile i32 34 - len = __builtin_os_log_format_buffer_size("%d %{public}s %{private}.16P", i, data, data); - - // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]] - // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0 - // CHECK: store i8 3, i8* [[SUMMARY]] - // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1 - // CHECK: store i8 4, i8* [[NUM_ARGS]] - // - // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2 - // CHECK: store i8 0, i8* [[ARG1_DESC]] - // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3 - // CHECK: store i8 4, i8* [[ARG1_SIZE]] - // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4 - // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32* - // CHECK: [[I2:%.*]] = load i32, i32* [[I_ADDR]] - // CHECK: store i32 [[I2]], i32* [[ARG1_INT]] - - // CHECK: [[ARG2_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 8 - // CHECK: store i8 34, i8* [[ARG2_DESC]] - // CHECK: [[ARG2_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 9 - // CHECK: store i8 8, i8* [[ARG2_SIZE]] - // CHECK: [[ARG2:%.*]] = getelementptr i8, i8* [[BUF2]], i64 10 - // CHECK: [[ARG2_PTR:%.*]] = bitcast i8* [[ARG2]] to i8** - // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA_ADDR]] - // CHECK: store i8* [[DATA2]], i8** [[ARG2_PTR]] - - // CHECK: [[ARG3_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 18 - // CHECK: store i8 17, i8* [[ARG3_DESC]] - // CHECK: [[ARG3_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 19 - // CHECK: store i8 4, i8* [[ARG3_SIZE]] - // CHECK: [[ARG3:%.*]] = getelementptr i8, i8* [[BUF2]], i64 20 - // CHECK: [[ARG3_INT:%.*]] = bitcast i8* [[ARG3]] to i32* - // CHECK: store i32 16, i32* [[ARG3_INT]] - - // CHECK: [[ARG4_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 24 - // CHECK: store i8 49, i8* [[ARG4_DESC]] - // CHECK: [[ARG4_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 25 - // CHECK: store i8 8, i8* [[ARG4_SIZE]] - // CHECK: [[ARG4:%.*]] = getelementptr i8, i8* [[BUF2]], i64 26 - // CHECK: [[ARG4_PTR:%.*]] = bitcast i8* [[ARG4]] to i8** - // CHECK: [[DATA3:%.*]] = load i8*, i8** [[DATA_ADDR]] - // CHECK: store i8* [[DATA3]], i8** [[ARG4_PTR]] - - __builtin_os_log_format(buf, "%d %{public}s %{private}.16P", i, data, data); -} - -// CHECK-LABEL: define void @test_builtin_os_log_errno -// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]]) -void test_builtin_os_log_errno(void *buf, const char *data) { - volatile int len; - // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8 - // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8 - - // CHECK: store volatile i32 2 - len = __builtin_os_log_format_buffer_size("%S"); - - // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]] - // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0 - // CHECK: store i8 2, i8* [[SUMMARY]] - // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1 - // CHECK: store i8 1, i8* [[NUM_ARGS]] - - // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2 - // CHECK: store i8 96, i8* [[ARG1_DESC]] - // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3 - // CHECK: store i8 0, i8* [[ARG1_SIZE]] - // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4 - // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32* - // CHECK: store i32 0, i32* [[ARG1_INT]] - - __builtin_os_log_format(buf, "%m"); -} - -// CHECK-LABEL: define void @test_builtin_os_log_wide -// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]], i32* [[STR:%.*]]) -typedef int wchar_t; -void test_builtin_os_log_wide(void *buf, const char *data, wchar_t *str) { - volatile int len; - // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8 - // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8 - // CHECK: store i32* [[STR]], i32** [[STR_ADDR:%.*]], - - // CHECK: store volatile i32 12 - len = __builtin_os_log_format_buffer_size("%S", str); - - // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]] - // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0 - // CHECK: store i8 2, i8* [[SUMMARY]] - // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1 - // CHECK: store i8 1, i8* [[NUM_ARGS]] - - // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2 - // CHECK: store i8 80, i8* [[ARG1_DESC]] - // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3 - // CHECK: store i8 8, i8* [[ARG1_SIZE]] - // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4 - // CHECK: [[ARG1_PTR:%.*]] = bitcast i8* [[ARG1]] to i32** - // CHECK: [[STR2:%.*]] = load i32*, i32** [[STR_ADDR]] - // CHECK: store i32* [[STR2]], i32** [[ARG1_PTR]] - - __builtin_os_log_format(buf, "%S", str); -} - -// CHECK-LABEL: define void @test_builtin_os_log_percent -// Check that the %% which does not consume any argument is correctly handled -void test_builtin_os_log_percent(void *buf, const char *data) { - volatile int len; - // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8 - // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8 - // CHECK: store volatile i32 12 - len = __builtin_os_log_format_buffer_size("%s %%", data); - - // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]] - // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0 - // CHECK: store i8 2, i8* [[SUMMARY]] - // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1 - // CHECK: store i8 1, i8* [[NUM_ARGS]] - // - // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2 - // CHECK: store i8 32, i8* [[ARG1_DESC]] - // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3 - // CHECK: store i8 8, i8* [[ARG1_SIZE]] - // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4 - // CHECK: [[ARG1_PTR:%.*]] = bitcast i8* [[ARG1]] to i8** - // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA_ADDR]] - // CHECK: store i8* [[DATA2]], i8** [[ARG1_PTR]] - __builtin_os_log_format(buf, "%s %%", data); -} Removed: cfe/trunk/test/CodeGenObjC/os_log.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/os_log.m?rev=285006&view=auto ============================================================================== --- cfe/trunk/test/CodeGenObjC/os_log.m (original) +++ cfe/trunk/test/CodeGenObjC/os_log.m (removed) @@ -1,39 +0,0 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc -O2 | FileCheck %s - -// Make sure we emit clang.arc.use before calling objc_release as part of the -// cleanup. This way we make sure the object will not be released until the -// end of the full expression. - -// rdar://problem/24528966 - -@class NSString; -extern __attribute__((visibility("default"))) NSString *GenString(); - -// Behavior of __builtin_os_log differs between platforms, so only test on X86 -#ifdef __x86_64__ -// CHECK-LABEL: define i8* @test_builtin_os_log -void *test_builtin_os_log(void *buf) { - return __builtin_os_log_format(buf, "capabilities: %@", GenString()); - - // CHECK: store i8 2, i8* - // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* {{.*}}, i64 1 - // CHECK: store i8 1, i8* [[NUM_ARGS]] - // - // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* {{.*}}, i64 2 - // CHECK: store i8 64, i8* [[ARG1_DESC]] - // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* {{.*}}, i64 3 - // CHECK: store i8 8, i8* [[ARG1_SIZE]] - // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* {{.*}}, i64 4 - // CHECK: [[ARG1_CAST:%.*]] = bitcast i8* [[ARG1]] to - - // CHECK: [[STRING:%.*]] = {{.*}} call {{.*}} @GenString() - // CHECK: [[STRING_CAST:%.*]] = bitcast {{.*}} [[STRING]] to - // CHECK: call {{.*}} @objc_retainAutoreleasedReturnValue(i8* [[STRING_CAST]]) - // CHECK: store {{.*}} [[STRING]], {{.*}} [[ARG1_CAST]] - - // CHECK: call void (...) @clang.arc.use({{.*}} [[STRING]]) - // CHECK: call void @objc_release(i8* [[STRING_CAST]]) - // CHECK: ret i8* -} - -#endif Removed: cfe/trunk/test/SemaObjC/format-strings-oslog.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/format-strings-oslog.m?rev=285006&view=auto ============================================================================== --- cfe/trunk/test/SemaObjC/format-strings-oslog.m (original) +++ cfe/trunk/test/SemaObjC/format-strings-oslog.m (removed) @@ -1,62 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -#include <stdarg.h> -#include <stddef.h> -#define __need_wint_t -#include <stddef.h> // For wint_t and wchar_t - -int printf(const char *restrict, ...); - -@interface NSString -@end - -void test_os_log_format(const char *pc, int i, void *p, void *buf) { - __builtin_os_log_format(buf, ""); - __builtin_os_log_format(buf, "%d"); // expected-warning {{more '%' conversions than data arguments}} - __builtin_os_log_format(buf, "%d", i); - __builtin_os_log_format(buf, "%P", p); // expected-warning {{using '%P' format specifier without precision}} - __builtin_os_log_format(buf, "%.10P", p); - __builtin_os_log_format(buf, "%.*P", p); // expected-warning {{field precision should have type 'int', but argument has type 'void *'}} - __builtin_os_log_format(buf, "%.*P", i, p); - __builtin_os_log_format(buf, "%.*P", i, i); // expected-warning {{format specifies type 'void *' but the argument has type 'int'}} - __builtin_os_log_format(buf, "%n"); // expected-error {{os_log() '%n' format specifier is not allowed}} - __builtin_os_log_format(buf, pc); // expected-error {{os_log() format argument is not a string constant}} - - printf("%{private}s", pc); // expected-warning {{using 'private' format specifier annotation outside of os_log()/os_trace()}} - __builtin_os_log_format(buf, "%{private}s", pc); - - // <rdar://problem/23835805> - __builtin_os_log_format_buffer_size("no-args"); - __builtin_os_log_format(buf, "%s", "hi"); - - // <rdar://problem/24828090> - wchar_t wc = 'a'; - __builtin_os_log_format(buf, "%C", wc); - printf("%C", wc); - wchar_t wcs[] = {'a', 0}; - __builtin_os_log_format(buf, "%S", wcs); - printf("%S", wcs); -} - -// Test os_log_format primitive with ObjC string literal format argument. -void test_objc(const char *pc, int i, void *p, void *buf, NSString *nss) { - __builtin_os_log_format(buf, @""); - __builtin_os_log_format(buf, @"%d"); // expected-warning {{more '%' conversions than data arguments}} - __builtin_os_log_format(buf, @"%d", i); - __builtin_os_log_format(buf, @"%P", p); // expected-warning {{using '%P' format specifier without precision}} - __builtin_os_log_format(buf, @"%.10P", p); - __builtin_os_log_format(buf, @"%.*P", p); // expected-warning {{field precision should have type 'int', but argument has type 'void *'}} - __builtin_os_log_format(buf, @"%.*P", i, p); - __builtin_os_log_format(buf, @"%.*P", i, i); // expected-warning {{format specifies type 'void *' but the argument has type 'int'}} - - __builtin_os_log_format(buf, @"%{private}s", pc); - __builtin_os_log_format(buf, @"%@", nss); -} - -// Test the os_log format attribute. -void MyOSLog(const char *format, ...) __attribute__((format(os_log, 1, 2))); -void test_attribute(void *p) { - MyOSLog("%s\n", "Hello"); - MyOSLog("%d"); // expected-warning {{more '%' conversions than data arguments}} - MyOSLog("%P", p); // expected-warning {{using '%P' format specifier without precision}} -} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits