@@ -145,6 +145,16 @@ def vec_create_initialized(
145145 init = builder .coerce (init , item_type , line )
146146 vec = vec_create (builder , vtype , length , line )
147147
148+ # Guard against computing &buf->items when buf is NULL (length == 0).
149+ # vec_create returns buf=NULL for empty vecs, and accessing members
150+ # through a NULL pointer is undefined behavior that GCC -O3 can exploit.
151+ fill_body = BasicBlock ()
152+ fill_end = BasicBlock ()
153+ zero = Integer (0 , c_pyssize_t_rprimitive )
154+ comp = builder .add (ComparisonOp (length , zero , ComparisonOp .SGT , line = line ))
155+ builder .add (Branch (comp , fill_body , fill_end , Branch .BOOL ))
156+ builder .activate_block (fill_body )
157+
148158 items_start = vec_items (builder , vec )
149159 step = step_size (item_type )
150160 items_end = builder .int_add (items_start , builder .int_mul (length , step ))
@@ -155,6 +165,9 @@ def vec_create_initialized(
155165 builder .set_mem (for_loop .index , item_type , init )
156166 for_loop .finish ()
157167
168+ builder .goto (fill_end )
169+ builder .activate_block (fill_end )
170+
158171 builder .keep_alive ([vec ], line )
159172 return vec
160173
0 commit comments