Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- commit 19e7aca212afc7360f69f93100a157c0e659861d
- Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- Date: Tue May 14 11:18:34 2019 -0400
- Fix: bitfield: shift undefined/implementation defined behaviors (v3)
- bitfield.h uses the left shift operator with a left operand which
- may be negative. The C99 standard states that shifting a negative
- value is undefined.
- When building with -Wshift-negative-value, we get this gcc warning:
- In file included from /home/smarchi/src/babeltrace/include/babeltrace/ctfser-internal.h:44:0,
- from /home/smarchi/src/babeltrace/ctfser/ctfser.c:42:
- /home/smarchi/src/babeltrace/include/babeltrace/ctfser-internal.h: In function ‘bt_ctfser_write_unsigned_int’:
- /home/smarchi/src/babeltrace/include/babeltrace/bitfield-internal.h:116:24: error: left shift of negative value [-Werror=shift-negative-value]
- mask = ~((~(type) 0) << (__start % ts)); \
- ^
- /home/smarchi/src/babeltrace/include/babeltrace/bitfield-internal.h:222:2: note: in expansion of macro ‘_bt_bitfield_write_le’
- _bt_bitfield_write_le(ptr, type, _start, _length, _v)
- ^~~~~~~~~~~~~~~~~~~~~
- /home/smarchi/src/babeltrace/include/babeltrace/ctfser-internal.h:418:3: note: in expansion of macro ‘bt_bitfield_write_le’
- bt_bitfield_write_le(mmap_align_addr(ctfser->base_mma) +
- ^~~~~~~~~~~~~~~~~~~~
- This boils down to the fact that the expression ~((uint8_t)0) has type
- "signed int", which is used as an operand of the left shift. This is due
- to the integer promotion rules of C99 (6.3.3.1):
- If an int can represent all values of the original type, the value is
- converted to an int; otherwise, it is converted to an unsigned int.
- These are called the integer promotions. All other types are unchanged
- by the integer promotions.
- We also need to cast the result explicitly into the left hand
- side type to deal with:
- warning: large integer implicitly truncated to unsigned type [-Woverflow]
- The C99 standard states that a right shift has implementation-defined
- behavior when shifting a signed negative value. Add a preprocessor check
- that the compiler provides the expected behavior, else provide an
- alternative implementation which guarantees the intended behavior.
- A preprocessor check is also added to ensure that the compiler
- representation for signed values is two's complement, which is expected
- by this header.
- Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- Change-Id: I17ba38952ddc4c27d770649f782fd249f6ea69be
- ---
- Changes since v1:
- - Fix wrong use of _$prefix$bt_make_mask() in _$prefix$bt_bitfield_write_be.
- Should be _$prefix$bt_make_mask_complement().
- Changes since v2:
- - Documentation and style updates.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement