modocache created this revision.
modocache added reviewers: rsmith, rjmccall, doug.gregor, ahatanak.
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`
Repository:
rC Clang
https://reviews.llvm.org/D53860
Files:
lib/Sema/SemaInit.cpp
test/SemaCXX/aggregate-initialization.cpp
Index: test/SemaCXX/aggregate-initialization.cpp
===================================================================
--- test/SemaCXX/aggregate-initialization.cpp
+++ test/SemaCXX/aggregate-initialization.cpp
@@ -219,7 +219,7 @@
struct S0 { int f; ~S0() = delete; }; // expected-note {{'~S0' has been
explicitly marked deleted here}}
// Check destructor of base class.
- struct S3 : S0 {};
+ struct S3 : S0 {}; // expected-note {{destructor of 'S3' is implicitly
deleted because base class 'ElementDestructor::BaseDestructor::S0' has a
deleted destructor}}
void test3() {
S3 s3 = {1}; // expected-error {{attempt to use a deleted function}}
@@ -233,4 +233,10 @@
struct B { B(); A a; };
struct C { B b; };
C c = { B() };
+
+ // Zylong's destructor doesn't have to be accessible from the context of
+ // Yerbl's initialization.
+ struct Zylong { protected: ~Zylong(); };
+ struct Yerbl : Zylong {};
+ Yerbl y = {};
}
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -1954,7 +1954,7 @@
}
if (!VerifyOnly)
- if (hasAccessibleDestructor(Base.getType(), InitLoc, SemaRef)) {
+ if (hasAccessibleDestructor(DeclType, InitLoc, SemaRef)) {
hadError = true;
return;
}
Index: test/SemaCXX/aggregate-initialization.cpp
===================================================================
--- test/SemaCXX/aggregate-initialization.cpp
+++ test/SemaCXX/aggregate-initialization.cpp
@@ -219,7 +219,7 @@
struct S0 { int f; ~S0() = delete; }; // expected-note {{'~S0' has been explicitly marked deleted here}}
// Check destructor of base class.
- struct S3 : S0 {};
+ struct S3 : S0 {}; // expected-note {{destructor of 'S3' is implicitly deleted because base class 'ElementDestructor::BaseDestructor::S0' has a deleted destructor}}
void test3() {
S3 s3 = {1}; // expected-error {{attempt to use a deleted function}}
@@ -233,4 +233,10 @@
struct B { B(); A a; };
struct C { B b; };
C c = { B() };
+
+ // Zylong's destructor doesn't have to be accessible from the context of
+ // Yerbl's initialization.
+ struct Zylong { protected: ~Zylong(); };
+ struct Yerbl : Zylong {};
+ Yerbl y = {};
}
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -1954,7 +1954,7 @@
}
if (!VerifyOnly)
- if (hasAccessibleDestructor(Base.getType(), InitLoc, SemaRef)) {
+ if (hasAccessibleDestructor(DeclType, InitLoc, SemaRef)) {
hadError = true;
return;
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits