CBMC
convert_float_literal.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: C++ Language Conversion
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "convert_float_literal.h"
13 
14 #include <util/c_types.h>
15 #include <util/config.h>
16 #include <util/ieee_float.h>
17 #include <util/std_expr.h>
18 
19 #include <ansi-c/gcc_types.h>
20 
21 #include "parse_float.h"
22 
25 exprt convert_float_literal(const std::string &src)
26 {
27  parse_floatt parsed_float(src);
28 
29  // In ANSI-C, float literals are double by default,
30  // unless marked with 'f' (this can be overridden with
31  // config.ansi_c.single_precision_constant).
32  // Furthermore, floating-point literals can be complex.
33 
34  floatbv_typet type;
35 
36  if(parsed_float.is_float)
37  type = float_type();
38  else if(parsed_float.is_long)
39  type = long_double_type();
40  else if(parsed_float.is_float16)
41  type = gcc_float16_type();
42  else if(parsed_float.is_float32)
43  type = gcc_float32_type();
44  else if(parsed_float.is_float32x)
45  type = gcc_float32x_type();
46  else if(parsed_float.is_float64)
47  type = gcc_float64_type();
48  else if(parsed_float.is_float64x)
49  type = gcc_float64x_type();
50  else if(parsed_float.is_float80)
51  {
52  type = ieee_float_spect(64, 15).to_type();
53  type.set(ID_C_c_type, ID_long_double);
54  }
55  else if(parsed_float.is_float128)
56  type = gcc_float128_type();
57  else if(parsed_float.is_float128x)
58  type = gcc_float128x_type();
59  else
60  {
61  // default
63  type = float_type(); // default
64  else
65  type = double_type(); // default
66  }
67 
68  if(parsed_float.is_decimal)
69  {
70  // TODO - should set ID_gcc_decimal32/ID_gcc_decimal64/ID_gcc_decimal128,
71  // but these aren't handled anywhere
72  }
73 
74  ieee_floatt a(type);
75 
76  if(parsed_float.exponent_base==10)
77  a.from_base10(parsed_float.significand, parsed_float.exponent);
78  else if(parsed_float.exponent_base==2) // hex
79  a.build(parsed_float.significand, parsed_float.exponent);
80  else
82 
83  constant_exprt result = a.to_expr();
84  // ieee_floatt::to_expr gives us the representation, but doesn't preserve the
85  // distinction between bitwise-identical types such as _Float32 vs. float,
86  // so ensure we preserve that here:
87  result.type() = type;
88 
89  if(parsed_float.is_imaginary)
90  {
91  const complex_typet complex_type(type);
92 
93  constant_exprt zero_real_component = ieee_floatt::zero(type).to_expr();
94  // As above, ensure we preserve the exact type of the literal:
95  zero_real_component.type() = type;
96 
97  return complex_exprt(zero_real_component, result, complex_type);
98  }
99 
100  return std::move(result);
101 }
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
parse_floatt
Definition: parse_float.h:19
ieee_floatt
Definition: ieee_float.h:116
parse_floatt::is_float16
bool is_float16
Definition: parse_float.h:28
parse_float.h
gcc_float32_type
floatbv_typet gcc_float32_type()
Definition: gcc_types.cpp:21
gcc_float64x_type
floatbv_typet gcc_float64x_type()
Definition: gcc_types.cpp:48
gcc_float16_type
floatbv_typet gcc_float16_type()
Definition: gcc_types.cpp:13
gcc_types.h
parse_floatt::is_float64
bool is_float64
Definition: parse_float.h:30
long_double_type
floatbv_typet long_double_type()
Definition: c_types.cpp:211
floatbv_typet
Fixed-width bit-vector with IEEE floating-point interpretation.
Definition: bitvector_types.h:321
parse_floatt::is_float64x
bool is_float64x
Definition: parse_float.h:30
exprt
Base class for all expressions.
Definition: expr.h:55
parse_floatt::is_imaginary
bool is_imaginary
Definition: parse_float.h:28
complex_typet
Complex numbers made of pair of given subtype.
Definition: std_types.h:1076
configt::ansi_c
struct configt::ansi_ct ansi_c
parse_floatt::significand
mp_integer significand
Definition: parse_float.h:22
gcc_float128_type
floatbv_typet gcc_float128_type()
Definition: gcc_types.cpp:57
ieee_float_spect
Definition: ieee_float.h:22
gcc_float64_type
floatbv_typet gcc_float64_type()
Definition: gcc_types.cpp:39
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
parse_floatt::is_float128
bool is_float128
Definition: parse_float.h:32
parse_floatt::is_decimal
bool is_decimal
Definition: parse_float.h:28
convert_float_literal.h
irept::set
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:420
ieee_float_spect::to_type
class floatbv_typet to_type() const
Definition: ieee_float.cpp:24
parse_floatt::is_float32x
bool is_float32x
Definition: parse_float.h:29
float_type
floatbv_typet float_type()
Definition: c_types.cpp:195
convert_float_literal
exprt convert_float_literal(const std::string &src)
build an expression from a floating-point literal
Definition: convert_float_literal.cpp:25
parse_floatt::exponent_base
unsigned exponent_base
Definition: parse_float.h:23
complex_exprt
Complex constructor from a pair of numbers.
Definition: std_expr.h:1857
ieee_floatt::from_base10
void from_base10(const mp_integer &exp, const mp_integer &frac)
compute f * (10^e)
Definition: ieee_float.cpp:486
double_type
floatbv_typet double_type()
Definition: c_types.cpp:203
config
configt config
Definition: config.cpp:25
parse_floatt::is_long
bool is_long
Definition: parse_float.h:25
parse_floatt::is_float32
bool is_float32
Definition: parse_float.h:29
parse_floatt::is_float
bool is_float
Definition: parse_float.h:25
ieee_float.h
config.h
ieee_floatt::zero
static ieee_floatt zero(const floatbv_typet &type)
Definition: ieee_float.h:196
ieee_floatt::to_expr
constant_exprt to_expr() const
Definition: ieee_float.cpp:702
parse_floatt::is_float128x
bool is_float128x
Definition: parse_float.h:32
constant_exprt
A constant literal expression.
Definition: std_expr.h:2941
configt::ansi_ct::single_precision_constant
bool single_precision_constant
Definition: config.h:141
std_expr.h
parse_floatt::is_float80
bool is_float80
Definition: parse_float.h:31
parse_floatt::exponent
mp_integer exponent
Definition: parse_float.h:22
c_types.h
gcc_float32x_type
floatbv_typet gcc_float32x_type()
Definition: gcc_types.cpp:30
gcc_float128x_type
floatbv_typet gcc_float128x_type()
Definition: gcc_types.cpp:66
ieee_floatt::build
void build(const mp_integer &exp, const mp_integer &frac)
Definition: ieee_float.cpp:472