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) {
2041
2041
}
2042
2042
2043
2043
// First destroy member objects.
2044
+ if (RD->isUnion ())
2045
+ return ;
2044
2046
for (auto *FI : RD->fields ()) {
2045
2047
// Check for constant size array. Set type to array element type.
2046
2048
QualType QT = FI->getType ();
Original file line number Diff line number Diff line change @@ -441,3 +441,31 @@ void testLeakBecauseNTTPIsNotDeallocation() {
441
441
void * p = ::operator new (10 );
442
442
deallocate_via_nttp<not_free>(p);
443
443
} // 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() {
377
377
}
378
378
379
379
}
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