https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114124
Bug ID: 114124 Summary: Rejected use of function parameter as non-type template parameter in trailing-return-type Product: gcc Version: 13.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: barry.revzin at gmail dot com Target Milestone: --- Reduced from StackOverflow: template <int V> struct Constant { constexpr operator int() const noexcept { return V; } }; template <class T, int N> struct Array { }; auto function(auto s) -> Array<int, s + s> { return {}; } auto const a = function(Constant<3>{}); gcc trunk rejects this example with: <source>:10:42: error: template argument 2 is invalid 10 | auto function(auto s) -> Array<int, s + s> { | ^ <source>:10:42: error: template argument 2 is invalid <source>:10:42: error: template argument 2 is invalid <source>:10:42: error: template argument 2 is invalid <source>:10:26: error: invalid template-id 10 | auto function(auto s) -> Array<int, s + s> { | ^~~~~ <source>:10:39: error: use of parameter outside function body before '+' token 10 | auto function(auto s) -> Array<int, s + s> { | ^ <source>:10:42: error: use of parameter outside function body before '>' token 10 | auto function(auto s) -> Array<int, s + s> { | ^ <source>:10:1: error: deduced class type 'Array' in function return type 10 | auto function(auto s) -> Array<int, s + s> { | ^~~~ <source>:8:8: note: 'template<class T, int N> struct Array' declared here 8 | struct Array { }; | ^~~~~ <source>:14:16: error: 'function' was not declared in this scope; did you mean 'union'? 14 | auto const a = function(Constant<3>{}); | ^~~~~~~~ | union But this exact equivalent formulation of function is accepted: auto function(auto s) { return Array<int, s + s>{}; } In this case, we're not actually reading the value of s to form the non-type template argument, so this should be valid.