Skip to content

Model implicit pointer-to-array dereferences as nil consumers#423

Open
TvdW wants to merge 1 commit into
uber-go:mainfrom
TvdW:pointer-to-array
Open

Model implicit pointer-to-array dereferences as nil consumers#423
TvdW wants to merge 1 commit into
uber-go:mainfrom
TvdW:pointer-to-array

Conversation

@TvdW

@TvdW TvdW commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Slicing, indexing, and 2-variable ranging over a *[N]T implicitly dereference the pointer (e.g. p[low:high] is shorthand for (*p)[low:high]), so they panic on a nil pointer. Notably this holds even for slice forms like p[:0] and p[:] that are safe on a nil slice. len/cap and range loops with at most one (possibly blank) iteration variable never read the elements and stay nil-safe.

Add PtrLoad consumers for these cases in consumeIndexExpr, the SliceExpr case of AddComputation (bypassing the slice-only safe-slicing carve-out), and case 2 of backpropAcrossRange.

Claude-assisted, human-reviewed.

@TvdW
TvdW force-pushed the pointer-to-array branch from 2ccab67 to 19bc060 Compare June 17, 2026 19:20
@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.69%. Comparing base (5c662b7) to head (9a3820b).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #423      +/-   ##
==========================================
+ Coverage   86.66%   86.69%   +0.02%     
==========================================
  Files          76       76              
  Lines        8750     8769      +19     
==========================================
+ Hits         7583     7602      +19     
  Misses        945      945              
  Partials      222      222              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Slicing, indexing, and 2-variable ranging over a *[N]T implicitly
dereference the pointer (e.g. p[low:high] is shorthand for
(*p)[low:high]), so they panic on a nil pointer. Notably this holds
even for slice forms like p[:0] and p[:] that are safe on a nil
slice. len/cap and range loops with at most one (possibly blank)
iteration variable never read the elements and stay nil-safe.

Add PtrLoad consumers for these cases in consumeIndexExpr, the
SliceExpr case of AddComputation (bypassing the slice-only safe-slicing
carve-out), and case 2 of backpropAcrossRange.
@TvdW
TvdW force-pushed the pointer-to-array branch from bf388ba to 9a3820b Compare July 7, 2026 20:13
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Golden Test

Warning

❌ NilAway errors reported on stdlib are different 📈.

2176 errors on base branch (main, 5c662b7)
2198 errors on test branch (efaf143)

Diffs
+ /opt/hostedtoolcache/go/1.25.11/x64/src/crypto/internal/fips140/drbg/ctrdrbg.go:101:27: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- fips140test/acvp_test.go:1732:18: unassigned variable `reseedEntropy` passed as arg `entropy` to `Reseed()`
+ 	- drbg/ctrdrbg.go:101:27: function parameter `entropy` dereferenced
+ /opt/hostedtoolcache/go/1.25.11/x64/src/crypto/internal/fips140/drbg/ctrdrbg.go:101:39: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- fips140test/acvp_test.go:1732:33: unassigned variable `reseedAd` passed as arg `additionalInput` to `Reseed()`
+ 	- drbg/ctrdrbg.go:101:39: function parameter `additionalInput` dereferenced
+ /opt/hostedtoolcache/go/1.25.11/x64/src/crypto/internal/fips140/nistec/p224.go:434:3: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- nistec/p224.go:386:5: nilable value assigned into global variable `p224GeneratorTable`
+ 	- nistec/p224.go:407:9: global variable `p224GeneratorTable` returned from `generatorTable()` in position 0
+ 	- nistec/p224.go:434:3: result 0 of `generatorTable()` dereferenced via the assignment(s):
+ 		- `p.generatorTable()` to `tables` at nistec/p224.go:416:2
+ /opt/hostedtoolcache/go/1.25.11/x64/src/crypto/internal/fips140/nistec/p224_sqrt.go:130:23: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- nistec/p224_sqrt.go:12:5: nilable value assigned into global variable `p224GG`
+ 	- nistec/p224_sqrt.go:130:23: global variable `p224GG` dereferenced
+ /opt/hostedtoolcache/go/1.25.11/x64/src/crypto/internal/fips140/nistec/p256_asm.go:655:26: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- nistec/p256_asm.go:329:5: nilable value assigned into global variable `p256Precomputed`
+ 	- nistec/p256_asm.go:655:26: global variable `p256Precomputed` dereferenced
+ /opt/hostedtoolcache/go/1.25.11/x64/src/crypto/internal/fips140/nistec/p384.go:434:3: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- nistec/p384.go:386:5: nilable value assigned into global variable `p384GeneratorTable`
+ 	- nistec/p384.go:407:9: global variable `p384GeneratorTable` returned from `generatorTable()` in position 0
+ 	- nistec/p384.go:434:3: result 0 of `generatorTable()` dereferenced via the assignment(s):
+ 		- `p.generatorTable()` to `tables` at nistec/p384.go:416:2
+ /opt/hostedtoolcache/go/1.25.11/x64/src/crypto/internal/fips140/nistec/p521.go:434:3: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- nistec/p521.go:386:5: nilable value assigned into global variable `p521GeneratorTable`
+ 	- nistec/p521.go:407:9: global variable `p521GeneratorTable` returned from `generatorTable()` in position 0
+ 	- nistec/p521.go:434:3: result 0 of `generatorTable()` dereferenced via the assignment(s):
+ 		- `p.generatorTable()` to `tables` at nistec/p521.go:416:2
+ /opt/hostedtoolcache/go/1.25.11/x64/src/hash/crc32/crc32_amd64.go:82:3: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- crc32/crc32_amd64.go:46:5: nilable value assigned into global variable `castagnoliSSE42TableK1`
+ 	- crc32/crc32_amd64.go:187:25: global variable `castagnoliSSE42TableK1` passed as arg `table` to `castagnoliShift()`
+ 	- crc32/crc32_amd64.go:82:3: function parameter `table` dereferenced
+ /opt/hostedtoolcache/go/1.25.11/x64/src/hash/crc32/crc32_amd64.go:82:3: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- crc32/crc32_amd64.go:47:5: nilable value assigned into global variable `castagnoliSSE42TableK2`
+ 	- crc32/crc32_amd64.go:172:25: global variable `castagnoliSSE42TableK2` passed as arg `table` to `castagnoliShift()`
+ 	- crc32/crc32_amd64.go:82:3: function parameter `table` dereferenced
+ /opt/hostedtoolcache/go/1.25.11/x64/src/hash/crc32/crc32_generic.go:47:9: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- crc32/crc32.go:78:5: nilable value assigned into global variable `castagnoliTable`
+ 	- crc32/crc32.go:129:10: global variable `castagnoliTable` returned from `MakeTable()` in position 0
+ 	- crc32/example_test.go:25:61: result 0 of `MakeTable()` passed as arg `tab` to `Checksum()` via the assignment(s):
+ 		- `crc32.MakeTable(...)` to `crc32q` at crc32/example_test.go:24:2
+ 	- crc32/crc32.go:239:66: function parameter `tab` passed as arg `tab` to `Update()`
+ 	- crc32/crc32.go:220:21: function parameter `tab` passed as arg `tab` to `update()`
+ 	- crc32/crc32.go:212:28: function parameter `tab` passed as arg `tab` to `simpleUpdate()`
+ 	- crc32/crc32_generic.go:47:9: function parameter `tab` dereferenced
+ /opt/hostedtoolcache/go/1.25.11/x64/src/hash/crc32/crc32_generic.go:90:28: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- crc32/crc32_amd64.go:2

 ...(truncated)...

