https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86956

            Bug ID: 86956
           Summary: Use of an alias template unexpectedly breaks
                    compilation
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: v.reshetnikov at gmail dot com
  Target Milestone: ---

/********************** BEGIN SOURCE **********************/
template<class>
struct Outer {
    template<bool>
    struct Inner;

    template<bool x>
    using Alias = Inner<x>;
};

template<>
template<bool v>
struct Outer<void>::Inner { 
    static constexpr bool value = v;
};

static_assert(Outer<void>::Inner<true>::value); // OK
static_assert(Outer<void>::Alias<true>::value); // error
/*********************** END SOURCE ***********************/

The first static_assert compiles OK, but the second results in unexpected
errors:

/********************** BEGIN OUTPUT **********************/
<source>: In instantiation of 'struct Outer<void>::Inner<true>':
<source>:17:39:   required from here
<source>:12:27: error: type/value mismatch at argument 1 in template parameter
list for 'template<bool <anonymous> > struct Outer<void>::Inner<<enumerator> >'
12 | struct Outer<void>::Inner {
   |                           ^
<source>:12:27: note:   expected a constant of type 'bool', got 'void'
<source>:12:27: error: type/value mismatch at argument 1 in template parameter
list for 'Outer<void>::Inner<<enumerator> >::Inner'
<source>:12:27: note:   expected a constant of type 'bool', got 'void'
<source>:13:27: error: type/value mismatch at argument 1 in template parameter
list for 'template<bool <anonymous> > struct Outer<void>::Inner<<enumerator> >'
13 |     static constexpr bool value = v;
   |                           ^~~~~
<source>:13:27: note:   expected a constant of type 'bool', got 'void'
<source>:13:27: error: type/value mismatch at argument 1 in template parameter
list for 'value'
<source>:13:27: note:   expected a constant of type 'bool', got 'void'
<source>:17:41: error: 'value' is not a member of 'Outer<void>::Alias<true>'
{aka 'Outer<void>::Inner<true>'}
17 | static_assert(Outer<void>::Alias<true>::value); // error
   |                                         ^~~~~
Compiler returned: 1
/*********************** END OUTPUT ***********************/

The part "expected a constant of type 'bool', got 'void'" looks inexplicable;
"Inner<<enumerator> >" is also difficult to decipher. The issue is discovered
with build 9.0.0 20180813 (experimental), but appears to exist in earlier
versions as well.

For comparison, Clang compiles this code successfully.

Reply via email to