diff options
author | Xavier Leroy <xavier.leroy@college-de-france.fr> | 2021-05-02 19:19:12 +0200 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@college-de-france.fr> | 2021-05-02 19:19:12 +0200 |
commit | 1f35599abe1b82f565a9a1b1ee03f60df362f22d (patch) | |
tree | 09d7dab28169a68600e54149e3575c79247cdc4f /cparser/Bitfields.ml | |
parent | 3b448f597344109183c2436d477deed0ed820d6f (diff) | |
download | compcert-kvx-1f35599abe1b82f565a9a1b1ee03f60df362f22d.tar.gz compcert-kvx-1f35599abe1b82f565a9a1b1ee03f60df362f22d.zip |
Fix evaluation order in emulation of bitfield assignment
A bitfield assignment `x.b = f()` is expanded into a read-modify-write
on `x.carrier`. Wrong results can occur if `x.carrier` is read before
the call to `f()`, and `f` itself modifies a bitfield with the same
carrier `x.carrier`.
In this temporary fix, we play on the evaluation order implemented by
the SimplExpr pass of CompCert (left-to-right for side-effecting
subexpression) to make sure the read part of the read-modify-write
sequence occurs after the evaluation of the right-hand side.
More substantial fixes will be considered later.
Fixes: #395
Diffstat (limited to 'cparser/Bitfields.ml')
-rw-r--r-- | cparser/Bitfields.ml | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/cparser/Bitfields.ml b/cparser/Bitfields.ml index 7a00f719..6d4050f1 100644 --- a/cparser/Bitfields.ml +++ b/cparser/Bitfields.ml @@ -267,7 +267,7 @@ let bitfield_extract env bf carrier = unsigned int bitfield_insert(unsigned int x, int ofs, int sz, unsigned int y) { unsigned int mask = ((1U << sz) - 1) << ofs; - return (x & ~mask) | ((y << ofs) & mask); + return ((y << ofs) & mask) | (x & ~mask); } If the bitfield is of type _Bool, the new value (y above) must be converted @@ -284,7 +284,7 @@ let bitfield_assign env bf carrier newval = eshift env Oshl newval_casted (intconst (Int64.of_int bf.bf_pos) IUInt) in let newval_masked = ebinint env Oand newval_shifted msk and oldval_masked = ebinint env Oand carrier notmsk in - ebinint env Oor oldval_masked newval_masked + ebinint env Oor newval_masked oldval_masked (* Initialize a bitfield *) |