[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