[dead stores] don't warn on likely-harmless dead stores to default values

Reviewed By: jberdine

Differential Revision: D6223991

fbshipit-source-id: ff53e8b
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 0a1971a08d
commit ad522a8b19

@ -73,12 +73,23 @@ let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary =
let invariant_map =
Analyzer.exec_cfg cfg (ProcData.make_default proc_desc tenv) ~initial:Domain.empty ~debug:true
in
(* we don't want to report in harmless cases like int i = 0; if (...) { i = ... } else { i = ... }
that create an intentional dead store as an attempt to imitate default value semantics.
use dead stores to a "sentinel" value as a heuristic for ignoring this case *)
let is_sentinel_exp = function
| Exp.Const Cint i ->
IntLit.iszero i || IntLit.isnull i
| Exp.Const Cfloat 0.0 ->
true
| _ ->
false
in
let report_dead_store live_vars = function
| Sil.Store (Lvar pvar, _, _, loc)
| Sil.Store (Lvar pvar, _, rhs_exp, loc)
when not
( Pvar.is_frontend_tmp pvar || Pvar.is_return pvar || Pvar.is_global pvar
|| Domain.mem (Var.of_pvar pvar) live_vars || Procdesc.is_captured_var proc_desc pvar
|| is_whitelisted_var pvar ) ->
|| is_whitelisted_var pvar || is_sentinel_exp rhs_exp ) ->
let issue_id = IssueType.dead_store.unique_id in
let message = F.asprintf "The value written to %a is never used" (Pvar.pp Pp.text) pvar in
let ltr = [Errlog.make_trace_element 0 loc "Write of unused value" []] in

@ -34,37 +34,37 @@ void dead_pointer_bad() {
}
void plus_plus1_bad() {
int i = 0;
int i = 1;
++i;
}
void plus_plus2_bad() {
int i = 0;
int i = 1;
i++;
}
int plus_plus3_bad() {
int i = 0;
int i = 1;
return i++;
}
void FN_capture_no_read_bad() {
int x = 0;
int x = 1;
[x]() { return; }();
}
void init_capture_reassign_bad() {
int i = 0; // this is a dead store
return [i = 0]() { return i; }
int i = 1; // this is a dead store
return [i = 1]() { return i; }
();
}
void init_capture_no_call_bad() {
[i = 0]() { return i; };
[i = 1]() { return i; };
}
int FN_init_capture_no_read_bad() {
return [i = 0]() { return 0; }
return [i = 1]() { return 0; }
();
}
@ -125,19 +125,19 @@ void by_ref1_ok(int& ref) { ref = 7; }
void by_ref2_ok(int& ref) { ref++; }
int capture_by_ref3_ok() {
int x = 0;
int x = 1;
[&](auto y) { x += y; }(3);
return x;
}
int plus_plus_ok() {
int x = 0;
int x = 1;
return ++x;
}
int plus_plus_loop_ok(int n) {
int i;
for (i = 0; i < n; i++) {
for (i = 1; i < n; i++) {
i++;
}
return i;
@ -162,14 +162,14 @@ void capture2_ok(int x) {
}
int capture_by_ref1_ok() {
int x = 0;
int x = 1;
[&x]() { x++; }();
return x;
}
int capture_by_ref2_ok() {
int x = 0;
int y = 0;
int x = 1;
int y = 1;
[&]() {
x = x + y;
y = x;
@ -178,7 +178,7 @@ int capture_by_ref2_ok() {
}
int FN_capture_by_ref_reuseBad() {
int x = 0;
int x = 1;
[&x]() {
x = 1; // dead, but we won't report
x = 2;
@ -187,31 +187,31 @@ int FN_capture_by_ref_reuseBad() {
}
int init_capture1_ok() {
return [i = 0]() { return i; }
return [i = 1]() { return i; }
();
}
int init_capture2_ok() {
int i = 0;
int i = 1;
return [j = i]() { return j; }
();
}
int init_capture3_ok() {
int i = 0;
int i = 1;
return [i = i]() { return i; }
();
}
int init_capture4_ok() {
int i = 0;
int j = 0;
return [ a = 0, b = i, c = j ]() { return a + b + c; }
int i = 1;
int j = 1;
return [ a = 1, b = i, c = j ]() { return a + b + c; }
();
}
int init_capture5_ok() {
int i = 0;
int i = 1;
int k = [j = i]() { return j; }
();
i = 5; // should not be flagged
@ -219,7 +219,7 @@ int init_capture5_ok() {
}
int init_capture6_ok() {
int i = 0;
int i = 1;
int k = [i = i + 1]() { return i; }
();
i = 5; // should not be flagged;
@ -242,4 +242,42 @@ void placement_new_ok(int len, int* ptr) {
}
}
// we don't report on dead stores where the RHS is 0, 0.0, false, nullptr, etc.
bool sentinel_bool_ok() {
bool b = false;
b = true;
return b;
}
int sentinel_int_ok() {
int i = 0;
i = 1;
return i;
}
int sentinel_long_ok() {
long l = 0L;
l = 1L;
return l;
}
float sentinel_float_ok() {
float f = 0.0;
f = 1.0;
return f;
}
double sentinel_double_ok() {
double d = 0.0;
d = 1.0;
return d;
}
int* sentinel_ptr_ok(int* j) {
int* i = nullptr;
i = j;
return i;
}
}

Loading…
Cancel
Save