Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ensure binding type is set consistently for consts #44232

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,14 +680,13 @@ JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var
uint8_t constp = 0;
// if (jl_atomic_cmpswap(&bp->constp, &constp, 1)) {
if (constp = bp->constp, bp->constp = 1, constp == 0) {
jl_value_t *old = NULL;
jl_value_t *old_ty = NULL, *old = NULL;
jl_atomic_cmpswap_relaxed(&bp->ty, &old_ty, jl_typeof(val));
if (jl_atomic_cmpswap(&bp->value, &old, val)) {
jl_gc_wb_binding(bp, val);
return;
}
}
jl_value_t *old_ty = NULL;
jl_atomic_cmpswap_relaxed(&bp->ty, &old_ty, (jl_value_t*)jl_any_type);
}
jl_errorf("invalid redefinition of constant %s",
jl_symbol_name(bp->name));
Expand Down Expand Up @@ -807,11 +806,8 @@ void jl_binding_deprecation_warning(jl_module_t *m, jl_binding_t *b)
JL_DLLEXPORT void jl_checked_assignment(jl_binding_t *b, jl_value_t *rhs)
{
jl_value_t *old_ty = NULL;
if (!jl_atomic_cmpswap_relaxed(&b->ty, &old_ty, (jl_value_t*)jl_any_type) && !jl_isa(rhs, old_ty)) {
jl_errorf("cannot assign an incompatible value to the global %s.",
jl_symbol_name(b->name));
}
if (b->constp) {
jl_atomic_cmpswap_relaxed(&b->ty, &old_ty, jl_typeof(rhs));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit fussy perhaps, but I think it would make sense to move this inside the if (jl_atomic_cmpswap for the value.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same above.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure right now we always assume that a non-null value implies that the binding type is also set, while setting a type for an uninitialized binding is perfectly fine. In case of a race we might have set the wrong type, but this should then be caught and error appropriately before we set the value to something inconsistent. Or is there another reason for doing it the other way around?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to add another check of the binding type here though, I can add that. (Although declaring constants isn't really thread-safe right now anyways.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just thinking of making setting the value and type more atomic, but I guess the behavior ends up being the same either way.

jl_value_t *old = NULL;
if (jl_atomic_cmpswap(&b->value, &old, rhs)) {
jl_gc_wb_binding(b, rhs);
Expand All @@ -828,6 +824,10 @@ JL_DLLEXPORT void jl_checked_assignment(jl_binding_t *b, jl_value_t *rhs)
jl_safe_printf("WARNING: redefinition of constant %s. This may fail, cause incorrect answers, or produce other errors.\n",
jl_symbol_name(b->name));
}
if (!jl_atomic_cmpswap_relaxed(&b->ty, &old_ty, (jl_value_t*)jl_any_type) && !jl_isa(rhs, old_ty)) {
jl_errorf("cannot assign an incompatible value to the global %s.",
jl_symbol_name(b->name));
}
jl_atomic_store_relaxed(&b->value, rhs);
jl_gc_wb_binding(b, rhs);
}
Expand Down
3 changes: 3 additions & 0 deletions test/misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1109,3 +1109,6 @@ end
@testset "Base/timing.jl" begin
@test Base.jit_total_bytes() >= 0
end

const I_AM_A_CONSTANT_INT = 1
@test Core.get_binding_type(@__MODULE__, :I_AM_A_CONSTANT_INT) == Int