ahatanak updated this revision to Diff 153779. ahatanak added a comment. Herald added a subscriber: dexonsmith.
Implement the new rule defined here: http://wg21.link/p0968r0#2227. Produce a diagnostic if a class is initialized with aggregate initialization and one of its element's destructor is not accessible. Repository: rC Clang https://reviews.llvm.org/D45898 Files: lib/Sema/SemaInit.cpp test/CodeGenObjCXX/arc-list-init-destruct.mm test/SemaCXX/aggregate-initialization.cpp Index: test/SemaCXX/aggregate-initialization.cpp =================================================================== --- test/SemaCXX/aggregate-initialization.cpp +++ test/SemaCXX/aggregate-initialization.cpp @@ -186,3 +186,15 @@ // amount of time. struct A { int n; int arr[1000 * 1000 * 1000]; } a = {1, {2}}; } + +namespace ElementDestructor { + // The destructor for each element of class type is potentially invoked + // (15.4 [class.dtor]) from the context where the aggregate initialization + // occurs. Produce a diagnostic if an element's destructor isn't accessible. + + class X { ~X(); }; // expected-note {{implicitly declared private here}} + struct Y { X x; }; + void test() { + auto *y = new Y {}; // expected-error {{temporary of type 'ElementDestructor::X' has private destructor}} + } +} Index: test/CodeGenObjCXX/arc-list-init-destruct.mm =================================================================== --- /dev/null +++ test/CodeGenObjCXX/arc-list-init-destruct.mm @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -std=c++1z -fobjc-arc -fobjc-exceptions -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s + +// CHECK: %[[V0:.*]] = type opaque +// CHECK: %[[STRUCT_CLASS1:.*]] = type { %[[V0]]* } + +@interface Class0; +@end + +struct Class1 { + Class0 *f; +}; + +struct Container { + Class1 a; + bool b; +}; + +bool getBool() { + return false; +} + +Class0 *g; + +// CHECK: define {{.*}} @_Z4testv() +// CHECK: invoke zeroext i1 @_Z7getBoolv() +// CHECK: landingpad { i8*, i32 } +// CHECK: call void @_ZN6Class1D1Ev(%[[STRUCT_CLASS1]]* %{{.*}}) +// CHECK: br label + +// CHECK: define linkonce_odr void @_ZN6Class1D1Ev( + +Container test() { + return {{g}, getBool()}; +} Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -7083,6 +7083,28 @@ InitListExpr *StructuredInitList = PerformInitList.getFullyStructuredList(); + + // The destructor for each element of class type is potentially invoked + // (15.4 [class.dtor]) from the context where the aggregate + // initialization occurs. + if (StructuredInitList) + if (const auto *RD = + StructuredInitList->getType()->getAsCXXRecordDecl()) { + for (const FieldDecl *FD : RD->fields()) { + QualType FT = FD->getType(); + if (auto *FRD = FT->getAsCXXRecordDecl()) { + CXXDestructorDecl *Destructor = S.LookupDestructor(FRD); + S.CheckDestructorAccess(CurInit.get()->getLocStart(), Destructor, + S.PDiag(diag::err_access_dtor_temp) + << FT); + S.MarkFunctionReferenced(CurInit.get()->getLocStart(), + Destructor); + if (S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getLocStart())) + return ExprError(); + } + } + } + CurInit.get(); CurInit = shouldBindAsTemporary(InitEntity) ? S.MaybeBindToTemporary(StructuredInitList)
Index: test/SemaCXX/aggregate-initialization.cpp =================================================================== --- test/SemaCXX/aggregate-initialization.cpp +++ test/SemaCXX/aggregate-initialization.cpp @@ -186,3 +186,15 @@ // amount of time. struct A { int n; int arr[1000 * 1000 * 1000]; } a = {1, {2}}; } + +namespace ElementDestructor { + // The destructor for each element of class type is potentially invoked + // (15.4 [class.dtor]) from the context where the aggregate initialization + // occurs. Produce a diagnostic if an element's destructor isn't accessible. + + class X { ~X(); }; // expected-note {{implicitly declared private here}} + struct Y { X x; }; + void test() { + auto *y = new Y {}; // expected-error {{temporary of type 'ElementDestructor::X' has private destructor}} + } +} Index: test/CodeGenObjCXX/arc-list-init-destruct.mm =================================================================== --- /dev/null +++ test/CodeGenObjCXX/arc-list-init-destruct.mm @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -std=c++1z -fobjc-arc -fobjc-exceptions -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s + +// CHECK: %[[V0:.*]] = type opaque +// CHECK: %[[STRUCT_CLASS1:.*]] = type { %[[V0]]* } + +@interface Class0; +@end + +struct Class1 { + Class0 *f; +}; + +struct Container { + Class1 a; + bool b; +}; + +bool getBool() { + return false; +} + +Class0 *g; + +// CHECK: define {{.*}} @_Z4testv() +// CHECK: invoke zeroext i1 @_Z7getBoolv() +// CHECK: landingpad { i8*, i32 } +// CHECK: call void @_ZN6Class1D1Ev(%[[STRUCT_CLASS1]]* %{{.*}}) +// CHECK: br label + +// CHECK: define linkonce_odr void @_ZN6Class1D1Ev( + +Container test() { + return {{g}, getBool()}; +} Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -7083,6 +7083,28 @@ InitListExpr *StructuredInitList = PerformInitList.getFullyStructuredList(); + + // The destructor for each element of class type is potentially invoked + // (15.4 [class.dtor]) from the context where the aggregate + // initialization occurs. + if (StructuredInitList) + if (const auto *RD = + StructuredInitList->getType()->getAsCXXRecordDecl()) { + for (const FieldDecl *FD : RD->fields()) { + QualType FT = FD->getType(); + if (auto *FRD = FT->getAsCXXRecordDecl()) { + CXXDestructorDecl *Destructor = S.LookupDestructor(FRD); + S.CheckDestructorAccess(CurInit.get()->getLocStart(), Destructor, + S.PDiag(diag::err_access_dtor_temp) + << FT); + S.MarkFunctionReferenced(CurInit.get()->getLocStart(), + Destructor); + if (S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getLocStart())) + return ExprError(); + } + } + } + CurInit.get(); CurInit = shouldBindAsTemporary(InitEntity) ? S.MaybeBindToTemporary(StructuredInitList)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits