Skip to content

Commit ea8cea0

Browse files
author
Daniel Kroening
committed
fix up __float128 and _Float128 support
_Float128 is a keyword, defined in ISO/IEC TS 18661-3:2015, and exists since gcc 7.0. clang does not offer it. __float128 is a typedef in gcc since 4.3/4.5, depending on architecture. __float128 is a keyword in clang. This PR attempts to clean this up.
1 parent 3b384ed commit ea8cea0

File tree

11 files changed

+64
-37
lines changed

11 files changed

+64
-37
lines changed

regression/ansi-c/gcc_version1/gcc-5.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ typedef float _Float32;
33
typedef double _Float32x;
44
typedef double _Float64;
55
typedef long double _Float64x;
6+
typedef long double _Float128;
67
typedef long double _Float128x;
78

89
// But this type should:
9-
_Float128 f128;
10+
__float128 f128;

regression/ansi-c/gcc_version1/gcc-7.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ _Float64 f64;
55
_Float64x f64x;
66
_Float128 f128;
77
_Float128x f128x;
8+
9+
__float128 gcc_f128;

regression/cbmc/ts18661_typedefs/main.c

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,51 @@
1-
#if defined(__GNUC__) && !defined(__clang__)
1+
#if defined(__GNUC__)
22

3-
#include <features.h> // For __GNUC_PREREQ
3+
# ifdef __clang__
44

5-
#ifdef __x86_64__
6-
#define FLOAT128_MINOR_VERSION 3
7-
#else
8-
#define FLOAT128_MINOR_VERSION 5
9-
#endif
5+
# define HAS_FLOAT128
106

11-
#if __GNUC__ >= 7
12-
#define HAS_FLOATN
13-
#elif __GNUC_PREREQ(4, FLOAT128_MINOR_VERSION)
14-
#define HAS_FLOAT128
15-
#endif
7+
# else
8+
9+
# include <features.h> // For __GNUC_PREREQ
10+
11+
# ifdef __x86_64__
12+
# define FLOAT128_MINOR_VERSION 3
13+
# else
14+
# define FLOAT128_MINOR_VERSION 5
15+
# endif
16+
17+
# if __GNUC__ >= 7
18+
# define HAS_FLOATN
19+
# endif
20+
21+
# if __GNUC_PREREQ(4, FLOAT128_MINOR_VERSION)
22+
# define HAS_FLOAT128
23+
# endif
24+
25+
# endif
1626

1727
#endif
1828

19-
#ifndef HAS_FLOATN
29+
#ifdef HAS_FLOATN
30+
typedef _Float32 f1;
31+
typedef _Float32x f2;
32+
typedef _Float64 f3;
33+
typedef _Float64x f4;
34+
typedef _Float128 f5;
35+
typedef _Float128x f6;
36+
#else
2037
typedef float _Float32;
2138
typedef double _Float32x;
2239
typedef double _Float64;
2340
typedef long double _Float64x;
41+
typedef long double _Float128;
2442
typedef long double _Float128x;
2543
#endif
2644

27-
#if !defined(HAS_FLOATN) && !defined(HAS_FLOAT128)
28-
typedef long double _Float128;
45+
#if defined(HAS_FLOAT128)
46+
typedef __float128 f7;
47+
#else
48+
typedef long double __float128;
2949
#endif
3050

3151
int main(int argc, char** argv) {

src/ansi-c/ansi_c_internal_additions.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,12 @@ void ansi_c_internal_additions(std::string &code)
208208
// https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
209209
// For clang, __float128 is a keyword.
210210
// For gcc, this is a typedef and not a keyword.
211-
if(config.ansi_c.mode != configt::ansi_ct::flavourt::CLANG)
211+
if(
212+
config.ansi_c.mode != configt::ansi_ct::flavourt::CLANG &&
213+
config.ansi_c.gcc__float128_type)
214+
{
212215
code += "typedef " CPROVER_PREFIX "Float128 __float128;\n";
216+
}
213217
}
214218
else if(config.ansi_c.arch == "ppc64le")
215219
{
@@ -222,8 +226,12 @@ void ansi_c_internal_additions(std::string &code)
222226
// https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
223227
// For clang, __float128 is a keyword.
224228
// For gcc, this is a typedef and not a keyword.
225-
if(config.ansi_c.mode != configt::ansi_ct::flavourt::CLANG)
229+
if(
230+
config.ansi_c.mode != configt::ansi_ct::flavourt::CLANG &&
231+
config.ansi_c.gcc__float128_type)
232+
{
226233
code+="typedef long double __float128;\n";
234+
}
227235
}
228236

