-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Open
Labels
c++20clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"
Description
Consider this code compiled in C++20 mode:
#include <vector>
struct X{
struct Inner;
unsigned size() { return children.size(); }
std::vector<Inner> children;
};
struct X::Inner {
int a;
};
MSVC and GCC will succeed, but Clang (trunk, WIP version 16 at the time of writing) produces an error:
/lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0/bits/stl_vector.h:988:50: error: arithmetic on a pointer to an incomplete type 'X::Inner'
{ return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
This boils down to different approaches when instantiating constexpr
functions:
template <class T>
struct vector {
T* ptr;
constexpr unsigned size() { return ptr - ptr; }
};
struct X{
struct Inner;
unsigned size() { return children.size(); }
vector<Inner> children;
};
struct X::Inner {
int a;
};
Clang instantiates the bodies of constexpr
functions eagerly, other compilers seem to delay the instantiation until the end of the TU, e.g. this code fails in all compilers:
template <class T>
struct vector {
T* ptr;
constexpr unsigned size() { return ptr - ptr; }
};
struct X{
struct Inner;
static constexpr int a = vector<Inner>().size();
vector<Inner> children;
};
struct X::Inner {
int a;
};
We have observed that this pattern is used in much of the existing code and I believe Clang should follow the GCC's and MSVC's approach here, even though it is not mandated by the standard:
- it avoids breaking code that worked in C++17 when migrating to C++20.
- it allows to compile future C++20 code written for GCC and MSVC with Clang with no changes.
jdrouhard and zhanglistarzclllyybb
Metadata
Metadata
Assignees
Labels
c++20clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"
Type
Projects
Status
No status