clang generates bad code for std::function and __noreturn__

Originator:dairgrant
Number:rdar://19901364 Date Originated:09/Jun/15
Status:Open Resolved:
Product:Developer Tools Product Version:Xcode 6.1.1
Classification: Reproducible:Always
 
Summary:
If you declare a function with the _noreturn_ attribute then the compiler truncates the calling function after the call instruction. As the function never returns the caller does not need to perform any stack cleanup, return instruction, etc.

If you put a function inside a C++ std::function object then it generates a stub function to invoke your function.

That stub function is a template and so is instantiated based on param/return types: every function with the same signature uses the same stub. If your function is _noreturn_ then that stub gets truncated after the call instruction.

However clang does not take that attribute into account when reusing the instantiation for different functions.

So if you put a _noreturn_ function inside a std::function then any other std::function with a matching signature will be invoked by a caller that assumes they are also _noreturn_.

As these functions are not _noreturn_ they will actually return, jumping back to whatever happened to be after the truncated stub function.

Steps to Reproduce:
Attached example contains a test.cpp which demonstrates the problem.

Version:
Xcode 6.1.1 (6A2008a)
Mac OS X 10.9.5 (13F34)
$ clang -v
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

Configuration:
Seen in Xcode 5.1.1 and Xcode 6.1.1, for either C+98 (std::tr1) and C+11 (std).

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!