229237
if(

src/ansi-c/ansi_c_language.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ bool ansi_c_languaget::parse(
7676
ansi_c_parser.set_message_handler(get_message_handler());
7777
ansi_c_parser.for_has_scope=config.ansi_c.for_has_scope;
7878
ansi_c_parser.ts_18661_3_Floatn_types=config.ansi_c.ts_18661_3_Floatn_types;
79-
ansi_c_parser.Float128_type = config.ansi_c.Float128_type;
8079
ansi_c_parser.cpp98=false; // it's not C++
8180
ansi_c_parser.cpp11=false; // it's not C++
8281
ansi_c_parser.mode=config.ansi_c.mode;

src/ansi-c/ansi_c_parser.h

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,15 @@ class ansi_c_parsert:public parsert
2828
public:
2929
ansi_c_parse_treet parse_tree;
3030

31-
ansi_c_parsert():
32-
tag_following(false),
33-
asm_block_following(false),
34-
parenthesis_counter(0),
35-
mode(modet::NONE),
36-
cpp98(false),
37-
cpp11(false),
38-
for_has_scope(false),
39-
ts_18661_3_Floatn_types(false),
40-
Float128_type(false)
31+
ansi_c_parsert()
32+
: tag_following(false),
33+
asm_block_following(false),
34+
parenthesis_counter(0),
35+
mode(modet::NONE),
36+
cpp98(false),
37+
cpp11(false),
38+
for_has_scope(false),
39+
ts_18661_3_Floatn_types(false)
4140
{
4241
}
4342

@@ -84,9 +83,6 @@ class ansi_c_parsert:public parsert
8483
// ISO/IEC TS 18661-3:2015
8584
bool ts_18661_3_Floatn_types;
8685

87-
// Does the compiler version emulated provide _Float128?
88-
bool Float128_type;
89-
9086
typedef ansi_c_identifiert identifiert;
9187
typedef ansi_c_scopet scopet;
9288

src/ansi-c/scanner.l

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ void ansi_c_scanner_init()
565565
return make_identifier();
566566
}
567567

568-
"_Float128" { if(PARSER.Float128_type)
568+
"_Float128" { if(PARSER.ts_18661_3_Floatn_types)
569569
{ loc(); return TOK_GCC_FLOAT128; }
570570
else
571571
return make_identifier();

src/cpp/cpp_parser.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ bool cpp_parsert::parse()
2525
config.cpp.cpp_standard==configt::cppt::cpp_standardt::CPP11 ||
2626
config.cpp.cpp_standard==configt::cppt::cpp_standardt::CPP14;
2727
ansi_c_parser.ts_18661_3_Floatn_types=false;
28-
ansi_c_parser.Float128_type = false;
2928
ansi_c_parser.in=in;
3029
ansi_c_parser.mode=mode;
3130
ansi_c_parser.set_file(get_file());

src/goto-cc/gcc_mode.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,9 @@ int gcc_modet::doit()
539539
const auto gcc_float128_minor_version =
540540
config.ansi_c.arch == "x86_64" ? 3u : 5u;
541541

542-
config.ansi_c.Float128_type =
542+
// __float128 exists (as a typedef) since gcc 4.5 everywhere,
543+
// and since 4.3 on x86_64
544+
config.ansi_c.gcc__float128_type =
543545
gcc_version.flavor == gcc_versiont::flavort::GCC &&
544546
gcc_version.is_at_least(4u, gcc_float128_minor_version);
545547

src/util/config.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,7 @@ bool configt::set(const cmdlinet &cmdline)
948948
}
949949

950950
if(ansi_c.preprocessor == ansi_ct::preprocessort::GCC)
951-
ansi_c.Float128_type = true;
951+
ansi_c.gcc__float128_type = true;
952952

953953
set_arch(arch);
954954

src/util/config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class configt
4444
bool char_is_unsigned, wchar_t_is_unsigned;
4545
bool for_has_scope;
4646
bool ts_18661_3_Floatn_types; // ISO/IEC TS 18661-3:2015
47-
bool Float128_type;
47+
bool gcc__float128_type; // __float128, a gcc extension since 4.3/4.5
4848
bool single_precision_constant;
4949
enum class c_standardt { C89, C99, C11 } c_standard;
5050
static c_standardt default_c_standard();

0 commit comments

Comments
 (0)