aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-decl.c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-08-21 18:34:16 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2020-08-25 21:41:05 -0400
commit2fc201382d3498778934f1262b57acd20f76f300 (patch)
treed7d4041be925e87889af093a4a8aacc4d1c4c1a4 /gcc/fortran/trans-decl.c
parentd88c8df70342fcd6817e23f243ff38d0fe42fc6b (diff)
downloadgcc-2fc201382d3498778934f1262b57acd20f76f300.zip
gcc-2fc201382d3498778934f1262b57acd20f76f300.tar.gz
gcc-2fc201382d3498778934f1262b57acd20f76f300.tar.bz2
analyzer: fix leak false positive/widening on pointer iteration [PR94858]
PR analyzer/94858 reports a false diagnostic from -Wanalyzer-malloc-leak, where the allocated pointer is pointed to by a field of a struct, and a loop writes to a buffer, writing through an iterating pointer value. There were several underlying problems, relating to clobbering of the struct holding the malloc-ed pointer; in each case the analyzer was conservatively assuming that a write could affect this region, clobbering it to "unknown", and this was detected as a leak. The initial write within the loop dereferences the initial value of a field, and the analyzer was assuming that that pointer could point to the result of the malloc call. The patch extends store::eval_alias_1 so that it "knows" that the initial value of a pointer at the beginning of a path can't point to a region that was allocated on the heap after the beginning of the path. On fixing that, the next issue is that within the loop the iterated pointer value becomes "unknown", and hence *ptr becomes a write to a symbolic region, and thus might clobber the struct (which it can't). This patch adds enough logic to svalue::can_merge_p to merge the iterating pointer value so that at the 2nd iteration analyzing the loop it becomes a widening_svalue from the initial svalue, so that this becomes a fixed point of the analysis, and is not an unknown_svalue. The patch further extends store::eval_alias_1 so that it "knows" that this widening_svalue can only point to the same base region as the initial value did; in particular, symbolic writes through this pointer can only clobber that base region, not the struct holding the malloc-ed pointer. gcc/analyzer/ChangeLog: PR analyzer/94858 * region-model-manager.cc (region_model_manager::get_or_create_widening_svalue): Assert that neither of the inputs are themselves widenings. * store.cc (store::eval_alias_1): The initial value of a pointer can't point to a region that was allocated on the heap after the beginning of the path. A widened pointer value can't alias anything that the initial pointer value can't alias. * svalue.cc (svalue::can_merge_p): Merge BINOP (X, OP, CST) with X to a widening svalue. Merge BINOP(WIDENING(BASE, BINOP(BASE, X)), X) and BINOP(BASE, X) to to the LHS of the first BINOP. gcc/testsuite/ChangeLog: PR analyzer/94858 * gcc.dg/analyzer/loop-start-up-to-end-by-1.c: Remove xfail. * gcc.dg/analyzer/pr94858-1.c: New test. * gcc.dg/analyzer/pr94858-2.c: New test. * gcc.dg/analyzer/torture/loop-inc-ptr-2.c: Update expected number of enodes. * gcc.dg/analyzer/torture/loop-inc-ptr-3.c: Likewise.
Diffstat (limited to 'gcc/fortran/trans-decl.c')
0 files changed, 0 insertions, 0 deletions