Index: cfe/trunk/lib/CodeGen/CGCall.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGCall.cpp +++ cfe/trunk/lib/CodeGen/CGCall.cpp @@ -1462,6 +1462,10 @@ 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 @@ 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(); Index: cfe/trunk/test/CodeGen/attr-naked.c =================================================================== --- cfe/trunk/test/CodeGen/attr-naked.c +++ cfe/trunk/test/CodeGen/attr-naked.c @@ -12,7 +12,15 @@ // 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{{.*}} }