<div dir="ltr"><div dir="ltr">Hi,</div><div dir="ltr"><br></div><div dir="ltr">this patch seems to cause a build failure:</div><div dir="ltr"><br><div><div>/usr/bin/ld: CMakeFiles/clangAST.dir/OSLog.cpp.o: in function `(anonymous namespace)::OSLogFormatStringHandler::~OSLogFormatStringHandler()':</div><div>/home/jvesely/llvm/tools/clang/lib/AST/OSLog.cpp:18: undefined reference to `clang::analyze_format_string::FormatStringHandler::~FormatStringHandler()'</div><div>/usr/bin/ld: CMakeFiles/clangAST.dir/OSLog.cpp.o: in function `(anonymous namespace)::OSLogFormatStringHandler::~OSLogFormatStringHandler()':</div><div>/home/jvesely/llvm/tools/clang/lib/AST/OSLog.cpp:18: undefined reference to `clang::analyze_format_string::FormatStringHandler::~FormatStringHandler()'</div><div>/usr/bin/ld: CMakeFiles/clangAST.dir/OSLog.cpp.o: in function `clang::analyze_os_log::computeOSLogBufferLayout(clang::ASTContext&, clang::CallExpr const*, clang::analyze_os_log::OSLogBufferLayout&)':</div><div>/home/jvesely/llvm/tools/clang/lib/AST/OSLog.cpp:198: undefined reference to `clang::analyze_format_string::ParsePrintfString(clang::analyze_format_string::FormatStringHandler&, char const*, char const*, clang::LangOptions const&, clang::TargetInfo const&, bool)'</div><div>/usr/bin/ld: /home/jvesely/llvm/tools/clang/lib/AST/OSLog.cpp:18: undefined reference to `clang::analyze_format_string::FormatStringHandler::~FormatStringHandler()'</div><div>collect2: error: ld returned 1 exit status</div></div><div><br></div><div>thanks,</div><div>Jan</div></div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Nov 1, 2018 at 2:06 PM Tim Northover via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: tnorthover<br>
Date: Thu Nov 1 11:04:49 2018<br>
New Revision: 345866<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=345866&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=345866&view=rev</a><br>
Log:<br>
Reapply Logging: make os_log buffer size an integer constant expression.<br>
<br>
The size of an os_log buffer is known at any stage of compilation, so making it<br>
a constant expression means that the common idiom of declaring a buffer for it<br>
won't result in a VLA. That allows the compiler to skip saving and restoring<br>
the stack pointer around such buffers.<br>
<br>
This also moves the OSLog helpers from libclangAnalysis to libclangAST<br>
to avoid a circular dependency.<br>
<br>
Added:<br>
cfe/trunk/include/clang/AST/OSLog.h<br>
cfe/trunk/lib/AST/OSLog.cpp<br>
Removed:<br>
cfe/trunk/include/clang/Analysis/Analyses/OSLog.h<br>
cfe/trunk/lib/Analysis/OSLog.cpp<br>
Modified:<br>
cfe/trunk/lib/AST/CMakeLists.txt<br>
cfe/trunk/lib/AST/ExprConstant.cpp<br>
cfe/trunk/lib/Analysis/CMakeLists.txt<br>
cfe/trunk/lib/Analysis/PrintfFormatString.cpp<br>
cfe/trunk/lib/CodeGen/CGBuiltin.cpp<br>
cfe/trunk/test/CodeGen/builtins.c<br>
<br>
Added: cfe/trunk/include/clang/AST/OSLog.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OSLog.h?rev=345866&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OSLog.h?rev=345866&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/OSLog.h (added)<br>
+++ cfe/trunk/include/clang/AST/OSLog.h Thu Nov 1 11:04:49 2018<br>
@@ -0,0 +1,155 @@<br>
+//= OSLog.h - Analysis of calls to os_log builtins --*- C++ -*-===============//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file defines APIs for determining the layout of the data buffer for<br>
+// os_log() and os_trace().<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H<br>
+#define LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H<br>
+<br>
+#include "clang/AST/ASTContext.h"<br>
+#include "clang/AST/Expr.h"<br>
+<br>
+namespace clang {<br>
+namespace analyze_os_log {<br>
+<br>
+/// An OSLogBufferItem represents a single item in the data written by a call<br>
+/// to os_log() or os_trace().<br>
+class OSLogBufferItem {<br>
+public:<br>
+ enum Kind {<br>
+ // The item is a scalar (int, float, raw pointer, etc.). No further copying<br>
+ // is required. This is the only kind allowed by os_trace().<br>
+ ScalarKind = 0,<br>
+<br>
+ // The item is a count, which describes the length of the following item to<br>
+ // be copied. A count may only be followed by an item of kind StringKind,<br>
+ // WideStringKind, or PointerKind.<br>
+ CountKind,<br>
+<br>
+ // The item is a pointer to a C string. If preceded by a count 'n',<br>
+ // os_log() will copy at most 'n' bytes from the pointer.<br>
+ StringKind,<br>
+<br>
+ // The item is a pointer to a block of raw data. This item must be preceded<br>
+ // by a count 'n'. os_log() will copy exactly 'n' bytes from the pointer.<br>
+ PointerKind,<br>
+<br>
+ // The item is a pointer to an Objective-C object. os_log() may retain the<br>
+ // object for later processing.<br>
+ ObjCObjKind,<br>
+<br>
+ // The item is a pointer to wide-char string.<br>
+ WideStringKind,<br>
+<br>
+ // The item is corresponding to the '%m' format specifier, no value is<br>
+ // populated in the buffer and the runtime is loading the errno value.<br>
+ ErrnoKind<br>
+ };<br>
+<br>
+ enum {<br>
+ // The item is marked "private" in the format string.<br>
+ IsPrivate = 0x1,<br>
+<br>
+ // The item is marked "public" in the format string.<br>
+ IsPublic = 0x2<br>
+ };<br>
+<br>
+private:<br>
+ Kind TheKind = ScalarKind;<br>
+ const Expr *TheExpr = nullptr;<br>
+ CharUnits ConstValue;<br>
+ CharUnits Size; // size of the data, not including the header bytes<br>
+ unsigned Flags = 0;<br>
+<br>
+public:<br>
+ OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags)<br>
+ : TheKind(kind), TheExpr(expr), Size(size), Flags(flags) {}<br>
+<br>
+ OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags)<br>
+ : TheKind(CountKind), ConstValue(value),<br>
+ Size(Ctx.getTypeSizeInChars(Ctx.IntTy)), Flags(flags) {}<br>
+<br>
+ unsigned char getDescriptorByte() const {<br>
+ unsigned char result = 0;<br>
+ if (getIsPrivate())<br>
+ result |= IsPrivate;<br>
+ if (getIsPublic())<br>
+ result |= IsPublic;<br>
+ result |= ((unsigned)getKind()) << 4;<br>
+ return result;<br>
+ }<br>
+<br>
+ unsigned char getSizeByte() const { return size().getQuantity(); }<br>
+<br>
+ Kind getKind() const { return TheKind; }<br>
+ bool getIsPrivate() const { return (Flags & IsPrivate) != 0; }<br>
+ bool getIsPublic() const { return (Flags & IsPublic) != 0; }<br>
+<br>
+ const Expr *getExpr() const { return TheExpr; }<br>
+ CharUnits getConstValue() const { return ConstValue; }<br>
+ CharUnits size() const { return Size; }<br>
+};<br>
+<br>
+class OSLogBufferLayout {<br>
+public:<br>
+ SmallVector<OSLogBufferItem, 4> Items;<br>
+<br>
+ enum Flags { HasPrivateItems = 1, HasNonScalarItems = 1 << 1 };<br>
+<br>
+ CharUnits size() const {<br>
+ CharUnits result;<br>
+ result += CharUnits::fromQuantity(2); // summary byte, num-args byte<br>
+ for (auto &item : Items) {<br>
+ // descriptor byte, size byte<br>
+ result += item.size() + CharUnits::fromQuantity(2);<br>
+ }<br>
+ return result;<br>
+ }<br>
+<br>
+ bool hasPrivateItems() const {<br>
+ return llvm::any_of(<br>
+ Items, [](const OSLogBufferItem &Item) { return Item.getIsPrivate(); });<br>
+ }<br>
+<br>
+ bool hasPublicItems() const {<br>
+ return llvm::any_of(<br>
+ Items, [](const OSLogBufferItem &Item) { return Item.getIsPublic(); });<br>
+ }<br>
+<br>
+ bool hasNonScalar() const {<br>
+ return llvm::any_of(Items, [](const OSLogBufferItem &Item) {<br>
+ return Item.getKind() != OSLogBufferItem::ScalarKind;<br>
+ });<br>
+ }<br>
+<br>
+ unsigned char getSummaryByte() const {<br>
+ unsigned char result = 0;<br>
+ if (hasPrivateItems())<br>
+ result |= HasPrivateItems;<br>
+ if (hasNonScalar())<br>
+ result |= HasNonScalarItems;<br>
+ return result;<br>
+ }<br>
+<br>
+ unsigned char getNumArgsByte() const { return Items.size(); }<br>
+};<br>
+<br>
+// Given a call 'E' to one of the builtins __builtin_os_log_format() or<br>
+// __builtin_os_log_format_buffer_size(), compute the layout of the buffer that<br>
+// the call will write into and store it in 'layout'. Returns 'false' if there<br>
+// was some error encountered while computing the layout, and 'true' otherwise.<br>
+bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E,<br>
+ OSLogBufferLayout &layout);<br>
+<br>
+} // namespace analyze_os_log<br>
+} // namespace clang<br>
+#endif<br>
<br>
Removed: cfe/trunk/include/clang/Analysis/Analyses/OSLog.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/OSLog.h?rev=345865&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/OSLog.h?rev=345865&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Analysis/Analyses/OSLog.h (original)<br>
+++ cfe/trunk/include/clang/Analysis/Analyses/OSLog.h (removed)<br>
@@ -1,155 +0,0 @@<br>
-//= OSLog.h - Analysis of calls to os_log builtins --*- C++ -*-===============//<br>
-//<br>
-// The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-// This file defines APIs for determining the layout of the data buffer for<br>
-// os_log() and os_trace().<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H<br>
-#define LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H<br>
-<br>
-#include "clang/AST/ASTContext.h"<br>
-#include "clang/AST/Expr.h"<br>
-<br>
-namespace clang {<br>
-namespace analyze_os_log {<br>
-<br>
-/// An OSLogBufferItem represents a single item in the data written by a call<br>
-/// to os_log() or os_trace().<br>
-class OSLogBufferItem {<br>
-public:<br>
- enum Kind {<br>
- // The item is a scalar (int, float, raw pointer, etc.). No further copying<br>
- // is required. This is the only kind allowed by os_trace().<br>
- ScalarKind = 0,<br>
-<br>
- // The item is a count, which describes the length of the following item to<br>
- // be copied. A count may only be followed by an item of kind StringKind,<br>
- // WideStringKind, or PointerKind.<br>
- CountKind,<br>
-<br>
- // The item is a pointer to a C string. If preceded by a count 'n',<br>
- // os_log() will copy at most 'n' bytes from the pointer.<br>
- StringKind,<br>
-<br>
- // The item is a pointer to a block of raw data. This item must be preceded<br>
- // by a count 'n'. os_log() will copy exactly 'n' bytes from the pointer.<br>
- PointerKind,<br>
-<br>
- // The item is a pointer to an Objective-C object. os_log() may retain the<br>
- // object for later processing.<br>
- ObjCObjKind,<br>
-<br>
- // The item is a pointer to wide-char string.<br>
- WideStringKind,<br>
-<br>
- // The item is corresponding to the '%m' format specifier, no value is<br>
- // populated in the buffer and the runtime is loading the errno value.<br>
- ErrnoKind<br>
- };<br>
-<br>
- enum {<br>
- // The item is marked "private" in the format string.<br>
- IsPrivate = 0x1,<br>
-<br>
- // The item is marked "public" in the format string.<br>
- IsPublic = 0x2<br>
- };<br>
-<br>
-private:<br>
- Kind TheKind = ScalarKind;<br>
- const Expr *TheExpr = nullptr;<br>
- CharUnits ConstValue;<br>
- CharUnits Size; // size of the data, not including the header bytes<br>
- unsigned Flags = 0;<br>
-<br>
-public:<br>
- OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags)<br>
- : TheKind(kind), TheExpr(expr), Size(size), Flags(flags) {}<br>
-<br>
- OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags)<br>
- : TheKind(CountKind), ConstValue(value),<br>
- Size(Ctx.getTypeSizeInChars(Ctx.IntTy)), Flags(flags) {}<br>
-<br>
- unsigned char getDescriptorByte() const {<br>
- unsigned char result = 0;<br>
- if (getIsPrivate())<br>
- result |= IsPrivate;<br>
- if (getIsPublic())<br>
- result |= IsPublic;<br>
- result |= ((unsigned)getKind()) << 4;<br>
- return result;<br>
- }<br>
-<br>
- unsigned char getSizeByte() const { return size().getQuantity(); }<br>
-<br>
- Kind getKind() const { return TheKind; }<br>
- bool getIsPrivate() const { return (Flags & IsPrivate) != 0; }<br>
- bool getIsPublic() const { return (Flags & IsPublic) != 0; }<br>
-<br>
- const Expr *getExpr() const { return TheExpr; }<br>
- CharUnits getConstValue() const { return ConstValue; }<br>
- CharUnits size() const { return Size; }<br>
-};<br>
-<br>
-class OSLogBufferLayout {<br>
-public:<br>
- SmallVector<OSLogBufferItem, 4> Items;<br>
-<br>
- enum Flags { HasPrivateItems = 1, HasNonScalarItems = 1 << 1 };<br>
-<br>
- CharUnits size() const {<br>
- CharUnits result;<br>
- result += CharUnits::fromQuantity(2); // summary byte, num-args byte<br>
- for (auto &item : Items) {<br>
- // descriptor byte, size byte<br>
- result += item.size() + CharUnits::fromQuantity(2);<br>
- }<br>
- return result;<br>
- }<br>
-<br>
- bool hasPrivateItems() const {<br>
- return llvm::any_of(<br>
- Items, [](const OSLogBufferItem &Item) { return Item.getIsPrivate(); });<br>
- }<br>
-<br>
- bool hasPublicItems() const {<br>
- return llvm::any_of(<br>
- Items, [](const OSLogBufferItem &Item) { return Item.getIsPublic(); });<br>
- }<br>
-<br>
- bool hasNonScalar() const {<br>
- return llvm::any_of(Items, [](const OSLogBufferItem &Item) {<br>
- return Item.getKind() != OSLogBufferItem::ScalarKind;<br>
- });<br>
- }<br>
-<br>
- unsigned char getSummaryByte() const {<br>
- unsigned char result = 0;<br>
- if (hasPrivateItems())<br>
- result |= HasPrivateItems;<br>
- if (hasNonScalar())<br>
- result |= HasNonScalarItems;<br>
- return result;<br>
- }<br>
-<br>
- unsigned char getNumArgsByte() const { return Items.size(); }<br>
-};<br>
-<br>
-// Given a call 'E' to one of the builtins __builtin_os_log_format() or<br>
-// __builtin_os_log_format_buffer_size(), compute the layout of the buffer that<br>
-// the call will write into and store it in 'layout'. Returns 'false' if there<br>
-// was some error encountered while computing the layout, and 'true' otherwise.<br>
-bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E,<br>
- OSLogBufferLayout &layout);<br>
-<br>
-} // namespace analyze_os_log<br>
-} // namespace clang<br>
-#endif<br>
<br>
Modified: cfe/trunk/lib/AST/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CMakeLists.txt?rev=345866&r1=345865&r2=345866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CMakeLists.txt?rev=345866&r1=345865&r2=345866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/CMakeLists.txt (original)<br>
+++ cfe/trunk/lib/AST/CMakeLists.txt Thu Nov 1 11:04:49 2018<br>
@@ -48,6 +48,7 @@ add_clang_library(clangAST<br>
NestedNameSpecifier.cpp<br>
NSAPI.cpp<br>
ODRHash.cpp<br>
+ OSLog.cpp<br>
OpenMPClause.cpp<br>
ParentMap.cpp<br>
QualTypeNames.cpp<br>
<br>
Modified: cfe/trunk/lib/AST/ExprConstant.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=345866&r1=345865&r2=345866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=345866&r1=345865&r2=345866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)<br>
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Nov 1 11:04:49 2018<br>
@@ -39,6 +39,7 @@<br>
#include "clang/AST/ASTLambda.h"<br>
#include "clang/AST/CharUnits.h"<br>
#include "clang/AST/Expr.h"<br>
+#include "clang/AST/OSLog.h"<br>
#include "clang/AST/RecordLayout.h"<br>
#include "clang/AST/StmtVisitor.h"<br>
#include "clang/AST/TypeLoc.h"<br>
@@ -8126,6 +8127,12 @@ bool IntExprEvaluator::VisitBuiltinCallE<br>
llvm_unreachable("unexpected EvalMode");<br>
}<br>
<br>
+ case Builtin::BI__builtin_os_log_format_buffer_size: {<br>
+ analyze_os_log::OSLogBufferLayout Layout;<br>
+ analyze_os_log::computeOSLogBufferLayout(Info.Ctx, E, Layout);<br>
+ return Success(Layout.size().getQuantity(), E);<br>
+ }<br>
+<br>
case Builtin::BI__builtin_bswap16:<br>
case Builtin::BI__builtin_bswap32:<br>
case Builtin::BI__builtin_bswap64: {<br>
<br>
Added: cfe/trunk/lib/AST/OSLog.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/OSLog.cpp?rev=345866&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/OSLog.cpp?rev=345866&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/OSLog.cpp (added)<br>
+++ cfe/trunk/lib/AST/OSLog.cpp Thu Nov 1 11:04:49 2018<br>
@@ -0,0 +1,203 @@<br>
+// TODO: header template<br>
+<br>
+#include "clang/AST/OSLog.h"<br>
+#include "clang/AST/Attr.h"<br>
+#include "clang/AST/Decl.h"<br>
+#include "clang/AST/DeclCXX.h"<br>
+#include "clang/AST/ExprObjC.h"<br>
+#include "clang/Analysis/Analyses/FormatString.h"<br>
+#include "clang/Basic/Builtins.h"<br>
+#include "llvm/ADT/SmallBitVector.h"<br>
+<br>
+using namespace clang;<br>
+<br>
+using clang::analyze_os_log::OSLogBufferItem;<br>
+using clang::analyze_os_log::OSLogBufferLayout;<br>
+<br>
+namespace {<br>
+class OSLogFormatStringHandler<br>
+ : public analyze_format_string::FormatStringHandler {<br>
+private:<br>
+ struct ArgData {<br>
+ const Expr *E = nullptr;<br>
+ Optional<OSLogBufferItem::Kind> Kind;<br>
+ Optional<unsigned> Size;<br>
+ Optional<const Expr *> Count;<br>
+ Optional<const Expr *> Precision;<br>
+ Optional<const Expr *> FieldWidth;<br>
+ unsigned char Flags = 0;<br>
+ };<br>
+ SmallVector<ArgData, 4> ArgsData;<br>
+ ArrayRef<const Expr *> Args;<br>
+<br>
+ OSLogBufferItem::Kind<br>
+ getKind(analyze_format_string::ConversionSpecifier::Kind K) {<br>
+ switch (K) {<br>
+ case clang::analyze_format_string::ConversionSpecifier::sArg: // "%s"<br>
+ return OSLogBufferItem::StringKind;<br>
+ case clang::analyze_format_string::ConversionSpecifier::SArg: // "%S"<br>
+ return OSLogBufferItem::WideStringKind;<br>
+ case clang::analyze_format_string::ConversionSpecifier::PArg: { // "%P"<br>
+ return OSLogBufferItem::PointerKind;<br>
+ case clang::analyze_format_string::ConversionSpecifier::ObjCObjArg: // "%@"<br>
+ return OSLogBufferItem::ObjCObjKind;<br>
+ case clang::analyze_format_string::ConversionSpecifier::PrintErrno: // "%m"<br>
+ return OSLogBufferItem::ErrnoKind;<br>
+ default:<br>
+ return OSLogBufferItem::ScalarKind;<br>
+ }<br>
+ }<br>
+ }<br>
+<br>
+public:<br>
+ OSLogFormatStringHandler(ArrayRef<const Expr *> Args) : Args(Args) {<br>
+ ArgsData.reserve(Args.size());<br>
+ }<br>
+<br>
+ virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,<br>
+ const char *StartSpecifier,<br>
+ unsigned SpecifierLen) {<br>
+ if (!FS.consumesDataArgument() &&<br>
+ FS.getConversionSpecifier().getKind() !=<br>
+ clang::analyze_format_string::ConversionSpecifier::PrintErrno)<br>
+ return true;<br>
+<br>
+ ArgsData.emplace_back();<br>
+ unsigned ArgIndex = FS.getArgIndex();<br>
+ if (ArgIndex < Args.size())<br>
+ ArgsData.back().E = Args[ArgIndex];<br>
+<br>
+ // First get the Kind<br>
+ ArgsData.back().Kind = getKind(FS.getConversionSpecifier().getKind());<br>
+ if (ArgsData.back().Kind != OSLogBufferItem::ErrnoKind &&<br>
+ !ArgsData.back().E) {<br>
+ // missing argument<br>
+ ArgsData.pop_back();<br>
+ return false;<br>
+ }<br>
+<br>
+ switch (FS.getConversionSpecifier().getKind()) {<br>
+ case clang::analyze_format_string::ConversionSpecifier::sArg: // "%s"<br>
+ case clang::analyze_format_string::ConversionSpecifier::SArg: { // "%S"<br>
+ auto &precision = FS.getPrecision();<br>
+ switch (precision.getHowSpecified()) {<br>
+ case clang::analyze_format_string::OptionalAmount::NotSpecified: // "%s"<br>
+ break;<br>
+ case clang::analyze_format_string::OptionalAmount::Constant: // "%.16s"<br>
+ ArgsData.back().Size = precision.getConstantAmount();<br>
+ break;<br>
+ case clang::analyze_format_string::OptionalAmount::Arg: // "%.*s"<br>
+ ArgsData.back().Count = Args[precision.getArgIndex()];<br>
+ break;<br>
+ case clang::analyze_format_string::OptionalAmount::Invalid:<br>
+ return false;<br>
+ }<br>
+ break;<br>
+ }<br>
+ case clang::analyze_format_string::ConversionSpecifier::PArg: { // "%P"<br>
+ auto &precision = FS.getPrecision();<br>
+ switch (precision.getHowSpecified()) {<br>
+ case clang::analyze_format_string::OptionalAmount::NotSpecified: // "%P"<br>
+ return false; // length must be supplied with pointer format specifier<br>
+ case clang::analyze_format_string::OptionalAmount::Constant: // "%.16P"<br>
+ ArgsData.back().Size = precision.getConstantAmount();<br>
+ break;<br>
+ case clang::analyze_format_string::OptionalAmount::Arg: // "%.*P"<br>
+ ArgsData.back().Count = Args[precision.getArgIndex()];<br>
+ break;<br>
+ case clang::analyze_format_string::OptionalAmount::Invalid:<br>
+ return false;<br>
+ }<br>
+ break;<br>
+ }<br>
+ default:<br>
+ if (FS.getPrecision().hasDataArgument()) {<br>
+ ArgsData.back().Precision = Args[FS.getPrecision().getArgIndex()];<br>
+ }<br>
+ break;<br>
+ }<br>
+ if (FS.getFieldWidth().hasDataArgument()) {<br>
+ ArgsData.back().FieldWidth = Args[FS.getFieldWidth().getArgIndex()];<br>
+ }<br>
+<br>
+ if (FS.isPrivate()) {<br>
+ ArgsData.back().Flags |= OSLogBufferItem::IsPrivate;<br>
+ }<br>
+ if (FS.isPublic()) {<br>
+ ArgsData.back().Flags |= OSLogBufferItem::IsPublic;<br>
+ }<br>
+ return true;<br>
+ }<br>
+<br>
+ void computeLayout(ASTContext &Ctx, OSLogBufferLayout &Layout) const {<br>
+ Layout.Items.clear();<br>
+ for (auto &Data : ArgsData) {<br>
+ if (Data.FieldWidth) {<br>
+ CharUnits Size = Ctx.getTypeSizeInChars((*Data.FieldWidth)->getType());<br>
+ Layout.Items.emplace_back(OSLogBufferItem::ScalarKind, *Data.FieldWidth,<br>
+ Size, 0);<br>
+ }<br>
+ if (Data.Precision) {<br>
+ CharUnits Size = Ctx.getTypeSizeInChars((*Data.Precision)->getType());<br>
+ Layout.Items.emplace_back(OSLogBufferItem::ScalarKind, *Data.Precision,<br>
+ Size, 0);<br>
+ }<br>
+ if (Data.Count) {<br>
+ // "%.*P" has an extra "count" that we insert before the argument.<br>
+ CharUnits Size = Ctx.getTypeSizeInChars((*Data.Count)->getType());<br>
+ Layout.Items.emplace_back(OSLogBufferItem::CountKind, *Data.Count, Size,<br>
+ 0);<br>
+ }<br>
+ if (Data.Size)<br>
+ Layout.Items.emplace_back(Ctx, CharUnits::fromQuantity(*Data.Size),<br>
+ Data.Flags);<br>
+ if (Data.Kind) {<br>
+ CharUnits Size;<br>
+ if (*Data.Kind == OSLogBufferItem::ErrnoKind)<br>
+ Size = CharUnits::Zero();<br>
+ else<br>
+ Size = Ctx.getTypeSizeInChars(Data.E->getType());<br>
+ Layout.Items.emplace_back(*Data.Kind, Data.E, Size, Data.Flags);<br>
+ } else {<br>
+ auto Size = Ctx.getTypeSizeInChars(Data.E->getType());<br>
+ Layout.Items.emplace_back(OSLogBufferItem::ScalarKind, Data.E, Size,<br>
+ Data.Flags);<br>
+ }<br>
+ }<br>
+ }<br>
+};<br>
+} // end anonymous namespace<br>
+<br>
+bool clang::analyze_os_log::computeOSLogBufferLayout(<br>
+ ASTContext &Ctx, const CallExpr *E, OSLogBufferLayout &Layout) {<br>
+ ArrayRef<const Expr *> Args(E->getArgs(), E->getArgs() + E->getNumArgs());<br>
+<br>
+ const Expr *StringArg;<br>
+ ArrayRef<const Expr *> VarArgs;<br>
+ switch (E->getBuiltinCallee()) {<br>
+ case Builtin::BI__builtin_os_log_format_buffer_size:<br>
+ assert(E->getNumArgs() >= 1 &&<br>
+ "__builtin_os_log_format_buffer_size takes at least 1 argument");<br>
+ StringArg = E->getArg(0);<br>
+ VarArgs = Args.slice(1);<br>
+ break;<br>
+ case Builtin::BI__builtin_os_log_format:<br>
+ assert(E->getNumArgs() >= 2 &&<br>
+ "__builtin_os_log_format takes at least 2 arguments");<br>
+ StringArg = E->getArg(1);<br>
+ VarArgs = Args.slice(2);<br>
+ break;<br>
+ default:<br>
+ llvm_unreachable("non-os_log builtin passed to computeOSLogBufferLayout");<br>
+ }<br>
+<br>
+ const StringLiteral *Lit = cast<StringLiteral>(StringArg->IgnoreParenCasts());<br>
+ assert(Lit && (Lit->isAscii() || Lit->isUTF8()));<br>
+ StringRef Data = Lit->getString();<br>
+ OSLogFormatStringHandler H(VarArgs);<br>
+ ParsePrintfString(H, Data.begin(), Data.end(), Ctx.getLangOpts(),<br>
+ Ctx.getTargetInfo(), /*isFreeBSDKPrintf*/ false);<br>
+<br>
+ H.computeLayout(Ctx, Layout);<br>
+ return true;<br>
+}<br>
<br>
Modified: cfe/trunk/lib/Analysis/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=345866&r1=345865&r2=345866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=345866&r1=345865&r2=345866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Analysis/CMakeLists.txt (original)<br>
+++ cfe/trunk/lib/Analysis/CMakeLists.txt Thu Nov 1 11:04:49 2018<br>
@@ -18,7 +18,6 @@ add_clang_library(clangAnalysis<br>
ExprMutationAnalyzer.cpp<br>
FormatString.cpp<br>
LiveVariables.cpp<br>
- OSLog.cpp<br>
ObjCNoReturn.cpp<br>
PostOrderCFGView.cpp<br>
PrintfFormatString.cpp<br>
<br>
Removed: cfe/trunk/lib/Analysis/OSLog.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/OSLog.cpp?rev=345865&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/OSLog.cpp?rev=345865&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Analysis/OSLog.cpp (original)<br>
+++ cfe/trunk/lib/Analysis/OSLog.cpp (removed)<br>
@@ -1,203 +0,0 @@<br>
-// TODO: header template<br>
-<br>
-#include "clang/Analysis/Analyses/OSLog.h"<br>
-#include "clang/AST/Attr.h"<br>
-#include "clang/AST/Decl.h"<br>
-#include "clang/AST/DeclCXX.h"<br>
-#include "clang/AST/ExprObjC.h"<br>
-#include "clang/Analysis/Analyses/FormatString.h"<br>
-#include "clang/Basic/Builtins.h"<br>
-#include "llvm/ADT/SmallBitVector.h"<br>
-<br>
-using namespace clang;<br>
-<br>
-using clang::analyze_os_log::OSLogBufferItem;<br>
-using clang::analyze_os_log::OSLogBufferLayout;<br>
-<br>
-namespace {<br>
-class OSLogFormatStringHandler<br>
- : public analyze_format_string::FormatStringHandler {<br>
-private:<br>
- struct ArgData {<br>
- const Expr *E = nullptr;<br>
- Optional<OSLogBufferItem::Kind> Kind;<br>
- Optional<unsigned> Size;<br>
- Optional<const Expr *> Count;<br>
- Optional<const Expr *> Precision;<br>
- Optional<const Expr *> FieldWidth;<br>
- unsigned char Flags = 0;<br>
- };<br>
- SmallVector<ArgData, 4> ArgsData;<br>
- ArrayRef<const Expr *> Args;<br>
-<br>
- OSLogBufferItem::Kind<br>
- getKind(analyze_format_string::ConversionSpecifier::Kind K) {<br>
- switch (K) {<br>
- case clang::analyze_format_string::ConversionSpecifier::sArg: // "%s"<br>
- return OSLogBufferItem::StringKind;<br>
- case clang::analyze_format_string::ConversionSpecifier::SArg: // "%S"<br>
- return OSLogBufferItem::WideStringKind;<br>
- case clang::analyze_format_string::ConversionSpecifier::PArg: { // "%P"<br>
- return OSLogBufferItem::PointerKind;<br>
- case clang::analyze_format_string::ConversionSpecifier::ObjCObjArg: // "%@"<br>
- return OSLogBufferItem::ObjCObjKind;<br>
- case clang::analyze_format_string::ConversionSpecifier::PrintErrno: // "%m"<br>
- return OSLogBufferItem::ErrnoKind;<br>
- default:<br>
- return OSLogBufferItem::ScalarKind;<br>
- }<br>
- }<br>
- }<br>
-<br>
-public:<br>
- OSLogFormatStringHandler(ArrayRef<const Expr *> Args) : Args(Args) {<br>
- ArgsData.reserve(Args.size());<br>
- }<br>
-<br>
- virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,<br>
- const char *StartSpecifier,<br>
- unsigned SpecifierLen) {<br>
- if (!FS.consumesDataArgument() &&<br>
- FS.getConversionSpecifier().getKind() !=<br>
- clang::analyze_format_string::ConversionSpecifier::PrintErrno)<br>
- return true;<br>
-<br>
- ArgsData.emplace_back();<br>
- unsigned ArgIndex = FS.getArgIndex();<br>
- if (ArgIndex < Args.size())<br>
- ArgsData.back().E = Args[ArgIndex];<br>
-<br>
- // First get the Kind<br>
- ArgsData.back().Kind = getKind(FS.getConversionSpecifier().getKind());<br>
- if (ArgsData.back().Kind != OSLogBufferItem::ErrnoKind &&<br>
- !ArgsData.back().E) {<br>
- // missing argument<br>
- ArgsData.pop_back();<br>
- return false;<br>
- }<br>
-<br>
- switch (FS.getConversionSpecifier().getKind()) {<br>
- case clang::analyze_format_string::ConversionSpecifier::sArg: // "%s"<br>
- case clang::analyze_format_string::ConversionSpecifier::SArg: { // "%S"<br>
- auto &precision = FS.getPrecision();<br>
- switch (precision.getHowSpecified()) {<br>
- case clang::analyze_format_string::OptionalAmount::NotSpecified: // "%s"<br>
- break;<br>
- case clang::analyze_format_string::OptionalAmount::Constant: // "%.16s"<br>
- ArgsData.back().Size = precision.getConstantAmount();<br>
- break;<br>
- case clang::analyze_format_string::OptionalAmount::Arg: // "%.*s"<br>
- ArgsData.back().Count = Args[precision.getArgIndex()];<br>
- break;<br>
- case clang::analyze_format_string::OptionalAmount::Invalid:<br>
- return false;<br>
- }<br>
- break;<br>
- }<br>
- case clang::analyze_format_string::ConversionSpecifier::PArg: { // "%P"<br>
- auto &precision = FS.getPrecision();<br>
- switch (precision.getHowSpecified()) {<br>
- case clang::analyze_format_string::OptionalAmount::NotSpecified: // "%P"<br>
- return false; // length must be supplied with pointer format specifier<br>
- case clang::analyze_format_string::OptionalAmount::Constant: // "%.16P"<br>
- ArgsData.back().Size = precision.getConstantAmount();<br>
- break;<br>
- case clang::analyze_format_string::OptionalAmount::Arg: // "%.*P"<br>
- ArgsData.back().Count = Args[precision.getArgIndex()];<br>
- break;<br>
- case clang::analyze_format_string::OptionalAmount::Invalid:<br>
- return false;<br>
- }<br>
- break;<br>
- }<br>
- default:<br>
- if (FS.getPrecision().hasDataArgument()) {<br>
- ArgsData.back().Precision = Args[FS.getPrecision().getArgIndex()];<br>
- }<br>
- break;<br>
- }<br>
- if (FS.getFieldWidth().hasDataArgument()) {<br>
- ArgsData.back().FieldWidth = Args[FS.getFieldWidth().getArgIndex()];<br>
- }<br>
-<br>
- if (FS.isPrivate()) {<br>
- ArgsData.back().Flags |= OSLogBufferItem::IsPrivate;<br>
- }<br>
- if (FS.isPublic()) {<br>
- ArgsData.back().Flags |= OSLogBufferItem::IsPublic;<br>
- }<br>
- return true;<br>
- }<br>
-<br>
- void computeLayout(ASTContext &Ctx, OSLogBufferLayout &Layout) const {<br>
- Layout.Items.clear();<br>
- for (auto &Data : ArgsData) {<br>
- if (Data.FieldWidth) {<br>
- CharUnits Size = Ctx.getTypeSizeInChars((*Data.FieldWidth)->getType());<br>
- Layout.Items.emplace_back(OSLogBufferItem::ScalarKind, *Data.FieldWidth,<br>
- Size, 0);<br>
- }<br>
- if (Data.Precision) {<br>
- CharUnits Size = Ctx.getTypeSizeInChars((*Data.Precision)->getType());<br>
- Layout.Items.emplace_back(OSLogBufferItem::ScalarKind, *Data.Precision,<br>
- Size, 0);<br>
- }<br>
- if (Data.Count) {<br>
- // "%.*P" has an extra "count" that we insert before the argument.<br>
- CharUnits Size = Ctx.getTypeSizeInChars((*Data.Count)->getType());<br>
- Layout.Items.emplace_back(OSLogBufferItem::CountKind, *Data.Count, Size,<br>
- 0);<br>
- }<br>
- if (Data.Size)<br>
- Layout.Items.emplace_back(Ctx, CharUnits::fromQuantity(*Data.Size),<br>
- Data.Flags);<br>
- if (Data.Kind) {<br>
- CharUnits Size;<br>
- if (*Data.Kind == OSLogBufferItem::ErrnoKind)<br>
- Size = CharUnits::Zero();<br>
- else<br>
- Size = Ctx.getTypeSizeInChars(Data.E->getType());<br>
- Layout.Items.emplace_back(*Data.Kind, Data.E, Size, Data.Flags);<br>
- } else {<br>
- auto Size = Ctx.getTypeSizeInChars(Data.E->getType());<br>
- Layout.Items.emplace_back(OSLogBufferItem::ScalarKind, Data.E, Size,<br>
- Data.Flags);<br>
- }<br>
- }<br>
- }<br>
-};<br>
-} // end anonymous namespace<br>
-<br>
-bool clang::analyze_os_log::computeOSLogBufferLayout(<br>
- ASTContext &Ctx, const CallExpr *E, OSLogBufferLayout &Layout) {<br>
- ArrayRef<const Expr *> Args(E->getArgs(), E->getArgs() + E->getNumArgs());<br>
-<br>
- const Expr *StringArg;<br>
- ArrayRef<const Expr *> VarArgs;<br>
- switch (E->getBuiltinCallee()) {<br>
- case Builtin::BI__builtin_os_log_format_buffer_size:<br>
- assert(E->getNumArgs() >= 1 &&<br>
- "__builtin_os_log_format_buffer_size takes at least 1 argument");<br>
- StringArg = E->getArg(0);<br>
- VarArgs = Args.slice(1);<br>
- break;<br>
- case Builtin::BI__builtin_os_log_format:<br>
- assert(E->getNumArgs() >= 2 &&<br>
- "__builtin_os_log_format takes at least 2 arguments");<br>
- StringArg = E->getArg(1);<br>
- VarArgs = Args.slice(2);<br>
- break;<br>
- default:<br>
- llvm_unreachable("non-os_log builtin passed to computeOSLogBufferLayout");<br>
- }<br>
-<br>
- const StringLiteral *Lit = cast<StringLiteral>(StringArg->IgnoreParenCasts());<br>
- assert(Lit && (Lit->isAscii() || Lit->isUTF8()));<br>
- StringRef Data = Lit->getString();<br>
- OSLogFormatStringHandler H(VarArgs);<br>
- ParsePrintfString(H, Data.begin(), Data.end(), Ctx.getLangOpts(),<br>
- Ctx.getTargetInfo(), /*isFreeBSDKPrintf*/ false);<br>
-<br>
- H.computeLayout(Ctx, Layout);<br>
- return true;<br>
-}<br>
<br>
Modified: cfe/trunk/lib/Analysis/PrintfFormatString.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp?rev=345866&r1=345865&r2=345866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp?rev=345866&r1=345865&r2=345866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Analysis/PrintfFormatString.cpp (original)<br>
+++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp Thu Nov 1 11:04:49 2018<br>
@@ -13,7 +13,7 @@<br>
//===----------------------------------------------------------------------===//<br>
<br>
#include "clang/Analysis/Analyses/FormatString.h"<br>
-#include "clang/Analysis/Analyses/OSLog.h"<br>
+#include "clang/AST/OSLog.h"<br>
#include "FormatStringParsing.h"<br>
#include "clang/Basic/TargetInfo.h"<br>
<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=345866&r1=345865&r2=345866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=345866&r1=345865&r2=345866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Thu Nov 1 11:04:49 2018<br>
@@ -21,7 +21,7 @@<br>
#include "TargetInfo.h"<br>
#include "clang/AST/ASTContext.h"<br>
#include "clang/AST/Decl.h"<br>
-#include "clang/Analysis/Analyses/OSLog.h"<br>
+#include "clang/AST/OSLog.h"<br>
#include "clang/Basic/TargetBuiltins.h"<br>
#include "clang/Basic/TargetInfo.h"<br>
#include "clang/CodeGen/CGFunctionInfo.h"<br>
@@ -3609,13 +3609,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(<br>
case Builtin::BI__builtin_os_log_format:<br>
return emitBuiltinOSLogFormat(*E);<br>
<br>
- case Builtin::BI__builtin_os_log_format_buffer_size: {<br>
- analyze_os_log::OSLogBufferLayout Layout;<br>
- analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout);<br>
- return RValue::get(ConstantInt::get(ConvertType(E->getType()),<br>
- Layout.size().getQuantity()));<br>
- }<br>
-<br>
case Builtin::BI__xray_customevent: {<br>
if (!ShouldXRayInstrumentFunction())<br>
return RValue::getIgnored();<br>
<br>
Modified: cfe/trunk/test/CodeGen/builtins.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins.c?rev=345866&r1=345865&r2=345866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins.c?rev=345866&r1=345865&r2=345866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/builtins.c (original)<br>
+++ cfe/trunk/test/CodeGen/builtins.c Thu Nov 1 11:04:49 2018<br>
@@ -729,25 +729,28 @@ void test_builtin_os_log_merge_helper1(v<br>
<br>
// CHECK-LABEL: define void @test_builtin_os_log_errno<br>
void test_builtin_os_log_errno() {<br>
- // CHECK: %[[VLA:.*]] = alloca i8, i64 4, align 16<br>
- // CHECK: call void @__os_log_helper_16_2_1_0_96(i8* %[[VLA]])<br>
+ // CHECK-NOT: @stacksave<br>
+ // CHECK: %[[BUF:.*]] = alloca [4 x i8], align 1<br>
+ // CHECK: %[[DECAY:.*]] = getelementptr inbounds [4 x i8], [4 x i8]* %[[BUF]], i32 0, i32 0<br>
+ // CHECK: call void @__os_log_helper_1_2_1_0_96(i8* %[[DECAY]])<br>
+ // CHECK-NOT: @stackrestore<br>
<br>
char buf[__builtin_os_log_format_buffer_size("%m")];<br>
__builtin_os_log_format(buf, "%m");<br>
}<br>
<br>
-// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_16_2_1_0_96<br>
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_1_0_96<br>
// CHECK: (i8* %[[BUFFER:.*]])<br>
<br>
// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8<br>
// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8<br>
// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8<br>
// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0<br>
-// CHECK: store i8 2, i8* %[[SUMMARY]], align 16<br>
+// CHECK: store i8 2, i8* %[[SUMMARY]], align 1<br>
// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1<br>
// CHECK: store i8 1, i8* %[[NUMARGS]], align 1<br>
// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2<br>
-// CHECK: store i8 96, i8* %[[ARGDESCRIPTOR]], align 2<br>
+// CHECK: store i8 96, i8* %[[ARGDESCRIPTOR]], align 1<br>
// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3<br>
// CHECK: store i8 0, i8* %[[ARGSIZE]], align 1<br>
// CHECK-NEXT: ret void<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>