Index: lib/CodeGen/SafeStack.cpp =================================================================== --- lib/CodeGen/SafeStack.cpp +++ lib/CodeGen/SafeStack.cpp @@ -58,6 +58,11 @@ "Non-thread-local storage"), clEnumValEnd)); +static cl::opt SubroutineAccessAsUnsafe("safe-stack-subr-acc-as-unsafe", + cl::Hidden, cl::init(false), + cl::desc("Allocate memory on the unsafe stack if a pointer to it is passed " + "to a subroutine")); + namespace llvm { STATISTIC(NumFunctions, "Total number of functions"); @@ -313,6 +318,9 @@ continue; } + if (SubroutineAccessAsUnsafe) + return false; + // LLVM 'nocapture' attribute is only set for arguments whose address // is not stored, passed around, or used in any other non-trivial way. // We assume that passing a pointer to an object as a 'nocapture Index: test/Transforms/SafeStack/call.ll =================================================================== --- test/Transforms/SafeStack/call.ll +++ test/Transforms/SafeStack/call.ll @@ -1,5 +1,7 @@ ; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s ; RUN: opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s +; RUN: opt -safe-stack -safe-stack-subr-acc-as-unsafe -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck -check-prefix=SUBR-ACC-AS-UNSAFE %s +; RUN: opt -safe-stack -safe-stack-subr-acc-as-unsafe -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck -check-prefix=SUBR-ACC-AS-UNSAFE %s @.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1 @@ -79,11 +81,12 @@ ret void } -; Arg0 is readnone, arg1 is not. Pass alloca ptr as arg0 -> safe +; Arg0 is readnone, arg1 is not. Pass alloca ptr as arg0 -> safe unless -safe-stack-subr-acc-as-unsafe is set. define void @call_readnone0_0(i64 %len) safestack { entry: ; CHECK-LABEL: define void @call_readnone0_0 ; CHECK-NOT: @__safestack_unsafe_stack_ptr + ; SUBR-ACC-AS-UNSAFE: @__safestack_unsafe_stack_ptr ; CHECK: ret void %q = alloca [10 x i8], align 1 %arraydecay = getelementptr inbounds [10 x i8], [10 x i8]* %q, i32 0, i32 0