https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124574

            Bug ID: 124574
           Summary: sparseset_bit_p causes valgrind false positives on
                    non-annotated compiler builds
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: albert at tugraz dot at
  Target Milestone: ---

Direct valgrind on the compiler binary still reports sparse-set false positives
on normal GCC builds that were not configured with
--enable-valgrind-annotations.

Current trunk evidence:
- trunk added gcc/testsuite/sparseset.supp in commit
ac750f1b7f473f206ad5620fb46bbd3282968880 because a valgrind-wrapped test needed
to suppress sparseset warnings
- on my local GCC 16 trunk build without --enable-valgrind-annotations, direct
memcheck on f951 reports errors in sparseset_bit_p for simple Fortran inputs

Typical reproducer:
  valgrind --tool=memcheck --track-origins=yes --error-limit=no -s ./gcc/f951
hello.f90

Observed before patch on a non-annotated trunk build:
- hello world: 161 errors from 28 contexts
- PR84779 mixed-ENTRY reducer: 358 errors from 28 contexts
- gfortran.fortran-torture/execute/entry_4.f90: 3031 errors from 38 contexts

The stacks land in sparseset_bit_p, reached from IRA/LRA.

Root cause:
- sparseset_bit_p reads sparse[e] before it can prove whether E is a member
- the sparse index vector is left uninitialized unless the compiler was built
with valgrind annotations enabled, or unless sparse-set storage is fully
cleared
- this is logically harmless because membership is still validated against
members and dense[idx], but it is not valgrind-clean on ordinary builds

Historical context:
- PR33796 changed sparseset_alloc to use clearing allocation in 2008
- commit a9c283a506663a1bb97330a609a3c443043424b1 switched back to non-clearing
allocation in 2012 and relied on valgrind annotations
- there is older bug history around the same symptom, e.g. PR55290 and PR78454

Proposed fix:
- initialize only the sparse index vector once in sparseset_alloc
- keep the dense vector non-cleared so sparseset_clear remains O(1)
- keep the valgrind annotation for the sparseset header

With the attached patch, the same non-annotated build becomes clean for the
three cases above:
- hello world: 0 errors from 0 contexts
- PR84779 reducer: 0 errors from 0 contexts
- entry_4.f90: 0 errors from 0 contexts

Reply via email to