From 2f80fc473f1a71cce62cfeaed6f335fc52acd585 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Mon, 8 Dec 2025 00:24:46 +0300 Subject: [PATCH] libexpr-tests: Work around LTO issue with SAMPLE_USER_DATA on i686-linux with sanitizers This somehow fails https://hydra.nixos.org/build/315675349/nixlog/1. I don't know the exact details, but it seems that something goes very wrong with LTO and sanitizers that lead to the string literal to be moved? Instead of relying on the string literal deduplication to provide a consistent address we can use a global. That should have a single address (modulo wonky copy relocations). --- src/libexpr-tests/nix_api_expr.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libexpr-tests/nix_api_expr.cc b/src/libexpr-tests/nix_api_expr.cc index fdd09a449..c7e246c72 100644 --- a/src/libexpr-tests/nix_api_expr.cc +++ b/src/libexpr-tests/nix_api_expr.cc @@ -232,22 +232,22 @@ TEST_F(nix_api_expr_test, nix_expr_realise_context) nix_realised_string_free(r); } -const char * SAMPLE_USER_DATA = "whatever"; +static const char SAMPLE_USER_DATA = 0; static void primop_square(void * user_data, nix_c_context * context, EvalState * state, nix_value ** args, nix_value * ret) { assert(context); assert(state); - assert(user_data == SAMPLE_USER_DATA); + assert(user_data == &SAMPLE_USER_DATA); auto i = nix_get_int(context, args[0]); nix_init_int(context, ret, i * i); } TEST_F(nix_api_expr_test, nix_expr_primop) { - PrimOp * primop = - nix_alloc_primop(ctx, primop_square, 1, "square", nullptr, "square an integer", (void *) SAMPLE_USER_DATA); + PrimOp * primop = nix_alloc_primop( + ctx, primop_square, 1, "square", nullptr, "square an integer", const_cast(&SAMPLE_USER_DATA)); assert_ctx_ok(); nix_value * primopValue = nix_alloc_value(ctx, state); assert_ctx_ok(); @@ -273,7 +273,7 @@ primop_repeat(void * user_data, nix_c_context * context, EvalState * state, nix_ { assert(context); assert(state); - assert(user_data == SAMPLE_USER_DATA); + assert(user_data == &SAMPLE_USER_DATA); // Get the string to repeat std::string s; @@ -295,8 +295,8 @@ primop_repeat(void * user_data, nix_c_context * context, EvalState * state, nix_ TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_multiple_calls) { - PrimOp * primop = - nix_alloc_primop(ctx, primop_repeat, 2, "repeat", nullptr, "repeat a string", (void *) SAMPLE_USER_DATA); + PrimOp * primop = nix_alloc_primop( + ctx, primop_repeat, 2, "repeat", nullptr, "repeat a string", const_cast(&SAMPLE_USER_DATA)); assert_ctx_ok(); nix_value * primopValue = nix_alloc_value(ctx, state); assert_ctx_ok(); @@ -330,8 +330,8 @@ TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_multiple_calls) TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_single_call) { - PrimOp * primop = - nix_alloc_primop(ctx, primop_repeat, 2, "repeat", nullptr, "repeat a string", (void *) SAMPLE_USER_DATA); + PrimOp * primop = nix_alloc_primop( + ctx, primop_repeat, 2, "repeat", nullptr, "repeat a string", const_cast(&SAMPLE_USER_DATA)); assert_ctx_ok(); nix_value * primopValue = nix_alloc_value(ctx, state); assert_ctx_ok();