Skip to content

Commit 0a6af1e

Browse files
authored
Merge pull request #4629 from diffblue/__float128
fix up __float128 and _Float128 support
2 parents 133a6f4 + c937b3f commit 0a6af1e

File tree

14 files changed

+95
-48
lines changed

14 files changed

+95
-48
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/gcc_version.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,23 @@ std::ostream &operator<<(std::ostream &out, const gcc_versiont &v)
142142
{
143143
return out << v.v_major << '.' << v.v_minor << '.' << v.v_patchlevel;
144144
}
145+
146+
void configure_gcc(const gcc_versiont &gcc_version)
147+
{
148+
// ISO/IEC TS 18661-3:2015 support was introduced with gcc 7.0
149+
if(
150+
gcc_version.flavor == gcc_versiont::flavort::GCC &&
151+
gcc_version.is_at_least(7u))
152+
{
153+
config.ansi_c.ts_18661_3_Floatn_types = true;
154+
}
155+
156+
const auto gcc_float128_minor_version =
157+
config.ansi_c.arch == "x86_64" ? 3u : 5u;
158+
159+
// __float128 exists (as a typedef) since gcc 4.5 everywhere,
160+
// and since 4.3 on x86_64
161+
config.ansi_c.gcc__float128_type =
162+
gcc_version.flavor == gcc_versiont::flavort::GCC &&
163+
gcc_version.is_at_least(4u, gcc_float128_minor_version);
164+
}

src/ansi-c/gcc_version.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class gcc_versiont
5050
}
5151
};
5252

53+
void configure_gcc(const gcc_versiont &);
54+
5355
std::ostream &operator<<(std::ostream &, const gcc_versiont &);
5456

5557
#endif

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/cbmc/cbmc_parse_options.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Author: Daniel Kroening, [email protected]
2828

2929
#include <ansi-c/c_preprocess.h>
3030
#include <ansi-c/cprover_library.h>
31+
#include <ansi-c/gcc_version.h>
3132

3233
#include <assembler/remove_asm.h>
3334

@@ -490,6 +491,14 @@ int cbmc_parse_optionst::doit()
490491

491492
register_languages();
492493

494+
// configure gcc, if required
495+
if(config.ansi_c.preprocessor == configt::ansi_ct::preprocessort::GCC)
496+
{
497+
gcc_versiont gcc_version;
498+
gcc_version.get("gcc");
499+
configure_gcc(gcc_version);
500+
}
501+
493502
if(cmdline.isset("test-preprocessor"))
494503
return test_c_preprocessor(ui_message_handler)
495504
? CPROVER_EXIT_PREPROCESSOR_TEST_FAILED

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 & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -531,22 +531,13 @@ int gcc_modet::doit()
531531
if(cmdline.isset("-fsingle-precision-constant"))
532532
config.ansi_c.single_precision_constant=true;
533533

534-
// ISO/IEC TS 18661-3:2015 support was introduced with gcc 7.0
535-
if(gcc_version.flavor==gcc_versiont::flavort::GCC &&
536-
gcc_version.is_at_least(7))
537-
config.ansi_c.ts_18661_3_Floatn_types=true;
538-
539-
const auto gcc_float128_minor_version =
540-
config.ansi_c.arch == "x86_64" ? 3u : 5u;
541-
542-
config.ansi_c.Float128_type =
543-
gcc_version.flavor == gcc_versiont::flavort::GCC &&
544-
gcc_version.is_at_least(4u, gcc_float128_minor_version);
545-
546534
// -fshort-double makes double the same as float
547535
if(cmdline.isset("fshort-double"))
548536
config.ansi_c.double_width=config.ansi_c.single_width;
549537

538+
// configure version-specific gcc settings
539+
configure_gcc(gcc_version);
540+
550541
switch(compiler.mode)
551542
{
552543
case compilet::LINK_LIBRARY:

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)