[clang][ExprConst] Field pointer incorrectly diagnosed as "base class subobject"
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
See this code:
```c++
class A { public: int a; };
class B : public A { public: int b; };
class C : public B { };
constexpr C c{};
static_assert((void*)(A*)&c < (void*)&c.b);
static_assert(&c.a < &c.b);
```
```console
:9:17: error: static assertion expression is not an integral constant expression
9 | static_assert((void*)(A*)&c < (void*)&c.b);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
:9:31: note: comparison of address of base class subobject 'A' of class 'B' to field 'b' has unspecified value
9 | static_assert((void*)(A*)&c < (void*)&c.b);
| ^
:12:15: error: static assertion expression is not an integral constant expression
12 | static_assert(&c.a < &c.b);
| ^~~~~~~~~~~
:12:20: note: comparison of address of base class subobject 'A' of class 'B' to field 'b' has unspecified value
12 | static_assert(&c.a < &c.b);
| ^
```
https://godbolt.org/z/PqTqss6rG
The diagnostic makes sense for the first `static_assert`, but for the second it doesn't make sense I think.
If we instead change the class hierarchy so `C` inherits from both `A` and `B`, we get a diagnostic that's more like the one I wanted to see:
```c++
class A { public: int a; };
class B { public: int b; };
class C : public A, public B {};
constexpr C c{};
static_assert(&c.a < &c.b);
```
```console
array.cpp:501:17: error: static assertion expression is not an integral constant expression
501 | static_assert(&c.a < &c.b);
| ^~~~~~~~~~~
array.cpp:501:22: note: comparison of addresses of subobjects of different base classes has unspecified value
501 | static_assert(&c.a < &c.b);
| ^
```
Is the second `static_assert` in the first code sample actually UB and if so, is the diagnostic wrong or just poorly worded?
Contributor guide
Assessment
This issue has not been assessed yet.