In https://reviews.llvm.org/D45898?id=157373, @rsmith advises to move a
checkMemberDestructor into InitListChecker::CheckStructUnionTypes,
to check base classes for an accessible destructor when performing
aggregate initialization. However, in so doing, the following C++ code
now fails to compile:
class Base { protected: ~Base() = default; }; struct Derived : Base {}; void foo() { Derived d = {}; }
GCC 8.2 and Clang 7.0.0 both treat this C++ code as valid, whereas
Clang trunk emits the following error diagnostic:
<source>:3:27: error: temporary of type 'Base' has protected destructor void foo() { Derived d = {}; } ^ <source>:1:25: note: declared protected here class Base { protected: ~Base() = default; }; ^
I think Clang trunk is wrong about the validity of this C++ code: my
understanding of the C++17 standard is that the Base destructor need
only be accessible from within the context of Derived, and not at the
context in which Derived is aggregate initialized within the foo
function.
Add a test for the case above, and modify the destructor access check
within InitListChecker::CheckStructUnionTypes to check only that the
derived class has an accessible destructor.
Test Plan: check-clang