diff --git a/src/datatype.c b/src/datatype.c index 63069f3675854..908a9a457d05b 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -770,7 +770,16 @@ JL_DLLEXPORT jl_value_t *jl_new_structv(jl_datatype_t *type, jl_value_t **args, uint32_t na) { jl_ptls_t ptls = jl_get_ptls_states(); - if (type->instance != NULL) return type->instance; + if (type->instance != NULL) { + for (size_t i = 0; i < na; i++) { + jl_value_t *ft = jl_field_type(type, i); + if (!jl_isa(args[i], ft)) + jl_type_error("new", ft, args[i]); + } + return type->instance; + } + if (type->layout == NULL) + jl_type_error("new", (jl_value_t*)jl_datatype_type, (jl_value_t*)type); size_t nf = jl_datatype_nfields(type); jl_value_t *jv = jl_gc_alloc(ptls, jl_datatype_size(type), type); JL_GC_PUSH1(&jv); @@ -783,8 +792,8 @@ JL_DLLEXPORT jl_value_t *jl_new_structv(jl_datatype_t *type, jl_value_t **args, for(size_t i=na; i < nf; i++) { if (jl_field_isptr(type, i)) { *(jl_value_t**)((char*)jl_data_ptr(jv)+jl_field_offset(type,i)) = NULL; - - } else { + } + else { jl_value_t *ft = jl_field_type(type, i); if (jl_is_uniontype(ft)) { uint8_t *psel = &((uint8_t *)jv)[jl_field_offset(type, i) + jl_field_size(type, i) - 1]; diff --git a/src/interpreter.c b/src/interpreter.c index 61d803cbf043a..feb0bbbe168a4 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -477,18 +477,12 @@ SECT_INTERP static jl_value_t *eval_value(jl_value_t *e, interpreter_state *s) return jl_nothing; } else if (head == new_sym) { - jl_value_t *thetype = eval_value(args[0], s); - jl_value_t *v=NULL, *fldv=NULL; - JL_GC_PUSH3(&thetype, &v, &fldv); - assert(jl_is_structtype(thetype)); - v = jl_new_struct_uninit((jl_datatype_t*)thetype); - for (size_t i = 1; i < nargs; i++) { - jl_value_t *ft = jl_field_type(thetype, i - 1); - fldv = eval_value(args[i], s); - if (!jl_isa(fldv, ft)) - jl_type_error("new", ft, fldv); - jl_set_nth_field(v, i - 1, fldv); - } + jl_value_t **argv; + JL_GC_PUSHARGS(argv, nargs); + for (size_t i = 0; i < nargs; i++) + argv[i] = eval_value(args[i], s); + assert(jl_is_structtype(argv[0])); + jl_value_t *v = jl_new_structv((jl_datatype_t*)argv[0], &argv[1], nargs - 1); JL_GC_POP(); return v; } diff --git a/test/core.jl b/test/core.jl index ff9282a243b40..f1e4112c86677 100644 --- a/test/core.jl +++ b/test/core.jl @@ -6702,3 +6702,11 @@ end @test_throws ErrorException Array{Int, 2}(undef, 0, -10) @test_throws ErrorException Array{Int, 2}(undef, -10, 0) @test_throws ErrorException Array{Int, 2}(undef, -1, -1) + +# issue #29145 +struct T29145{A,B} + function T29145() + new{S,Ref{S}}() where S + end +end +@test_throws TypeError T29145()