fix: initialize c_options in the Stimulus type definition - #2792
Conversation
The `PAGERANKOPT` type declares an optional `INOUT` argument, so Stimulus wraps its input conversion into `if (!Rf_isNull(options))`, but passes the pointer to `igraph_pagerank()` unconditionally. Reading it when `options` is `NULL` at the R level is an uninitialized read, flagged by `clang -Wsometimes-uninitialized`. Declare the pointer with a `NULL` initializer via `CDECL`, which is the same fix as in #2751 but applied to the code generator. The `else` branch of the input conversion becomes redundant and is dropped, so the default lives in one place only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RF5eavxtBTfTSquRjc2San
I'm curious what Claude is doing internally to manage a stacked chain, is it anything formal? or it's just keeping track of it "manually"? E.g. keeping a clone of my forked branch to use as a base here would be natural but Claude doesn't. (fwiw I've become quite fond of jj lately) |
|
I just requested a stacked PR and it figured it out. Using Claude Code Web which has some restrictions. Do you mean https://github.com/jj-vcs/jj? This does look interesting. What do you like about it? Are we losing any features under this abstraction, or can we always drop to the underlying layer? |
The language for moving commits around on a tree feels pretty natural to me, as does the syntax for describing revsets ( I also use more than one VCS day-to-day and being able to use the more-or-less the same syntax is quite a relief.
For my own workflows, I'm still adapting, but I basically use git like (1) plain old git for simple branches, one bug fix, a simple feature, etc; or (2) fully The interaction with GitHub is still a bit awkward, but it's a bit a limitation of
Is that the new GitHub stacked PRs feature (link)? I haven't gotten a chance to try that out yet. |
|
I just signed up for the stacked PRs preview. Claude also force-pushes a lot under my guidance. I use Git pretty much exclusively and am not ready to embrace a new mental model. For newcomers, this looks like an interesting approach to getting accustomed to VCS. |
Stacked on #2751: the first commit is @MichaelChirico's fix to
src/rinterface.c, the second moves it into the code generator so that it survives the next regeneration.GitHub cannot use a fork branch as a PR base, so the commit is carried along here instead of being a true base branch; it can be dropped once #2751 is merged.
The fix
PAGERANKOPTis anOPTIONAL INOUTargument, so Stimulus wraps its input conversion intoif (!Rf_isNull(options)), whilechunk_call()adds the(Rf_isNull(...) ? 0 : ...)guard only for arguments that are purely input.The pointer is therefore read unconditionally at the call site, which is an uninitialized read when
optionsisNULLat the R level, as flagged byclang -Wsometimes-uninitialized.The type definition now declares the variable through
CDECLwith aNULLinitializer:CTYPEno longer has to smuggle the extraigraph_arpack_options_tdeclaration past the type, so it can name the actual C type again.The
else { %C% = NULL; }branch of the input conversion is dropped: with the initializer in place it is a redundant re-assignment, and keeping it would suggest that the twoNULLpaths differ.The default now lives in exactly one place.
Generated code for the three affected functions (
igraph_pagerank(),igraph_personalized_pagerank(),igraph_personalized_pagerank_vs()):Are other functions affected?
No, these three are the only real cases.
Compiling the regenerated
src/rinterface.cwithclang -Wall -Wextrareports no-Wsometimes-uninitializedwarning any more.Five further sites are reported by
gcc -O2 -Wmaybe-uninitializedandclang -Wconditional-uninitialized:c_outfileinigraph_maximal_cliques_subset(),c_creatorinigraph_write_graph_gml(),c_startinigraph_fundamental_cycles()andigraph_vertex_path_from_edge_path(), andc_vidinigraph_random_spanning_tree().These are false positives: the arguments are purely input, so the call site does carry the
(Rf_isNull(x) ? 0 : c_x)guard and never reads the variable on the path where the conversion is skipped.The compilers just do not correlate the two
Rf_isNull()tests.Silencing them would mean initializing every optional scalar declaration, which would churn the generated code and weaken the warning elsewhere, so this PR leaves them alone.
🤖 Generated with Claude Code
https://claude.ai/code/session_01RF5eavxtBTfTSquRjc2San
Generated by Claude Code