lue assigned into global variable `slicing8TableECMA`
+ 	- crc64/crc64.go:52:11: global variable `slicing8TableECMA` dereferenced
+ /opt/hostedtoolcache/go/1.25.11/x64/src/internal/trace/internal/tracev1/parser.go:294:10: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- tracev1/parser.go:340:18: literal `nil` assigned deeply into field `buckets`
+ 	- tracev1/parser.go:294:10: deep read from field `buckets` dereferenced
+ /opt/hostedtoolcache/go/1.25.11/x64/src/math/j0.go:324:7: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- math/j0.go:324:7: unassigned variable `p` dereferenced
+ 
+ (Same nil source could also cause potential nil panic(s) at 5 other place(s): "math/j0.go:324:17", "math/j0.go:324:25", "math/j0.go:324:33", "math/j0.go:324:41", and "math/j0.go:324:48".)
+ /opt/hostedtoolcache/go/1.25.11/x64/src/math/j0.go:325:14: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- math/j0.go:325:14: unassigned variable `q` dereferenced
+ 
+ (Same nil source could also cause potential nil panic(s) at 4 other place(s): "math/j0.go:325:22", "math/j0.go:325:30", "math/j0.go:325:38", and "math/j0.go:325:45".)
+ /opt/hostedtoolcache/go/1.25.11/x64/src/math/j0.go:426:7: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- math/j0.go:426:7: unassigned variable `p` dereferenced
+ 
+ (Same nil source could also cause potential nil panic(s) at 5 other place(s): "math/j0.go:426:17", "math/j0.go:426:25", "math/j0.go:426:33", "math/j0.go:426:41", and "math/j0.go:426:48".)
+ /opt/hostedtoolcache/go/1.25.11/x64/src/math/j0.go:427:14: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- math/j0.go:427:14: unassigned variable `q` dereferenced
+ 
+ (Same nil source could also cause potential nil panic(s) at 5 other place(s): "math/j0.go:427:22", "math/j0.go:427:30", "math/j0.go:427:38", "math/j0.go:427:46", and "math/j0.go:427:53".)
+ /opt/hostedtoolcache/go/1.25.11/x64/src/math/j1.go:319:7: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- math/j1.go:319:7: unassigned variable `p` dereferenced
+ 
+ (Same nil source could also cause potential nil panic(s) at 5 other place(s): "math/j1.go:319:17", "math/j1.go:319:25", "math/j1.go:319:33", "math/j1.go:319:41", and "math/j1.go:319:48".)
+ /opt/hostedtoolcache/go/1.25.11/x64/src/math/j1.go:320:16: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- math/j1.go:320:16: unassigned variable `q` dereferenced
+ 
+ (Same nil source could also cause potential nil panic(s) at 4 other place(s): "math/j1.go:320:24", "math/j1.go:320:32", "math/j1.go:320:40", and "math/j1.go:320:47".)
+ /opt/hostedtoolcache/go/1.25.11/x64/src/math/j1.go:421:7: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- math/j1.go:421:7: unassigned variable `p` dereferenced
+ 
+ (Same nil source could also cause potential nil panic(s) at 5 other place(s): "math/j1.go:421:17", "math/j1.go:421:25", "math/j1.go:421:33", "math/j1.go:421:41", and "math/j1.go:421:48".)
+ /opt/hostedtoolcache/go/1.25.11/x64/src/math/j1.go:422:14: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- math/j1.go:422:14: unassigned variable `q` dereferenced
+ 
+ (Same nil source could also cause potential nil panic(s) at 5 other place(s): "math/j1.go:422:22", "math/j1.go:422:30", "math/j1.go:422:38", "math/j1.go:422:46", and "math/j1.go:422:53".)
+ /opt/hostedtoolcache/go/1.25.11/x64/src/runtime/mpagealloc.go:353:10: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- runtime/export_test.go:1084:18: literal `nil` assigned deeply into field `chunks`
+ 	- runtime/mpagealloc.go:353:10: deep read from field `chunks` dereferenced
+ /opt/hostedtoolcache/go/1.25.11/x64/src/runtime/vdso_linux.go:178:14: Potential nil panic detected. Observed nil flow from source to dereference point: 
+ 	- runtime/vdso_linux.go:178:14: unassigned variable `hash` dereferenced
+ 
+ (Same nil source could also cause potential nil panic(s) at 3 other place(s): "runtime/vdso_linux.go:179:13", "runtime/vdso_linux.go:180:17", and "runtime/vdso_linux.go:181:16".)
- /opt/hostedtoolcache/go/1.25.11/x64/src/runtime/mpagealloc.go:475:60: Potential nil panic detected. Observed nil flow from source to dereference point: 
- 	- runtime/export_test.go:1084:18: literal `nil` assigned deeply into field `chunks`
- 	- runtime/mpagealloc.go:475:60: deep read from field `chunks` dereferenced
- /opt/hostedtoolcache/go/1.25.11/x64/src/runtime/vdso_linux.go:180:17: Potential nil panic detected. Observed nil flow from source to dereference point: 
- 	- runtime/vdso_linux.go:180:17: unassigned variable `hash` sliced into
- 
- (Same nil source could also cause potential nil panic(s) at 1 other place(s): "runtime/vdso_linux.go:181:16".)

@TvdW

TvdW commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

In my defense, the golden test 📈 means the code works 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant