File tree Expand file tree Collapse file tree 3 files changed +54
-0
lines changed Expand file tree Collapse file tree 3 files changed +54
-0
lines changed Original file line number Diff line number Diff line change @@ -2041,6 +2041,8 @@ void CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) {
20412041 }
20422042
20432043 // First destroy member objects.
2044+ if (RD->isUnion ())
2045+ return ;
20442046 for (auto *FI : RD->fields ()) {
20452047 // Check for constant size array. Set type to array element type.
20462048 QualType QT = FI->getType ();
Original file line number Diff line number Diff line change @@ -441,3 +441,31 @@ void testLeakBecauseNTTPIsNotDeallocation() {
441441 void * p = ::operator new (10 );
442442 deallocate_via_nttp<not_free>(p);
443443} // leak-warning{{Potential leak of memory pointed to by 'p'}}
444+
445+ namespace optional_union {
446+ template <typename T>
447+ class unique_ptr {
448+ T *q;
449+ public:
450+ unique_ptr () : q(new T) {}
451+ ~unique_ptr () {
452+ delete q;
453+ }
454+ };
455+
456+ union custom_union_t {
457+ unique_ptr<int > present;
458+ char notpresent;
459+ custom_union_t () : present (unique_ptr<int >()) {}
460+ ~custom_union_t () {};
461+ };
462+
463+ void testUnionCorrect () {
464+ custom_union_t a;
465+ a.present .~unique_ptr<int >();
466+ }
467+
468+ void testUnionLeak () {
469+ custom_union_t a;
470+ } // leak-warning{{Potential leak of memory pointed to by 'a.present.q'}}
471+ }
Original file line number Diff line number Diff line change @@ -377,3 +377,27 @@ void directUnknownSymbol() {
377377}
378378
379379}
380+
381+ void testUnionDtor () {
382+ static int unionDtorCalled;
383+ InlineDtor::cnt = 0 ;
384+ InlineDtor::dtorCalled = 0 ;
385+ unionDtorCalled = 0 ;
386+ {
387+ union UnionDtor {
388+ InlineDtor kind1;
389+ char kind2;
390+ ~UnionDtor () { unionDtorCalled++; }
391+ };
392+ UnionDtor u1{.kind1 {}};
393+ UnionDtor u2{.kind2 {}};
394+ auto u3 = new UnionDtor{.kind1 {}};
395+ auto u4 = new UnionDtor{.kind2 {}};
396+ delete u3;
397+ delete u4;
398+ }
399+
400+ clang_analyzer_eval (unionDtorCalled == 4 ); // expected-warning {{TRUE}}
401+ clang_analyzer_eval (InlineDtor::dtorCalled != 4 ); // expected-warning {{TRUE}}
402+ clang_analyzer_eval (InlineDtor::dtorCalled == 0 ); // expected-warning {{TRUE}}
403+ }
You can’t perform that action at this time.
0 commit comments