File tree Expand file tree Collapse file tree 3 files changed +68
-0
lines changed Expand file tree Collapse file tree 3 files changed +68
-0
lines changed Original file line number Diff line number Diff line change @@ -2034,6 +2034,8 @@ void CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) {
20342034 }
20352035
20362036 // First destroy member objects.
2037+ if (RD->isUnion ())
2038+ return ;
20372039 for (auto *FI : RD->fields ()) {
20382040 // Check for constant size array. Set type to array element type.
20392041 QualType QT = FI->getType ();
Original file line number Diff line number Diff line change @@ -458,3 +458,31 @@ void testLeakBecauseNTTPIsNotDeallocation() {
458458 void * p = ::operator new (10 );
459459 deallocate_via_nttp<not_free>(p);
460460} // leak-warning{{Potential leak of memory pointed to by 'p'}}
461+
462+ namespace optional_union {
463+ template <typename T>
464+ class unique_ptr {
465+ T *q;
466+ public:
467+ unique_ptr () : q(new T) {}
468+ ~unique_ptr () {
469+ delete q;
470+ }
471+ };
472+
473+ union custom_union_t {
474+ unique_ptr<int > present;
475+ char notpresent;
476+ custom_union_t () : present (unique_ptr<int >()) {}
477+ ~custom_union_t () {}
478+ };
479+
480+ void testUnionCorrect () {
481+ custom_union_t a;
482+ a.present .~unique_ptr<int >();
483+ }
484+
485+ void testUnionLeak () {
486+ custom_union_t a;
487+ } // leak-warning{{Potential leak of memory pointed to by 'a.present.q'}}
488+ }
Original file line number Diff line number Diff line change 1+ // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=destructors -verify -std=c++11 %s
2+ // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=destructors -verify -std=c++17 %s
3+
4+ void clang_analyzer_eval (bool );
5+
6+ struct InlineDtor {
7+ static int cnt;
8+ static int dtorCalled;
9+ ~InlineDtor () {
10+ ++dtorCalled;
11+ }
12+ };
13+
14+ int InlineDtor::cnt = 0 ;
15+ int InlineDtor::dtorCalled = 0 ;
16+
17+ void testUnionDtor () {
18+ static int unionDtorCalled;
19+ InlineDtor::cnt = 0 ;
20+ InlineDtor::dtorCalled = 0 ;
21+ unionDtorCalled = 0 ;
22+ {
23+ union UnionDtor {
24+ InlineDtor kind1;
25+ char kind2;
26+ ~UnionDtor () { unionDtorCalled++; }
27+ };
28+ UnionDtor u1{.kind1 {}};
29+ UnionDtor u2{.kind2 {}};
30+ auto u3 = new UnionDtor{.kind1 {}};
31+ auto u4 = new UnionDtor{.kind2 {}};
32+ delete u3;
33+ delete u4;
34+ }
35+
36+ clang_analyzer_eval (unionDtorCalled == 4 ); // expected-warning {{TRUE}}
37+ clang_analyzer_eval (InlineDtor::dtorCalled == 0 ); // expected-warning {{TRUE}}
38+ }
You can’t perform that action at this time.
0 commit comments