Bug 66042 - Implicitly converts lvalue to rvalue when returning reference parameter in function template
Summary: Implicitly converts lvalue to rvalue when returning reference parameter in fu...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.1.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-05-07 06:44 UTC by David Stone
Modified: 2015-05-07 14:36 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Stone 2015-05-07 06:44:29 UTC
#include <type_traits>

template<typename T>
auto compiles(T && t) -> T && {
	static_assert(std::is_same<T, int>::value, "Incorrect type deduced for T.");
	return t;
}
static_assert(std::is_same<int &&, decltype(compiles(0))>::value, "shouldn't compile");

auto fails(int && t) -> int && {
	return t;
}
static_assert(std::is_same<int &&, decltype(fails(0))>::value, "doesn't compile");


Neither function should compile. In the function template case, T is deduced as int, so the parameter type is int &&. Local variables and function parameters taken by value can be implicitly moved into the return value, but not function parameters taken by rvalue reference (t is an lvalue, even though decltype(t) == int &&).

The non-template function correctly honors this behavior.

If the return type of compiles is changed to decltype(auto) or auto &&, then the function correctly returns int & and the static_assert fires.
Comment 1 David Stone 2015-05-07 06:45:33 UTC
I have also filed this bug against clang under https://llvm.org/bugs/show_bug.cgi?id=23440
Comment 2 David Stone 2015-05-07 14:36:21 UTC
It looks like gcc behaves correctly, which can be seen by adding the line

auto x = compiles(0);

I wasn't actually instantiating the template, just looking at its return type.

This can be closed; sorry for the noise.