diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1394,15 +1394,11 @@ // If we have an expression that provided the value, try to track where it // came from. if (InitE) { - if (V.isUndef() || - V.getAs() || V.getAs()) { - if (!IsParam) - InitE = InitE->IgnoreParenCasts(); - bugreporter::trackExpressionValue(StoreSite, InitE, BR, - EnableNullFPSuppression); - } - ReturnVisitor::addVisitorIfNecessary(StoreSite, InitE->IgnoreParenCasts(), - BR, EnableNullFPSuppression); + if (!IsParam) + InitE = InitE->IgnoreParenCasts(); + + bugreporter::trackExpressionValue(StoreSite, InitE, BR, + EnableNullFPSuppression); } // Okay, we've found the binding. Emit an appropriate message. @@ -1945,19 +1941,20 @@ // We should not try to dereference pointers at all when we don't care // what is written inside the pointer. bool CanDereference = true; - if (const auto *SR = dyn_cast(L->getRegion())) + if (const auto *SR = L->getRegionAs()) { if (SR->getSymbol()->getType()->getPointeeType()->isVoidType()) CanDereference = false; + } else if (const auto *AR = L->getRegionAs()) + CanDereference = false; // At this point we are dealing with the region's LValue. // However, if the rvalue is a symbolic region, we should track it as well. // Try to use the correct type when looking up the value. SVal RVal; - if (ExplodedGraph::isInterestingLValueExpr(Inner)) { + if (ExplodedGraph::isInterestingLValueExpr(Inner)) RVal = LVState->getRawSVal(L.getValue(), Inner->getType()); - } else if (CanDereference) { + else if (CanDereference) RVal = LVState->getSVal(L->getRegion()); - } if (CanDereference) if (auto KV = RVal.getAs()) diff --git a/clang/test/Analysis/track-control-dependency-conditions.cpp b/clang/test/Analysis/track-control-dependency-conditions.cpp --- a/clang/test/Analysis/track-control-dependency-conditions.cpp +++ b/clang/test/Analysis/track-control-dependency-conditions.cpp @@ -366,6 +366,30 @@ } } // end of namespace tracked_condition_written_in_nested_stackframe +namespace condition_written_in_nested_stackframe_before_assignment { +int flag = 0; +int getInt(); + +void foo() { + flag = getInt(); // tracking-note{{Value assigned to 'flag'}} +} + +void f() { + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + int y = 0; + + foo(); // tracking-note{{Calling 'foo'}} + // tracking-note@-1{{Returning from 'foo'}} + y = flag; // tracking-note{{Value assigned to 'y'}} + + if (y) // expected-note{{Assuming 'y' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'y'}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // end of namespace condition_written_in_nested_stackframe_before_assignment + namespace collapse_point_not_in_condition { [[noreturn]] void halt(); diff --git a/clang/test/Analysis/uninit-const.c b/clang/test/Analysis/uninit-const.c --- a/clang/test/Analysis/uninit-const.c +++ b/clang/test/Analysis/uninit-const.c @@ -24,15 +24,15 @@ void doStuff_variadic(const int *u, ...){}; void f_1(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int* tp = &t; // expected-note {{'tp' initialized here}} doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } void f_1_1(void) { - int t; - int* tp1 = &t; + int t; // expected-note {{'t' declared without an initial value}} + int *tp1 = &t; // expected-note {{'tp1' initialized here}} int* tp2 = tp1; // expected-note {{'tp2' initialized here}} doStuff_pointerToConstInt(tp2); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} @@ -40,12 +40,15 @@ int *f_2_sub(int *p) { - return p; + return p; // expected-note {{Returning pointer (loaded from 'p')}} } void f_2(void) { - int t; - int* p = f_2_sub(&t); + int t; // expected-note {{'t' declared without an initial value}} + int *p = f_2_sub(&t); // expected-note {{Passing value via 1st parameter 'p'}} + // expected-note@-1{{Calling 'f_2_sub'}} + // expected-note@-2{{Returning from 'f_2_sub'}} + // expected-note@-3{{'p' initialized here}} int* tp = p; // expected-note {{'tp' initialized here}} doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} @@ -62,7 +65,7 @@ } void f_5(void) { - int ta[5]; + int ta[5]; // expected-note {{'ta' initialized here}} int* tp = ta; // expected-note {{'tp' initialized here}} doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} @@ -99,7 +102,7 @@ } void f_9(void) { - int a[6]; + int a[6]; // expected-note {{'a' initialized here}} int const *ptau = a; // expected-note {{'ptau' initialized here}} doStuff_arrayOfConstInt(ptau); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} @@ -173,7 +176,7 @@ // uninit pointer, uninit val void f_variadic_unp_unv(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int v; int* tp = &t; // expected-note {{'tp' initialized here}} doStuff_variadic(tp,v); // expected-warning {{1st function call argument is a pointer to uninitialized value}} @@ -181,7 +184,7 @@ } // uninit pointer, init val void f_variadic_unp_inv(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int v = 3; int* tp = &t; // expected-note {{'tp' initialized here}} doStuff_variadic(tp,v); // expected-warning {{1st function call argument is a pointer to uninitialized value}} @@ -216,7 +219,7 @@ //uninit pointer, init pointer void f_variadic_unp_inp(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int u=3; int *vp = &u ; int *tp = &t; // expected-note {{'tp' initialized here}} @@ -235,7 +238,7 @@ //uninit pointer, uninit pointer void f_variadic_unp_unp(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int u; int *vp = &u ; int *tp = &t; // expected-note {{'tp' initialized here}} diff --git a/clang/test/Analysis/uninit-const.cpp b/clang/test/Analysis/uninit-const.cpp --- a/clang/test/Analysis/uninit-const.cpp +++ b/clang/test/Analysis/uninit-const.cpp @@ -66,8 +66,8 @@ void f6_2(void) { int t; //expected-note {{'t' declared without an initial value}} - int &p = t; - int &s = p; + int &p = t; //expected-note {{'p' initialized here}} + int &s = p; //expected-note {{'s' initialized here}} int &q = s; //expected-note {{'q' initialized here}} doStuff6(q); //expected-warning {{1st function call argument is an uninitialized value}} //expected-note@-1 {{1st function call argument is an uninitialized value}} @@ -96,7 +96,7 @@ void f5(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int* tp = &t; // expected-note {{'tp' initialized here}} doStuff_uninit(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}