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) {
2034
2034
}
2035
2035
2036
2036
// First destroy member objects.
2037
+ if (RD->isUnion ())
2038
+ return ;
2037
2039
for (auto *FI : RD->fields ()) {
2038
2040
// Check for constant size array. Set type to array element type.
2039
2041
QualType QT = FI->getType ();
Original file line number Diff line number Diff line change @@ -458,3 +458,31 @@ void testLeakBecauseNTTPIsNotDeallocation() {
458
458
void * p = ::operator new (10 );
459
459
deallocate_via_nttp<not_free>(p);
460
460
} // 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