1*e3e9082bSisuckatcs // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++11 -verify %s 2*e3e9082bSisuckatcs // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s 3*e3e9082bSisuckatcs 4*e3e9082bSisuckatcs void clang_analyzer_eval(bool); 5*e3e9082bSisuckatcs 6*e3e9082bSisuckatcs struct S{ 7*e3e9082bSisuckatcs static int CtorInvocationCount; 8*e3e9082bSisuckatcs static int DtorInvocationCount; 9*e3e9082bSisuckatcs SS10*e3e9082bSisuckatcs S(){CtorInvocationCount++;} ~SS11*e3e9082bSisuckatcs ~S(){DtorInvocationCount++;} 12*e3e9082bSisuckatcs }; 13*e3e9082bSisuckatcs 14*e3e9082bSisuckatcs int S::CtorInvocationCount = 0; 15*e3e9082bSisuckatcs int S::DtorInvocationCount = 0; 16*e3e9082bSisuckatcs zeroSizeArrayStack()17*e3e9082bSisuckatcsvoid zeroSizeArrayStack() { 18*e3e9082bSisuckatcs S::CtorInvocationCount = 0; 19*e3e9082bSisuckatcs 20*e3e9082bSisuckatcs S arr[0]; 21*e3e9082bSisuckatcs 22*e3e9082bSisuckatcs clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}} 23*e3e9082bSisuckatcs } 24*e3e9082bSisuckatcs zeroSizeMultidimensionalArrayStack()25*e3e9082bSisuckatcsvoid zeroSizeMultidimensionalArrayStack() { 26*e3e9082bSisuckatcs S::CtorInvocationCount = 0; 27*e3e9082bSisuckatcs S::DtorInvocationCount = 0; 28*e3e9082bSisuckatcs 29*e3e9082bSisuckatcs { 30*e3e9082bSisuckatcs S arr[2][0]; 31*e3e9082bSisuckatcs S arr2[0][2]; 32*e3e9082bSisuckatcs 33*e3e9082bSisuckatcs S arr3[0][2][2]; 34*e3e9082bSisuckatcs S arr4[2][2][0]; 35*e3e9082bSisuckatcs S arr5[2][0][2]; 36*e3e9082bSisuckatcs } 37*e3e9082bSisuckatcs 38*e3e9082bSisuckatcs clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}} 39*e3e9082bSisuckatcs clang_analyzer_eval(S::DtorInvocationCount == 0); //expected-warning{{TRUE}} 40*e3e9082bSisuckatcs } 41*e3e9082bSisuckatcs zeroSizeArrayStackInLambda()42*e3e9082bSisuckatcsvoid zeroSizeArrayStackInLambda() { 43*e3e9082bSisuckatcs S::CtorInvocationCount = 0; 44*e3e9082bSisuckatcs S::DtorInvocationCount = 0; 45*e3e9082bSisuckatcs 46*e3e9082bSisuckatcs []{ 47*e3e9082bSisuckatcs S arr[0]; 48*e3e9082bSisuckatcs }(); 49*e3e9082bSisuckatcs 50*e3e9082bSisuckatcs clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}} 51*e3e9082bSisuckatcs clang_analyzer_eval(S::DtorInvocationCount == 0); //expected-warning{{TRUE}} 52*e3e9082bSisuckatcs } 53*e3e9082bSisuckatcs zeroSizeArrayHeap()54*e3e9082bSisuckatcsvoid zeroSizeArrayHeap() { 55*e3e9082bSisuckatcs S::CtorInvocationCount = 0; 56*e3e9082bSisuckatcs S::DtorInvocationCount = 0; 57*e3e9082bSisuckatcs 58*e3e9082bSisuckatcs auto *arr = new S[0]; 59*e3e9082bSisuckatcs delete[] arr; 60*e3e9082bSisuckatcs 61*e3e9082bSisuckatcs clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}} 62*e3e9082bSisuckatcs clang_analyzer_eval(S::DtorInvocationCount == 0); //expected-warning{{TRUE}} 63*e3e9082bSisuckatcs } 64*e3e9082bSisuckatcs zeroSizeMultidimensionalArrayHeap()65*e3e9082bSisuckatcsvoid zeroSizeMultidimensionalArrayHeap() { 66*e3e9082bSisuckatcs S::CtorInvocationCount = 0; 67*e3e9082bSisuckatcs S::DtorInvocationCount = 0; 68*e3e9082bSisuckatcs 69*e3e9082bSisuckatcs auto *arr = new S[2][0]; 70*e3e9082bSisuckatcs delete[] arr; 71*e3e9082bSisuckatcs 72*e3e9082bSisuckatcs auto *arr2 = new S[0][2]; 73*e3e9082bSisuckatcs delete[] arr2; 74*e3e9082bSisuckatcs 75*e3e9082bSisuckatcs auto *arr3 = new S[0][2][2]; 76*e3e9082bSisuckatcs delete[] arr3; 77*e3e9082bSisuckatcs 78*e3e9082bSisuckatcs auto *arr4 = new S[2][2][0]; 79*e3e9082bSisuckatcs delete[] arr4; 80*e3e9082bSisuckatcs 81*e3e9082bSisuckatcs auto *arr5 = new S[2][0][2]; 82*e3e9082bSisuckatcs delete[] arr5; 83*e3e9082bSisuckatcs 84*e3e9082bSisuckatcs clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}} 85*e3e9082bSisuckatcs clang_analyzer_eval(S::DtorInvocationCount == 0); //expected-warning{{TRUE}} 86*e3e9082bSisuckatcs } 87*e3e9082bSisuckatcs 88*e3e9082bSisuckatcs #if __cplusplus >= 201703L 89*e3e9082bSisuckatcs zeroSizeArrayBinding()90*e3e9082bSisuckatcsvoid zeroSizeArrayBinding() { 91*e3e9082bSisuckatcs S::CtorInvocationCount = 0; 92*e3e9082bSisuckatcs 93*e3e9082bSisuckatcs S arr[0]; 94*e3e9082bSisuckatcs 95*e3e9082bSisuckatcs // Note: This is an error in gcc but a warning in clang. 96*e3e9082bSisuckatcs // In MSVC the declaration of 'S arr[0]' is already an error 97*e3e9082bSisuckatcs // and it doesn't recognize this syntax as a structured binding. 98*e3e9082bSisuckatcs auto [] = arr; //expected-warning{{ISO C++17 does not allow a decomposition group to be empty}} 99*e3e9082bSisuckatcs 100*e3e9082bSisuckatcs clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}} 101*e3e9082bSisuckatcs } 102*e3e9082bSisuckatcs 103*e3e9082bSisuckatcs #endif 104*e3e9082bSisuckatcs zeroSizeArrayLambdaCapture()105*e3e9082bSisuckatcsvoid zeroSizeArrayLambdaCapture() { 106*e3e9082bSisuckatcs S::CtorInvocationCount = 0; 107*e3e9082bSisuckatcs S::DtorInvocationCount = 0; 108*e3e9082bSisuckatcs 109*e3e9082bSisuckatcs S arr[0]; 110*e3e9082bSisuckatcs 111*e3e9082bSisuckatcs auto l = [arr]{}; 112*e3e9082bSisuckatcs [arr]{}(); 113*e3e9082bSisuckatcs 114*e3e9082bSisuckatcs //FIXME: These should be TRUE. We should avoid calling the destructor 115*e3e9082bSisuckatcs // of the temporary that is materialized as the lambda. 116*e3e9082bSisuckatcs clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}} expected-warning{{FALSE}} 117*e3e9082bSisuckatcs clang_analyzer_eval(S::DtorInvocationCount == 0); //expected-warning{{TRUE}} expected-warning{{FALSE}} 118*e3e9082bSisuckatcs } 119*e3e9082bSisuckatcs 120*e3e9082bSisuckatcs // FIXME: Report a warning if the standard is at least C++17. 121*e3e9082bSisuckatcs #if __cplusplus < 201703L zeroSizeArrayLambdaCaptureUndefined1()122*e3e9082bSisuckatcsvoid zeroSizeArrayLambdaCaptureUndefined1() { 123*e3e9082bSisuckatcs S arr[0]; 124*e3e9082bSisuckatcs int n; 125*e3e9082bSisuckatcs 126*e3e9082bSisuckatcs auto l = [arr, n]{ 127*e3e9082bSisuckatcs int x = n; //expected-warning{{Assigned value is garbage or undefined}} 128*e3e9082bSisuckatcs (void) x; 129*e3e9082bSisuckatcs }; 130*e3e9082bSisuckatcs 131*e3e9082bSisuckatcs l(); 132*e3e9082bSisuckatcs } 133*e3e9082bSisuckatcs #endif 134*e3e9082bSisuckatcs zeroSizeArrayLambdaCaptureUndefined2()135*e3e9082bSisuckatcsvoid zeroSizeArrayLambdaCaptureUndefined2() { 136*e3e9082bSisuckatcs S arr[0]; 137*e3e9082bSisuckatcs int n; 138*e3e9082bSisuckatcs 139*e3e9082bSisuckatcs [arr, n]{ 140*e3e9082bSisuckatcs int x = n; //expected-warning{{Assigned value is garbage or undefined}} 141*e3e9082bSisuckatcs (void) x; 142*e3e9082bSisuckatcs }(); 143*e3e9082bSisuckatcs } 144*e3e9082bSisuckatcs 145*e3e9082bSisuckatcs struct Wrapper{ 146*e3e9082bSisuckatcs S arr[0]; 147*e3e9082bSisuckatcs }; 148*e3e9082bSisuckatcs zeroSizeArrayMember()149*e3e9082bSisuckatcsvoid zeroSizeArrayMember() { 150*e3e9082bSisuckatcs S::CtorInvocationCount = 0; 151*e3e9082bSisuckatcs S::DtorInvocationCount = 0; 152*e3e9082bSisuckatcs 153*e3e9082bSisuckatcs { 154*e3e9082bSisuckatcs Wrapper W; 155*e3e9082bSisuckatcs } 156*e3e9082bSisuckatcs 157*e3e9082bSisuckatcs clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}} 158*e3e9082bSisuckatcs clang_analyzer_eval(S::DtorInvocationCount == 0); //expected-warning{{TRUE}} 159*e3e9082bSisuckatcs } 160*e3e9082bSisuckatcs zeroSizeArrayMemberCopyMove()161*e3e9082bSisuckatcsvoid zeroSizeArrayMemberCopyMove() { 162*e3e9082bSisuckatcs S::CtorInvocationCount = 0; 163*e3e9082bSisuckatcs S::DtorInvocationCount = 0; 164*e3e9082bSisuckatcs 165*e3e9082bSisuckatcs { 166*e3e9082bSisuckatcs Wrapper W; 167*e3e9082bSisuckatcs Wrapper W2 = W; 168*e3e9082bSisuckatcs Wrapper W3 = (Wrapper&&) W2; 169*e3e9082bSisuckatcs } 170*e3e9082bSisuckatcs 171*e3e9082bSisuckatcs clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}} 172*e3e9082bSisuckatcs clang_analyzer_eval(S::DtorInvocationCount == 0); //expected-warning{{TRUE}} 173*e3e9082bSisuckatcs } 174*e3e9082bSisuckatcs 175*e3e9082bSisuckatcs struct MultiWrapper{ 176*e3e9082bSisuckatcs S arr[2][0]; 177*e3e9082bSisuckatcs }; 178*e3e9082bSisuckatcs zeroSizeMultidimensionalArrayMember()179*e3e9082bSisuckatcsvoid zeroSizeMultidimensionalArrayMember() { 180*e3e9082bSisuckatcs S::CtorInvocationCount = 0; 181*e3e9082bSisuckatcs S::DtorInvocationCount = 0; 182*e3e9082bSisuckatcs 183*e3e9082bSisuckatcs { 184*e3e9082bSisuckatcs MultiWrapper MW; 185*e3e9082bSisuckatcs } 186*e3e9082bSisuckatcs 187*e3e9082bSisuckatcs clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}} 188*e3e9082bSisuckatcs clang_analyzer_eval(S::DtorInvocationCount == 0); //expected-warning{{TRUE}} 189*e3e9082bSisuckatcs } 190