diff --git a/cc.sh b/cc.sh index d3889c8..4156eed 100755 --- a/cc.sh +++ b/cc.sh @@ -366,16 +366,14 @@ if [ -z "$mode" ] || [ "$mode" = ld ]; then done fi -# Finish setting up the mode, and check whether -frandom-seed needs to be set. -eval "_set_frandom_seed=\${SPACK_${comp}_HAS_FRANDOM_SEED:-}" +# Finish setting up the mode. if [ -z "$mode" ]; then mode=ccld for arg in "$@"; do case $arg in - -E) mode=cpp ;; - -S) mode=as ;; - -c) mode=cc ;; - -frandom-seed=*) _set_frandom_seed= ;; + -E) mode=cpp; break ;; + -S) mode=as; break ;; + -c) mode=cc; break ;; esac done fi @@ -953,14 +951,27 @@ extend args_list libs_list "-l" full_command_list="$command" extend full_command_list args_list -if [ -n "$_set_frandom_seed" ]; then - case "$mode" in - cc|ccld) - # Make GCC deterministic by setting the random seed to command line arguments - append full_command_list "-frandom-seed=$input_command" - ;; - esac -fi +case "$mode" in + cc|ccld) + eval "_frandom_seed_input=\${SPACK_${comp}_HAS_FRANDOM_SEED:-}" + if [ -n "$_frandom_seed_input" ]; then + _frandom_seed_input="" + setsep other_args_list + [ "$sep" != " " ] && IFS="$sep" + for arg in $other_args_list; do + case "$arg" in + -frandom-seed=*) _frandom_seed_input=; break ;; + -*|*.o|*.so|*.dylib|*.a) ;; + *) _frandom_seed_input="${_frandom_seed_input}${arg}" ;; + esac + done + unset IFS + if [ -n "$_frandom_seed_input" ]; then + append full_command_list "-frandom-seed=$_frandom_seed_input" + fi + fi + ;; +esac # prepend the ccache binary if we're using ccache if [ -n "$SPACK_CCACHE_BINARY" ]; then diff --git a/test/run.sh b/test/run.sh index 2dd28c8..a59b0a9 100644 --- a/test/run.sh +++ b/test/run.sh @@ -1011,6 +1011,51 @@ expected: $_expected_LR" fi } +# --------------------------------------------------------------------------- +# -frandom-seed +# --------------------------------------------------------------------------- + +test_frandom_seed_not_added_without_env() { + wrapper_environment + _out=$(dump_args cc '-c +hello.c +-O2') + if printf '%s\n' "$_out" | grep -F -- '-frandom-seed=' >/dev/null; then + fail "frandom_seed_absent: -frandom-seed should not appear without SPACK_CC_HAS_FRANDOM_SEED" + fi +} + +test_frandom_seed_filters_args() { + wrapper_environment + SPACK_CC_HAS_FRANDOM_SEED=1; export SPACK_CC_HAS_FRANDOM_SEED + + # cc mode: -frandom-seed should contain only source files, concatenated. + # Includes space-separated path flags to verify their values do not leak. + _out=$(dump_args cc '-c +-O2 +-I/some/include +-isystem +/some/sys +-L +/some/lib +hello.c +world.c +foo.o +bar.a +baz.so +quux.dylib') + expect_contains frandom_seed_value "$_out" '-frandom-seed=hello.cworld.c' + + # User-supplied -frandom-seed suppresses auto-generated one + _out=$(dump_args cc '-c +-frandom-seed=custom +hello.c') + if printf '%s\n' "$_out" | grep -cF -- '-frandom-seed=' | grep -qv '^1$'; then + fail "frandom_seed_user_override: expected exactly one -frandom-seed" + fi + expect_contains frandom_seed_user_passthrough "$_out" '-frandom-seed=custom' +} + # --------------------------------------------------------------------------- # Runner # --------------------------------------------------------------------------- @@ -1029,6 +1074,8 @@ test_disable_new_dtags test_filter_enable_new_dtags test_linker_strips_loopopt test_spack_managed_dirs_are_prioritized +test_frandom_seed_not_added_without_env +test_frandom_seed_filters_args ' if [ $# -gt 0 ]; then