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.

Reply via email to