168ee5ec0SMarco Antognini // RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s 268ee5ec0SMarco Antognini 368ee5ec0SMarco Antognini // This tests false-positive issues related to PR48534. 468ee5ec0SMarco Antognini // 568ee5ec0SMarco Antognini // Essentially, having a default member initializer for a constant member does 668ee5ec0SMarco Antognini // not necessarily imply the member will have the given default value. 768ee5ec0SMarco Antognini 868ee5ec0SMarco Antognini struct WithConstructor { 968ee5ec0SMarco Antognini int *const ptr = nullptr; WithConstructorWithConstructor1068ee5ec0SMarco Antognini WithConstructor(int *x) : ptr(x) {} 1168ee5ec0SMarco Antognini compliantWithConstructor1268ee5ec0SMarco Antognini static auto compliant() { 13*a504ddc8SKristóf Umann WithConstructor c(new int{}); 1468ee5ec0SMarco Antognini return *(c.ptr); // no warning 1568ee5ec0SMarco Antognini } 1668ee5ec0SMarco Antognini compliantWithParamWithConstructor1768ee5ec0SMarco Antognini static auto compliantWithParam(WithConstructor c) { 1868ee5ec0SMarco Antognini return *(c.ptr); // no warning 1968ee5ec0SMarco Antognini } 2068ee5ec0SMarco Antognini issueWithConstructor2168ee5ec0SMarco Antognini static auto issue() { 2268ee5ec0SMarco Antognini WithConstructor c(nullptr); 2368ee5ec0SMarco Antognini return *(c.ptr); // expected-warning{{Dereference of null pointer (loaded from field 'ptr')}} 2468ee5ec0SMarco Antognini } 2568ee5ec0SMarco Antognini }; 2668ee5ec0SMarco Antognini 2768ee5ec0SMarco Antognini struct RegularAggregate { 2868ee5ec0SMarco Antognini int *const ptr = nullptr; 2968ee5ec0SMarco Antognini compliantRegularAggregate3068ee5ec0SMarco Antognini static int compliant() { 31*a504ddc8SKristóf Umann RegularAggregate c{new int{}}; 3268ee5ec0SMarco Antognini return *(c.ptr); // no warning 3368ee5ec0SMarco Antognini } 3468ee5ec0SMarco Antognini issueRegularAggregate3568ee5ec0SMarco Antognini static int issue() { 3668ee5ec0SMarco Antognini RegularAggregate c; 3768ee5ec0SMarco Antognini return *(c.ptr); // expected-warning{{Dereference of null pointer (loaded from field 'ptr')}} 3868ee5ec0SMarco Antognini } 3968ee5ec0SMarco Antognini }; 4068ee5ec0SMarco Antognini 4168ee5ec0SMarco Antognini struct WithConstructorAndArithmetic { 4268ee5ec0SMarco Antognini int const i = 0; WithConstructorAndArithmeticWithConstructorAndArithmetic4368ee5ec0SMarco Antognini WithConstructorAndArithmetic(int x) : i(x + 1) {} 4468ee5ec0SMarco Antognini compliantWithConstructorAndArithmetic4568ee5ec0SMarco Antognini static int compliant(int y) { 4668ee5ec0SMarco Antognini WithConstructorAndArithmetic c(0); 4768ee5ec0SMarco Antognini return y / c.i; // no warning 4868ee5ec0SMarco Antognini } 4968ee5ec0SMarco Antognini issueWithConstructorAndArithmetic5068ee5ec0SMarco Antognini static int issue(int y) { 5168ee5ec0SMarco Antognini WithConstructorAndArithmetic c(-1); 5268ee5ec0SMarco Antognini return y / c.i; // expected-warning{{Division by zero}} 5368ee5ec0SMarco Antognini } 5468ee5ec0SMarco Antognini }; 5568ee5ec0SMarco Antognini 5668ee5ec0SMarco Antognini struct WithConstructorDeclarationOnly { 5768ee5ec0SMarco Antognini int const i = 0; 5868ee5ec0SMarco Antognini WithConstructorDeclarationOnly(int x); // definition not visible. 5968ee5ec0SMarco Antognini compliant1WithConstructorDeclarationOnly6068ee5ec0SMarco Antognini static int compliant1(int y) { 6168ee5ec0SMarco Antognini WithConstructorDeclarationOnly c(0); 6268ee5ec0SMarco Antognini return y / c.i; // no warning 6368ee5ec0SMarco Antognini } 6468ee5ec0SMarco Antognini compliant2WithConstructorDeclarationOnly6568ee5ec0SMarco Antognini static int compliant2(int y) { 6668ee5ec0SMarco Antognini WithConstructorDeclarationOnly c(-1); 6768ee5ec0SMarco Antognini return y / c.i; // no warning 6868ee5ec0SMarco Antognini } 6968ee5ec0SMarco Antognini }; 7068ee5ec0SMarco Antognini 7168ee5ec0SMarco Antognini // NonAggregateFP is not an aggregate (j is a private non-static field) and has no custom constructor. 7268ee5ec0SMarco Antognini // So we know i and j will always be 0 and 42, respectively. 7368ee5ec0SMarco Antognini // That being said, this is not implemented because it is deemed too rare to be worth the complexity. 7468ee5ec0SMarco Antognini struct NonAggregateFP { 7568ee5ec0SMarco Antognini public: 7668ee5ec0SMarco Antognini int const i = 0; 7768ee5ec0SMarco Antognini 7868ee5ec0SMarco Antognini private: 7968ee5ec0SMarco Antognini int const j = 42; 8068ee5ec0SMarco Antognini 8168ee5ec0SMarco Antognini public: falsePositive1NonAggregateFP8268ee5ec0SMarco Antognini static int falsePositive1(NonAggregateFP c) { 8368ee5ec0SMarco Antognini return 10 / c.i; // FIXME: Currently, no warning. 8468ee5ec0SMarco Antognini } 8568ee5ec0SMarco Antognini falsePositive2NonAggregateFP8668ee5ec0SMarco Antognini static int falsePositive2(NonAggregateFP c) { 8768ee5ec0SMarco Antognini return 10 / (c.j - 42); // FIXME: Currently, no warning. 8868ee5ec0SMarco Antognini } 8968ee5ec0SMarco Antognini }; 9068ee5ec0SMarco Antognini 9168ee5ec0SMarco Antognini struct NonAggregate { 9268ee5ec0SMarco Antognini public: 9368ee5ec0SMarco Antognini int const i = 0; 9468ee5ec0SMarco Antognini 9568ee5ec0SMarco Antognini private: 9668ee5ec0SMarco Antognini int const j = 42; 9768ee5ec0SMarco Antognini 9868ee5ec0SMarco Antognini NonAggregate(NonAggregate const &); // not provided, could set i and j to arbitrary values. 9968ee5ec0SMarco Antognini 10068ee5ec0SMarco Antognini public: compliant1NonAggregate10168ee5ec0SMarco Antognini static int compliant1(NonAggregate c) { 10268ee5ec0SMarco Antognini return 10 / c.i; // no warning 10368ee5ec0SMarco Antognini } 10468ee5ec0SMarco Antognini compliant2NonAggregate10568ee5ec0SMarco Antognini static int compliant2(NonAggregate c) { 10668ee5ec0SMarco Antognini return 10 / (c.j - 42); // no warning 10768ee5ec0SMarco Antognini } 10868ee5ec0SMarco Antognini }; 10968ee5ec0SMarco Antognini 11068ee5ec0SMarco Antognini struct WithStaticMember { 11168ee5ec0SMarco Antognini static int const i = 0; 11268ee5ec0SMarco Antognini issue1WithStaticMember11368ee5ec0SMarco Antognini static int issue1(WithStaticMember c) { 11468ee5ec0SMarco Antognini return 10 / c.i; // expected-warning{{division by zero is undefined}} expected-warning{{Division by zero}} 11568ee5ec0SMarco Antognini } 11668ee5ec0SMarco Antognini issue2WithStaticMember11768ee5ec0SMarco Antognini static int issue2() { 11868ee5ec0SMarco Antognini return 10 / WithStaticMember::i; // expected-warning{{division by zero is undefined}} expected-warning{{Division by zero}} 11968ee5ec0SMarco Antognini } 12068ee5ec0SMarco Antognini }; 121