From: Hans Wennborg Date: Thu, 4 Sep 2014 22:16:33 +0000 (+0000) Subject: Don't emit prologues or epilogues for naked functions (PR18791, PR20028) X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=60de5eb5b9bb9c64abc4b94636a5202d98205026;p=clang Don't emit prologues or epilogues for naked functions (PR18791, PR20028) For naked functions with parameters, Clang would still emit stores in the prologue that would clobber the stack, because LLVM doesn't set up a stack frame. (This shows up in -O0 compiles, because the stores are optimized away otherwise.) For example: __attribute__((naked)) int f(int x) { asm("movl $42, %eax"); asm("retl"); } Would result in: _Z1fi: movl 12(%esp), %eax movl %eax, (%esp) <--- Oops. movl $42, %eax retl Differential Revision: http://reviews.llvm.org/D5183 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@217198 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index ce16d3bd64..f0eeba06f9 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1462,6 +1462,10 @@ static bool shouldAddNonNullAttr(const Decl *FD, const ParmVarDecl *PVD) { void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, llvm::Function *Fn, const FunctionArgList &Args) { + if (CurCodeDecl && CurCodeDecl->hasAttr()) + // Naked functions don't have prologues. + return; + // If this is an implicit-return-zero function, go ahead and // initialize the return value. TODO: it might be nice to have // a more general mechanism for this that didn't require synthesized @@ -1985,6 +1989,12 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc, SourceLocation EndLoc) { + if (CurCodeDecl && CurCodeDecl->hasAttr()) { + // Naked functions don't have epilogues. + Builder.CreateUnreachable(); + return; + } + // Functions with no result always return void. if (!ReturnValue) { Builder.CreateRetVoid(); diff --git a/test/CodeGen/attr-naked.c b/test/CodeGen/attr-naked.c index c07dd8d373..270fc7959f 100644 --- a/test/CodeGen/attr-naked.c +++ b/test/CodeGen/attr-naked.c @@ -12,7 +12,15 @@ void t1() // Make sure this doesn't explode in the verifier. // (It doesn't really make sense, but it isn't invalid.) // CHECK: define void @t2() [[NAKED]] { -__attribute((naked, always_inline)) void t2() { +__attribute((naked, always_inline)) void t2() { +} + +// Make sure not to generate prolog or epilog for naked functions. +__attribute((naked)) void t3(int x) { +// CHECK: define void @t3(i32) +// CHECK-NOT: alloca +// CHECK-NOT: store +// CHECK: unreachable } // CHECK: attributes [[NAKED]] = { naked noinline nounwind{{.*}} }