| author | |
| committer | |
| log | 1165e13c256cb4aeb76674c2bc34f35c6ebd375b |
| tree | 294f03129e5c7cabfdab92adfd9fa289e8d8eb44 |
| parent | 455899668b620dfda40252501c748c0a983555bd |
Using zig cc to compile and run wasm2c on zig.wasm on Windows triggers
what appears to be a sanitizer crash. The FuncGen reuse array pointer is
initialized to null and at some point it's resized to a length of zero,
which triggers this code to execute:
memcpy(&self->reuse[self->reuse_i], &self->reuse[reuse_top], sizeof(uint32_t) * reuse_n);
Given the current values, this equates to:
memcpy(&(NULL)[0], &(NULL)[0], 0);
Taking the address of the first element of a null pointer doesn't trigger
any actual runtime problem, since the pointer won't be dereferenced because
were passing 0 as the length to memcpy, however, it seems that the C spec
considers indexing a null pointer to be undefined behavior even if you
don't use the resulting value (or are just taking the address of an
indexed pointer).1 files changed, 4 insertions(+), 2 deletions(-)
stage1/FuncGen.h+4-2| ... | ... | @@ -179,8 +179,10 @@ static void FuncGen_blockBegin(struct FuncGen *self, FILE *out, enum WasmOpcode |
| 179 | 179 | self->reuse = realloc(self->reuse, sizeof(uint32_t) * self->reuse_len); |
| 180 | 180 | if (self->reuse == NULL) panic("out of memory"); |
| 181 | 181 | } |
| 182 | memcpy(&self->reuse[self->reuse_i], &self->reuse[reuse_top], sizeof(uint32_t) * reuse_n); | |
| 183 | self->reuse_i += reuse_n; | |
| 182 | if (reuse_n != 0) { | |
| 183 | memcpy(&self->reuse[self->reuse_i], &self->reuse[reuse_top], sizeof(uint32_t) * reuse_n); | |
| 184 | self->reuse_i += reuse_n; | |
| 185 | } | |
| 184 | 186 | } |
| 185 | 187 | |
| 186 | 188 | static enum WasmOpcode FuncGen_blockKind(const struct FuncGen *self, uint32_t label_idx) { |