I recently ran into issues with aggregates and inheritance, I'm using it for creating a type-safe library where most of the types are build over "tagged" std::array. After bit of cleaning and enabling -Wall -Wextra -pedantic I noticed clang only in my pipeline gives me warning. After a bit of focusing on it I found it's not helpful, and contemplate disabling the warning all together. After a discussion with other library authors I found it's bothering more people and decided to fix it.
Removes this warning:
template<typename T, int N> struct StdArray {
T contents[N];
};
template<typename T, int N> struct AggregateAndEmpty : StdArray<T,N> { };
AggregateAndEmpty<int, 3> p = {1, 2, 3}; // <-- warning here about omitted bracesThis warning starts to be prominent when you have multiple levels of inheritance for strong typing with aggregates:
template<typename T, int N> struct StdArray {
T contents[N];
};
template <typename T, int N> struct JustABaseClass : StdArray<T, N> {};
template <typename T, int N> struct OnionBaseClass : JustABaseClass<T, N> {};
OnionBaseClass<int,3> i = {1,2,3}; // instead {{{1,2,3}}}This is my first patch for clang, so I hopefully didn't overlook something, but all tests are green.
I wonder if it'd be clearer to replace the one base and no fields check and the one field and no bases check with something like:
// Brace elision is idiomatic if we're initializing the only direct subobject of // an aggregate of record type. if (Entity.getKind() == InitializedEntity::EK_Base || Entity.getKind() == InitializedEntity::EK_Member) { auto *ParentRD = Entity.getParent()->getType()->getAsRecordDecl(); unsigned Subobjects = std::distance(ParentRD->field_begin(), ParentRD->field_end()); if (auto *CXXRD = dyn_cast<CXXRecordDecl>(ParentRD)) Subobjects += CXXRD->getNumBases(); return Subobjects == 1; }This'd be linear in the number of fields instead of constant-time, but I suspect that doesn't matter in practice. Aggregate initialization is linear in the number of fields regardless.
(No strong preference here; take this or leave it.)