From 1405552bdab2078010350503153ae6c6e923d60d Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Thu, 10 Mar 2016 17:35:07 -0500 Subject: [PATCH] Fix: use unions to write floats to avoid aliasing warnings Signed-off-by: Philippe Proulx --- barectf/gen.py | 47 ++++++++++++++++++++++++++++++++++++++------ barectf/templates.py | 10 ++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/barectf/gen.py b/barectf/gen.py index bd0a1ba..ed70573 100644 --- a/barectf/gen.py +++ b/barectf/gen.py @@ -103,6 +103,8 @@ class CCodeGenerator: metadata.String: self._generate_serialize_string, } self._saved_byte_offsets = {} + self._uf_written = False + self._ud_written = False self._sasa = _StaticAlignSizeAutomaton() def _generate_ctx_parent(self): @@ -417,6 +419,7 @@ class CCodeGenerator: self._cg.add_empty_line() def _generate_func_get_event_size(self, stream, event): + self._reset_per_func_state() self._generate_func_get_event_size_proto(stream, event) tmpl = templates._FUNC_GET_EVENT_SIZE_BODY_BEGIN self._cg.add_lines(tmpl) @@ -468,13 +471,34 @@ class CCodeGenerator: def _generate_serialize_float(self, var, ctx, t): ctype = self._get_type_ctype(t) - if ctype == 'float': - ctype = 'uint32_t' - elif ctype == 'double': - ctype = 'uint64_t' + if ctype == 'float' or ctype == 'double': + gen_union_var = False + + if ctype == 'float': + if not self._uf_written: + self._uf_written = True + gen_union_var = True + + union_name = 'f2u' + elif ctype == 'double': + if not self._ud_written: + self._ud_written = True + gen_union_var = True + + union_name = 'd2u' + + if gen_union_var: + # union for reading the bytes of the floating point number - var_casted = '*(({}*) &{})'.format(ctype, var) - self._generate_bitfield_write(var_casted, ctx, t) + self._cg.add_line('union {name} {name};'.format(name=union_name)) + self._cg.add_empty_line() + + self._cg.add_line('{}.f = {};'.format(union_name, var)) + bf_var = '{}.u'.format(union_name) + else: + bf_var = '({}) {}'.format(ctype, var) + + self._generate_bitfield_write(bf_var, ctx, t) self._generate_incr_pos('{}->at'.format(ctx), t.size) def _generate_serialize_enum(self, var, ctx, t): @@ -513,6 +537,7 @@ class CCodeGenerator: self._cg.add_empty_line() def _generate_func_serialize_event(self, stream, event): + self._reset_per_func_state() self._generate_func_serialize_event_proto(stream, event) tmpl = templates._FUNC_SERIALIZE_EVENT_BODY_BEGIN self._cg.add_lines(tmpl) @@ -581,6 +606,7 @@ class CCodeGenerator: self._cg.add_lines(tmpl) def _generate_func_serialize_stream_event_header(self, stream): + self._reset_per_func_state() self._generate_func_serialize_stream_event_header_proto(stream) tmpl = templates._FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_BEGIN self._cg.add_lines(tmpl) @@ -617,6 +643,7 @@ class CCodeGenerator: self._cg.add_lines(tmpl) def _generate_func_serialize_stream_event_context(self, stream): + self._reset_per_func_state() self._generate_func_serialize_stream_event_context_proto(stream) tmpl = templates._FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_BEGIN self._cg.add_lines(tmpl) @@ -631,6 +658,7 @@ class CCodeGenerator: self._cg.add_lines(tmpl) def _generate_func_trace(self, stream, event): + self._reset_per_func_state() self._generate_func_trace_proto(stream, event) params = self._get_call_event_param_list(stream, event) tmpl = templates._FUNC_TRACE_BODY @@ -638,6 +666,7 @@ class CCodeGenerator: params=params)) def _generate_func_init(self): + self._reset_per_func_state() self._generate_func_init_proto() tmpl = templates._FUNC_INIT_BODY self._cg.add_lines(tmpl.format(prefix=self._cfg.prefix)) @@ -651,12 +680,17 @@ class CCodeGenerator: def _restore_byte_offset(self, name): self._sasa.byte_offset = self._saved_byte_offsets[name] + def _reset_per_func_state(self): + self._uf_written = False + self._ud_written = False + def _generate_func_open(self, stream): def generate_save_offset(name): tmpl = 'ctx->off_spc_{} = ctx->parent.at;'.format(name) self._cg.add_line(tmpl) self._save_byte_offset(name) + self._reset_per_func_state() self._generate_func_open_proto(stream) tmpl = templates._FUNC_OPEN_BODY_BEGIN self._cg.add_lines(tmpl) @@ -778,6 +812,7 @@ class CCodeGenerator: tmpl = 'ctx->parent.at = ctx->off_spc_{};'.format(name) self._cg.add_line(tmpl) + self._reset_per_func_state() self._generate_func_close_proto(stream) tmpl = templates._FUNC_CLOSE_BODY_BEGIN self._cg.add_lines(tmpl) diff --git a/barectf/templates.py b/barectf/templates.py index 3efb080..78bc012 100644 --- a/barectf/templates.py +++ b/barectf/templates.py @@ -250,6 +250,16 @@ _C_SRC = '''/* #define _BITS_TO_BYTES(_x) ((_x) >> 3) #define _BYTES_TO_BITS(_x) ((_x) << 3) +union f2u {{ + float f; + uint32_t u; +}}; + +union d2u {{ + double f; + uint64_t u; +}}; + uint32_t {prefix}packet_size(void *ctx) {{ return ((struct {prefix}ctx *) ctx)->packet_size; -- 2.34.1