[cfe-dev] missing return statement for non-void functions in C++

Sjoerd Meijer sjoerd.meijer at arm.com
Tue Jul 28 06:14:40 PDT 2015


Hi,

 

In C++, the undefined behaviour of a missing return statements for a
non-void function results in not generating the function epilogue
(unreachable statement is inserted and the return statement is optimised
away).  Consequently, the runtime behaviour is that control is never
properly returned from this function and thus it starts executing "garbage
instructions". As this is undefined behaviour, this is perfectly fine and
according to the spec, and a compile warning for this missing return
statement is issued. However, in C, the behaviour is that a function
epilogue is generated, i.e. basically by returning uninitialised local
variable. Codes that rely on this are not beautiful pieces of code, i.e are
buggy, but it might just be okay if you for example have a function that
just initialises stuff (and the return value is not checked, directly or
indirectly); some one might argue that not returning from that function
might be a bit harsh. So this email is to probe if there would be strong
resistance to follow the C behaviour? I am not yet sure how, but would
perhaps a compromise be possible/acceptable to make the undefined behaviour
explicit and also generate the function epilogue?

 

The code snippet below is taken from CodeGenFunction.cpp, which implements
this C++ behaviour and also nicely documents why that is:

 

919   // C++11 [stmt.return]p2:

920   //   Flowing off the end of a function [...] results in undefined
behavior in

921   //   a value-returning function.

922   // C11 6.9.1p12:        

 923   //   If the '}' that terminates a function is reached, and the value
of the

924   //   function call is used by the caller, the behavior is undefined.

925   if (getLangOpts().CPlusPlus && !FD->hasImplicitReturnZero() &&
!SawAsmBlock &&

926       !FD->getReturnType()->isVoidType() && Builder.GetInsertBlock()) {

927     if (SanOpts.has(SanitizerKind::Return)) {

928       SanitizerScope SanScope(this);

929       llvm::Value *IsFalse = Builder.getFalse();

930       EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return),

931                 "missing_return",
EmitCheckSourceLocation(FD->getLocation()),

932                 None);

933     } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) {

934       EmitTrapCall(llvm::Intrinsic::trap);                 

 935     }   

 936     Builder.CreateUnreachable();

937     Builder.ClearInsertionPoint();

938   }                                     

 

 

Cheers,

Sjoerd.

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150728/4e743055/attachment.html>


More information about the cfe-dev mailing list