Bug 70692 - No warning when std::function<const int&(...)> binds a reference to a temporary
Summary: No warning when std::function<const int&(...)> binds a reference to a temporary
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: diagnostic
Depends on: 80472
Blocks: Wreturn-local-addr
  Show dependency treegraph
Reported: 2016-04-16 13:29 UTC by Jonathan Wakely
Modified: 2021-04-19 10:40 UTC (History)
4 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2016-04-16 00:00:00

Untested patch. (950 bytes, patch)
2016-04-16 13:55 UTC, Jonathan Wakely
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2016-04-16 13:29:22 UTC
This has undefined behaviour:

#include <functional>

int f() { return 0; }

int main()
  std::function<const int&()> ff = f;
  return ff();

but the -Wreturn-local-addr warning that is enabled by default is suppressed in system headers.

In file included from fun.cc:1:0:
/home/jwakely/gcc/6/include/c++/6.0.0/functional: In instantiation of ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes&& ...) [with _Res = const int&; _Functor = int (*)(); _ArgTypes = {}]’:
/home/jwakely/gcc/6/include/c++/6.0.0/functional:2124:19:   required from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = int (*)(); <template-parameter-2-2> = void; <template-parameter-2-3> = void; _Res = const int&; _ArgTypes = {}]’
fun.cc:7:36:   required from here
/home/jwakely/gcc/6/include/c++/6.0.0/functional:1726:40: warning: returning reference to temporary [-Wreturn-local-addr]

We should either ensure the warning is enabled, even in system headers (similar to PR 58876) or add a run-time check to _Function_handler<_Res(_ArgTypes...), _Functor>::_M_invoke (it can't be a compile-time static assertion because that function is instantiated even if it's never called, and the code is only undefined if it's invoked).
Comment 1 Jonathan Wakely 2016-04-16 13:55:28 UTC
Created attachment 38288 [details]
Untested patch.

We can enable -Wsystem-headers around the relevant function, but we also need a change to <ext/string_conversions.h> to suppress the false positive -Wsign-compare warnings in there.
Comment 2 Jonathan Wakely 2016-04-16 14:08:30 UTC
Bah, it seems that -Wsystem-headers doesn't get turned off again by the

#pragma GCC diagnostic pop
Comment 3 Jonathan Wakely 2019-03-25 23:32:47 UTC
This should get addressed more thoroughly by https://wg21.link/p0932