зеркало из https://github.com/microsoft/clang-1.git
Under a compiler flag, -freset-local-blocks,
wipe out stack blocks when they go out of scope. // rdar://9227352 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134045 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
d6a4d18f52
Коммит
1077e420b8
|
@ -72,6 +72,7 @@ public:
|
|||
unsigned POSIXThreads : 1; // Compiling with POSIX thread support
|
||||
// (-pthread)
|
||||
unsigned Blocks : 1; // block extension to C
|
||||
unsigned ResetLocalBlocks : 1; // reset local blocks going out of scope
|
||||
unsigned EmitAllDecls : 1; // Emit all declarations, even if
|
||||
// they are unused.
|
||||
unsigned MathErrno : 1; // Math functions must respect errno
|
||||
|
@ -198,7 +199,7 @@ public:
|
|||
|
||||
ThreadsafeStatics = 1;
|
||||
POSIXThreads = 0;
|
||||
Blocks = 0;
|
||||
Blocks = ResetLocalBlocks = 0;
|
||||
EmitAllDecls = 0;
|
||||
MathErrno = 1;
|
||||
SignedOverflowBehavior = SOB_Undefined;
|
||||
|
|
|
@ -444,6 +444,8 @@ def femit_all_decls : Flag<"-femit-all-decls">,
|
|||
HelpText<"Emit all declarations, even if unused">;
|
||||
def fblocks : Flag<"-fblocks">,
|
||||
HelpText<"enable the 'blocks' language feature">;
|
||||
def freset_local_blocks : Flag<"-freset-local-blocks">,
|
||||
HelpText<"reset local blocks when they go out of scope">;
|
||||
def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
|
||||
def fexceptions : Flag<"-fexceptions">,
|
||||
HelpText<"Enable support for exception handling">;
|
||||
|
|
|
@ -259,6 +259,7 @@ def fastf : Flag<"-fastf">, Group<f_Group>;
|
|||
def fast : Flag<"-fast">, Group<f_Group>;
|
||||
def fasynchronous_unwind_tables : Flag<"-fasynchronous-unwind-tables">, Group<f_Group>;
|
||||
def fblocks : Flag<"-fblocks">, Group<f_Group>;
|
||||
def freset_local_blocks : Flag<"-freset-local-blocks">, Group<f_Group>;
|
||||
def fbootclasspath_EQ : Joined<"-fbootclasspath=">, Group<f_Group>;
|
||||
def fborland_extensions : Flag<"-fborland-extensions">, Group<f_Group>;
|
||||
def fbuiltin_strcat : Flag<"-fbuiltin-strcat">, Group<f_Group>;
|
||||
|
|
|
@ -25,6 +25,22 @@
|
|||
using namespace clang;
|
||||
using namespace CodeGen;
|
||||
|
||||
struct CallMemsetLocalBlockObject : EHScopeStack::Cleanup {
|
||||
llvm::AllocaInst *BlockAddr;
|
||||
CharUnits BlockSize;
|
||||
|
||||
CallMemsetLocalBlockObject(llvm::AllocaInst *blockAddr,
|
||||
CharUnits blocSize)
|
||||
: BlockAddr(blockAddr), BlockSize(blocSize) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool isForEH) {
|
||||
CGF.Builder.CreateMemSet(BlockAddr,
|
||||
llvm::ConstantInt::get(CGF.Int8Ty, 0xCD),
|
||||
BlockSize.getQuantity(),
|
||||
BlockAddr->getAlignment());
|
||||
}
|
||||
};
|
||||
|
||||
CGBlockInfo::CGBlockInfo(const BlockExpr *blockExpr, const char *N)
|
||||
: Name(N), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false),
|
||||
HasCXXObject(false), UsesStret(false), StructureType(0), Block(blockExpr) {
|
||||
|
@ -649,6 +665,9 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) {
|
|||
llvm::Value *result =
|
||||
Builder.CreateBitCast(blockAddr,
|
||||
ConvertType(blockInfo.getBlockExpr()->getType()));
|
||||
if (getLangOptions().ResetLocalBlocks)
|
||||
EHStack.pushCleanup<CallMemsetLocalBlockObject>(NormalCleanup, blockAddr,
|
||||
blockInfo.BlockSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1709,6 +1709,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
!Args.hasArg(options::OPT_fno_blocks))) {
|
||||
CmdArgs.push_back("-fblocks");
|
||||
}
|
||||
if (Args.hasArg(options::OPT_freset_local_blocks))
|
||||
CmdArgs.push_back("-freset-local-blocks");
|
||||
|
||||
// -faccess-control is default.
|
||||
if (Args.hasFlag(options::OPT_fno_access_control,
|
||||
|
|
|
@ -638,6 +638,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
|
|||
Res.push_back("-pthread");
|
||||
if (Opts.Blocks)
|
||||
Res.push_back("-fblocks");
|
||||
if (Opts.ResetLocalBlocks)
|
||||
Res.push_back("-freset-local-blocks");
|
||||
if (Opts.EmitAllDecls)
|
||||
Res.push_back("-femit-all-decls");
|
||||
if (Opts.MathErrno)
|
||||
|
@ -1612,6 +1614,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
|
|||
|
||||
Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
|
||||
Opts.Blocks = Args.hasArg(OPT_fblocks);
|
||||
Opts.ResetLocalBlocks = Args.hasArg(OPT_freset_local_blocks);
|
||||
Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
|
||||
Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
|
||||
Opts.ShortEnums = Args.hasArg(OPT_fshort_enums);
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -freset-local-blocks -o - %s | FileCheck %s
|
||||
// rdar://9227352
|
||||
|
||||
typedef int (^BLOCK)();
|
||||
|
||||
BLOCK FUNC() {
|
||||
int i;
|
||||
double d;
|
||||
BLOCK block = ^{ return i + (int)d; };
|
||||
if (!block)
|
||||
block = ^{ return i; };
|
||||
return block;
|
||||
}
|
||||
|
||||
//CHECK: call void @llvm.memset{{.*}}, i8 -51, i64 36, i32 8, i1 false)
|
||||
//CHECK: call void @llvm.memset{{.*}}, i8 -51, i64 44, i32 8, i1 false)
|
Загрузка…
Ссылка в новой задаче