llvm / llvm/llvm-project

Clang accepts invalid forward-declared scoped enum with dependent underlying type in class template

Open
#183,597 2 comments 1 reaction 0 assignees View on GitHub
clang:frontend diverges-from:gcc
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

**What code / commands /steps will reproduce the problem?**
Compile the below sample code:

```c++
template
struct color {
enum city : int;
};

template
enum color::city : T {
london, ny, paris
};

int main() {
(void)color::london;
}
```

Compiler Explorer link: https://godbolt.org/z/frcn8jqK6

**What is the expected result?**
This is ill-formed code and must be rejected by the compiler with compile-time error.

C++17 ISO/IEC 14882:2017 Section 10.2 para 6 [dcl.enum] mentions:
An enumeration whose underlying type is fixed is an incomplete type from its point of declaration to immediately after its enum-base (if any), at which point it becomes a complete type. An enumeration whose underlying type is not fixed is an incomplete type from its point of declaration to immediately after the closing } of its enum-specifier, at which point it becomes a complete type.

**What happens instead?**
g++ (GCC) compilation fails:
```
:7:23: error: different underlying type in enum 'enum color::city' [-Wtemplate-body]
7 | enum color::city : T {
| ^
:3:17: note: previous definition here
3 | enum city : int;
| ^~~
Compiler returned: 1
```

Clang compiles successfully without any error or warning.

A forward-declared scoped enum inside a class template fixes the underlying type to int, but Clang accepts a later definition that uses the template parameter as the underlying type when compiled under -std=c++17.
This must be fixed.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.